diff options
Diffstat (limited to 'Source')
19 files changed, 313 insertions, 69 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/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index 2def2a6..85b1541 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -2743,7 +2743,7 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadTyp request.setCachePolicy(UseProtocolCachePolicy); } else if (loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadFromOrigin || request.isConditional()) request.setCachePolicy(ReloadIgnoringCacheData); - else if (isBackForwardLoadType(loadType) && m_stateMachine.committedFirstRealDocumentLoad() && !request.url().protocolIs("https")) + else if (isBackForwardLoadType(loadType) && m_stateMachine.committedFirstRealDocumentLoad()) request.setCachePolicy(ReturnCacheDataElseLoad); if (request.cachePolicy() == ReloadIgnoringCacheData) { diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp index 6b4296b..3528d47 100644 --- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp @@ -183,8 +183,10 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, SkScalar y = SkFloatToScalar(point.y()); const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from); const GlyphBufferAdvance* adv = glyphBuffer.advances(from); - SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); + SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs); SkPoint* pos = storage.get(); + SkPoint* vPosBegin = storage2.get(); + SkPoint* vPosEnd = storage3.get(); SkCanvas* canvas = gc->platformContext()->mCanvas; @@ -221,12 +223,27 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, localCount * sizeof(uint16_t), &pos[localIndex], paint); } else { + bool isVertical = font->platformData().orientation() == Vertical; for (int i = 0; i < numGlyphs; i++) { pos[i].set(x, y); - x += SkFloatToScalar(adv[i].width()); y += SkFloatToScalar(adv[i].height()); + if (isVertical) { + SkScalar myWidth = SkFloatToScalar(adv[i].width()); + vPosBegin[i].set(x + myWidth, y); + vPosEnd[i].set(x + myWidth, y - myWidth); + x += myWidth; + + SkPath path; + path.reset(); + path.moveTo(vPosBegin[i]); + path.lineTo(vPosEnd[i]); + canvas->drawTextOnPath(glyphs + i, 2, path, 0, paint); + } + else + x += SkFloatToScalar(adv[i].width()); } - canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); + if (!isVertical) + canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); } } diff --git a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp b/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp index 20ffd17..4fc3b4e 100644 --- a/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/FontCacheAndroid.cpp @@ -177,7 +177,9 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD result = new FontPlatformData(tf, fontDescription.computedSize(), (style & SkTypeface::kBold) && !tf->isBold(), - (style & SkTypeface::kItalic) && !tf->isItalic()); + (style & SkTypeface::kItalic) && !tf->isItalic(), + fontDescription.orientation(), + fontDescription.textOrientation()); } tf->unref(); diff --git a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp index 72fac68..693386e 100644 --- a/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp +++ b/Source/WebCore/platform/graphics/android/FontCustomPlatformData.cpp @@ -45,7 +45,8 @@ FontCustomPlatformData::~FontCustomPlatformData() // the unref is enough to release the font data... } -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontOrientation, TextOrientation, FontWidthVariant, FontRenderingMode) +FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, + FontOrientation fontOrientation, TextOrientation textOrientation, FontWidthVariant, FontRenderingMode) { // turn bold/italic into fakeBold/fakeItalic if (m_typeface != NULL) { @@ -54,7 +55,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b if (m_typeface->isItalic() == italic) italic = false; } - return FontPlatformData(m_typeface, size, bold, italic); + return FontPlatformData(m_typeface, size, bold, italic, fontOrientation, textOrientation); } FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) diff --git a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp index 1f19b6d..c6dd174 100644 --- a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp @@ -32,6 +32,7 @@ #include "SimpleFontData.h" #include "FloatRect.h" #include "FontDescription.h" +#include "SkFontHost.h" #include "SkPaint.h" #include "SkTypeface.h" #include "SkTime.h" @@ -57,6 +58,16 @@ void SimpleFontData::platformInit() m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f); // hack I stole from the window's port m_fontMetrics.setLineSpacing(a + d); m_fontMetrics.setLineGap(SkScalarToFloat(skiaFontMetrics.fLeading)); + + if (platformData().orientation() == Vertical && !isTextOrientationFallback()) { + static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a'); + static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G'); + const SkFontID fontID = m_platformData.uniqueID(); + size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag); + size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag); + if ((vheaSize > 0) || (vorgSize > 0)) + m_hasVerticalGlyphs = true; + } } void SimpleFontData::platformCharWidthInit() diff --git a/Source/WebCore/platform/graphics/android/FontPlatformData.h b/Source/WebCore/platform/graphics/android/FontPlatformData.h index 56ce6e9..5c3313e 100644 --- a/Source/WebCore/platform/graphics/android/FontPlatformData.h +++ b/Source/WebCore/platform/graphics/android/FontPlatformData.h @@ -31,6 +31,7 @@ #define FontPlatformData_h #include "FontOrientation.h" +#include "TextOrientation.h" #include <wtf/text/StringImpl.h> #ifndef NDEBUG @@ -52,7 +53,8 @@ public: FontPlatformData(); FontPlatformData(const FontPlatformData&); - FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic); + FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic, + FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight); FontPlatformData(const FontPlatformData& src, float textSize); FontPlatformData(float size, bool syntheticBold, bool syntheticOblique); FontPlatformData(const FontPlatformData& src, SkTypeface* typeface); @@ -65,9 +67,8 @@ public: return mTypeface == hashTableDeletedFontValue(); } - FontOrientation orientation() const { return Horizontal; } // FIXME: Implement. - void setOrientation(FontOrientation) { } // FIXME: Implement. - + FontOrientation orientation() const { return mOrientation; } + void setOrientation(FontOrientation orientation) { mOrientation = orientation; } FontPlatformData& operator=(const FontPlatformData&); bool operator==(const FontPlatformData& a) const; @@ -114,6 +115,8 @@ private: float mTextSize; bool mFakeBold; bool mFakeItalic; + FontOrientation mOrientation; + TextOrientation mTextOrientation; mutable RefPtr<RefCountedHarfbuzzFace> m_harfbuzzFace; static SkTypeface* hashTableDeletedFontValue() { diff --git a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp index 8e77b5b..3c90246 100644 --- a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp @@ -74,7 +74,8 @@ FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() } FontPlatformData::FontPlatformData() - : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false) + : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false), + mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight) { inc_count(); trace(1); @@ -92,13 +93,17 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src) mFakeBold = src.mFakeBold; mFakeItalic = src.mFakeItalic; m_harfbuzzFace = src.m_harfbuzzFace; + mOrientation = src.mOrientation; + mTextOrientation = src.mTextOrientation; inc_count(); trace(2); } -FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic) - : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic) +FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic, + FontOrientation orientation, TextOrientation textOrientation) + : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic), + mOrientation(orientation), mTextOrientation(textOrientation) { if (hashTableDeletedFontValue() != mTypeface) { SkSafeRef(mTypeface); @@ -110,7 +115,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic), - m_harfbuzzFace(src.m_harfbuzzFace) + m_harfbuzzFace(src.m_harfbuzzFace), mOrientation(src.mOrientation), mTextOrientation(src.mTextOrientation) { if (hashTableDeletedFontValue() != mTypeface) { SkSafeRef(mTypeface); @@ -121,7 +126,8 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize) } FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) - : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique) + : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique), + mOrientation(Horizontal), mTextOrientation(TextOrientationVerticalRight) { inc_count(); trace(5); @@ -129,7 +135,8 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf) : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold), - mFakeItalic(src.mFakeItalic) + mFakeItalic(src.mFakeItalic), mOrientation(src.mOrientation), + mTextOrientation(src.mTextOrientation) { if (hashTableDeletedFontValue() != mTypeface) { SkSafeRef(mTypeface); @@ -165,6 +172,8 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src) mFakeBold = src.mFakeBold; mFakeItalic = src.mFakeItalic; m_harfbuzzFace = src.m_harfbuzzFace; + mOrientation = src.mOrientation; + mTextOrientation = src.mTextOrientation; return *this; } @@ -204,7 +213,9 @@ bool FontPlatformData::operator==(const FontPlatformData& a) const return mTypeface == a.mTypeface && mTextSize == a.mTextSize && mFakeBold == a.mFakeBold && - mFakeItalic == a.mFakeItalic; + mFakeItalic == a.mFakeItalic && + mOrientation == a.mOrientation && + mTextOrientation == a.mTextOrientation; } unsigned FontPlatformData::hash() const @@ -219,7 +230,8 @@ unsigned FontPlatformData::hash() const uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize); - h ^= 0x01010101 * (((int)mFakeBold << 1) | (int)mFakeItalic); + h ^= 0x01010101 * ((static_cast<int>(mTextOrientation) << 3) | (static_cast<int>(mOrientation) << 2) | + ((int)mFakeBold << 1) | (int)mFakeItalic); h ^= sizeAsInt; return h; } diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index dbd4612..7b43305 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -310,10 +310,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(); @@ -465,8 +463,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..a327b79 100644 --- a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp @@ -27,17 +27,52 @@ #include "config.h" #include "EmojiFont.h" +#include "Font.h" #include "GlyphPageTreeNode.h" -#include "SkTemplates.h" +#include "HarfbuzzSkia.h" +#include "SimpleFontData.h" +#include "SkFontHost.h" #include "SkPaint.h" +#include "SkTemplates.h" #include "SkUtils.h" -#include "SimpleFontData.h" +#include "VerticalTextMap.h" + using namespace android; namespace WebCore { -#define NO_BREAK_SPACE_UNICHAR 0xA0 +#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) { @@ -49,21 +84,46 @@ 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 f56c443..dd2b169 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..6e715e2 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp @@ -0,0 +1,103 @@ +/* + * 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 "config.h" +#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 +}; + +namespace WebCore { + +static WTF::Mutex verticalTextHashMapMutex; +static HashMap<UChar, UChar>* verticalTextHashMap = 0; + +UChar VerticalTextMap::getVerticalForm(UChar c) { + { + MutexLocker lock(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..2955589 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/VerticalTextMap.h @@ -0,0 +1,44 @@ +/* + * 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 "WebViewCore.h" +#include <wtf/StdLibExtras.h> +#include <wtf/HashMap.h> +#include <wtf/unicode/CharacterNames.h> + +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/WebCoreSupport/WebCache.cpp b/Source/WebKit/android/WebCoreSupport/WebCache.cpp index 3c49430..9b505ee 100644 --- a/Source/WebKit/android/WebCoreSupport/WebCache.cpp +++ b/Source/WebKit/android/WebCoreSupport/WebCache.cpp @@ -42,28 +42,20 @@ namespace android { static WTF::Mutex instanceMutex; -static const string& rootDirectory() -{ - // This method may be called on any thread, as the Java method is - // synchronized. - static WTF::Mutex mutex; - MutexLocker lock(mutex); - static string cacheDirectory; - if (cacheDirectory.empty()) { - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jclass bridgeClass = env->FindClass("android/webkit/JniUtil"); - jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;"); - cacheDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method))); - env->DeleteLocalRef(bridgeClass); - } - return cacheDirectory; -} - static string storageDirectory() { - // Private cache is currently in memory only static const char* const kDirectory = "/webviewCacheChromium"; - string storageDirectory = rootDirectory(); + + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jclass bridgeClass = env->FindClass("android/webkit/JniUtil"); + jmethodID method = env->GetStaticMethodID(bridgeClass, "getCacheDirectory", "()Ljava/lang/String;"); + string storageDirectory = jstringToStdString(env, static_cast<jstring>(env->CallStaticObjectMethod(bridgeClass, method))); + env->DeleteLocalRef(bridgeClass); + + // Return empty string if storageDirectory is an empty string + if (storageDirectory.empty()) + return storageDirectory; + storageDirectory.append(kDirectory); return storageDirectory; } @@ -111,8 +103,13 @@ WebCache::WebCache(bool isPrivateBrowsing) if (isPrivateBrowsing) backendFactory = net::HttpCache::DefaultBackend::InMemory(kMaximumCacheSizeBytes / 2); else { - FilePath directoryPath(storageDirectory().c_str()); - backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy); + string storage(storageDirectory()); + if (storage.empty()) // Can't get a storage directory from the OS + backendFactory = net::HttpCache::DefaultBackend::InMemory(kMaximumCacheSizeBytes / 2); + else { + FilePath directoryPath(storage.c_str()); + backendFactory = new net::HttpCache::DefaultBackend(net::DISK_CACHE, directoryPath, kMaximumCacheSizeBytes, cacheMessageLoopProxy); + } } m_cache = new net::HttpCache(m_hostResolver.get(), 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 diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 0876db6..493d4b3 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -420,7 +420,7 @@ void scrollRectOnScreen(const IntRect& rect) { if (rect.isEmpty()) return; - SkRect visible; + SkRect visible = SkRect::MakeEmpty(); calcOurContentVisibleRect(&visible); int dx = 0; int left = rect.x(); |