diff options
Diffstat (limited to 'Source/WebCore')
28 files changed, 326 insertions, 142 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/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index a8c4d7a..2a1b1de 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -101,14 +101,6 @@ void BaseLayerAndroid::setContent(const PictureSet& src) // setSize(src.width(), src.height()); } -void BaseLayerAndroid::setExtra(SkPicture& src) -{ -#if USE(ACCELERATED_COMPOSITING) - android::Mutex::Autolock lock(m_drawLock); -#endif - m_extra.swap(src); -} - void BaseLayerAndroid::drawCanvas(SkCanvas* canvas) { #if USE(ACCELERATED_COMPOSITING) @@ -116,15 +108,12 @@ void BaseLayerAndroid::drawCanvas(SkCanvas* canvas) #endif if (!m_content.isEmpty()) m_content.draw(canvas); - // TODO : replace with !m_extra.isEmpty() once such a call exists - if (m_extra.width() > 0) - m_extra.draw(canvas); } #if USE(ACCELERATED_COMPOSITING) void BaseLayerAndroid::prefetchBasePicture(SkRect& viewport, float currentScale, - TiledPage* prefetchTiledPage) + TiledPage* prefetchTiledPage, bool draw) { SkIRect bounds; float prefetchScale = currentScale * PREFETCH_SCALE_MODIFIER; @@ -162,7 +151,8 @@ void BaseLayerAndroid::prefetchBasePicture(SkRect& viewport, float currentScale, prefetchTiledPage->swapBuffersIfReady(bounds, prefetchScale, TiledPage::SwapWhateverIsReady); - prefetchTiledPage->draw(PREFETCH_OPACITY, bounds); + if (draw) + prefetchTiledPage->draw(PREFETCH_OPACITY, bounds); } bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, @@ -235,7 +225,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, // When we aren't zooming, we should TRY and swap tile buffers if they're // ready. When scrolling, we swap whatever's ready. Otherwise, buffer until // the entire page is ready and then swap. - bool buffersSwapped = false; + bool tilesFinished = false; if (!zooming) { TiledPage::SwapMethod swapMethod; if (scrolling) @@ -243,13 +233,13 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, else swapMethod = TiledPage::SwapWholePage; - buffersSwapped = tiledPage->swapBuffersIfReady(preZoomBounds, + tilesFinished = tiledPage->swapBuffersIfReady(preZoomBounds, zoomManager->currentScale(), swapMethod); - if (buffersSwappedPtr && buffersSwapped) + if (buffersSwappedPtr && tilesFinished) *buffersSwappedPtr = true; - if (buffersSwapped) { + if (tilesFinished) { if (m_scrollState == ScrollingFinishPaint) { m_scrollState = NotScrolling; scrolling = false; @@ -265,7 +255,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, } - bool needsRedraw = scrolling || zooming || !buffersSwapped; + bool needsRedraw = scrolling || zooming || !tilesFinished; // if we don't expect to redraw, unlock the invals if (!needsRedraw) @@ -283,15 +273,19 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, TiledPage::ExpandedBounds); } - XLOG("scrolling %d, zooming %d, buffersSwapped %d, needsRedraw %d", - scrolling, zooming, buffersSwapped, needsRedraw); + XLOG("scrolling %d, zooming %d, tilesFinished %d, needsRedraw %d", + scrolling, zooming, tilesFinished, needsRedraw); // prefetch in the nextTiledPage if unused by zooming (even if not scrolling // since we want the tiles to be ready before they're needed) bool usePrefetchPage = !zooming; nextTiledPage->setIsPrefetchPage(usePrefetchPage); - if (usePrefetchPage) - prefetchBasePicture(viewport, scale, nextTiledPage); + if (usePrefetchPage) { + // if the non-prefetch page isn't missing tiles, don't bother drawing + // prefetch page + bool drawPrefetchPage = tiledPage->hasMissingContent(preZoomBounds); + prefetchBasePicture(viewport, scale, nextTiledPage, drawPrefetchPage); + } tiledPage->draw(transparency, preZoomBounds); diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h index 26fd158..ad77013 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -53,7 +53,6 @@ public: Color getBackgroundColor() { return m_color; } #endif void setContent(const android::PictureSet& src); - void setExtra(SkPicture& extra); android::PictureSet* content() { return &m_content; } // This method will paint using the current PictureSet onto // the passed canvas. We used it to paint the GL tiles as well as @@ -63,11 +62,10 @@ public: bool drawGL(double currentTime, LayerAndroid* compositedRoot, IntRect& rect, SkRect& viewport, float scale, bool* buffersSwappedPtr); - void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); } private: #if USE(ACCELERATED_COMPOSITING) void prefetchBasePicture(SkRect& viewport, float currentScale, - TiledPage* prefetchTiledPage); + TiledPage* prefetchTiledPage, bool draw); bool drawBasePictureInGL(SkRect& viewport, float scale, double currentTime, bool* buffersSwappedPtr); @@ -76,7 +74,6 @@ private: Color m_color; #endif android::PictureSet m_content; - SkPicture m_extra; SkRect m_previousVisible; ScrollState m_scrollState; diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp index 96599af..57baee8 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp @@ -133,8 +133,6 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) canvas.scale(renderInfo.scale, renderInfo.scale); unsigned int pictureCount = 0; renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas, &pictureCount); - if (renderInfo.baseTile->isLayerTile()) - renderInfo.tilePainter->paintExtra(&canvas); if (visualIndicator) { canvas.restore(); 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 febc34a..e53a1e1 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -147,8 +147,6 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval m_baseLayerUpdate = true; m_invalidateRegion.setEmpty(); } - if (m_currentBaseLayer && layer) - m_currentBaseLayer->swapExtra(layer); SkSafeRef(layer); SkSafeUnref(m_currentBaseLayer); @@ -309,10 +307,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(); @@ -464,8 +460,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/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp index 86e1f63..f647673 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp @@ -782,6 +782,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef void GraphicsContext::fillRect(const FloatRect& rect) { + save(); SkPaint paint; m_data->setupPaintFill(&paint); @@ -791,6 +792,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) m_state.fillGradient.get()); GC2CANVAS(this)->drawRect(rect, paint); + restore(); } void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace) @@ -799,6 +801,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS return; if (color.rgb() & 0xFF000000) { + save(); SkPaint paint; m_data->setupPaintCommon(&paint); @@ -828,6 +831,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS paint.setAntiAlias(false); GC2CANVAS(this)->drawRect(rect, paint); + restore(); } } 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/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index d4a1225..e0898e6 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -66,7 +66,6 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_preserves3D(false), m_anchorPointZ(0), m_recordingPicture(0), - m_extra(0), m_uniqueId(++gUniqueId), m_texture(0), m_imageRef(0), @@ -93,7 +92,6 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_haveClip(layer.m_haveClip), m_isIframe(layer.m_isIframe), - m_extra(0), // deliberately not copied m_uniqueId(layer.m_uniqueId), m_texture(0), m_imageTexture(0), @@ -154,7 +152,6 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_isFixed(false), m_isIframe(false), m_recordingPicture(picture), - m_extra(0), m_uniqueId(-1), m_texture(0), m_imageRef(0), @@ -180,7 +177,6 @@ LayerAndroid::~LayerAndroid() { if (m_imageTexture) ImagesManager::instance()->removeImage(m_imageTexture->imageRef()); - delete m_extra; SkSafeUnref(m_recordingPicture); m_animations.clear(); #ifdef DEBUG_COUNT @@ -929,14 +925,6 @@ bool LayerAndroid::drawChildrenGL(GLWebViewState* glWebViewState, SkMatrix& matr return askScreenUpdate; } -void LayerAndroid::extraDraw(SkCanvas* canvas) -{ - m_atomicSync.lock(); - if (m_extra) - canvas->drawPicture(*m_extra); - m_atomicSync.unlock(); -} - void LayerAndroid::contentDraw(SkCanvas* canvas) { if (m_recordingPicture) @@ -1230,32 +1218,6 @@ LayerAndroid* LayerAndroid::findById(int match) return 0; } -void LayerAndroid::setExtra(DrawExtra* extra) -{ - for (int i = 0; i < countChildren(); i++) - getChild(i)->setExtra(extra); - - android::AutoMutex lock(m_atomicSync); - if (extra || (m_extra && !extra)) - m_dirty = true; - - delete m_extra; - m_extra = 0; - - if (!extra) - return; - - if (m_recordingPicture) { - IntRect dummy; // inval area, unused for now - m_extra = new SkPicture(); - SkCanvas* canvas = m_extra->beginRecording(m_recordingPicture->width(), - m_recordingPicture->height()); - extra->draw(canvas, this, &dummy); - m_extra->endRecording(); - needsRepaint(); - } -} - } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index 4458a2c..15a581e 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -233,7 +233,6 @@ public: { return static_cast<LayerAndroid*>(this->INHERITED::getChild(index)); } - void setExtra(DrawExtra* extra); // does not assign ownership int uniqueId() const { return m_uniqueId; } bool isFixed() { return m_isFixed; } @@ -257,7 +256,6 @@ public: const SkRegion& dirtyRegion() { return m_dirtyRegion; } void contentDraw(SkCanvas*); - void extraDraw(SkCanvas*); virtual bool isMedia() const { return false; } virtual bool isVideo() const { return false; } @@ -357,7 +355,6 @@ private: FloatRect m_clippingRect; - SkPicture* m_extra; int m_uniqueId; PaintedSurface* m_texture; diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp index 8f78638..c0597a9 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp @@ -179,19 +179,6 @@ void PaintedSurface::markAsDirty(const SkRegion& dirtyArea) m_updateManager.updateInval(dirtyArea); } -void PaintedSurface::paintExtra(SkCanvas* canvas) -{ - m_layerLock.lock(); - LayerAndroid* layer = m_layer; - SkSafeRef(layer); - m_layerLock.unlock(); - - if (layer) - layer->extraDraw(canvas); - - SkSafeUnref(layer); -} - float PaintedSurface::opacity() { if (m_layer) return m_layer->drawOpacity(); diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h index 761be74..2e01b80 100644 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.h +++ b/Source/WebCore/platform/graphics/android/PaintedSurface.h @@ -66,7 +66,6 @@ public: void computeVisibleArea(); // TilePainter methods for TiledTexture - virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); // used by TiledTexture diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index 191edf3..91030cb 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -38,7 +38,6 @@ class TilePainter { public: virtual ~TilePainter() { } virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0; - virtual void paintExtra(SkCanvas*) = 0; virtual const TransformationMatrix* transform() { return 0; } }; diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp index b3b4daf..c097c58 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.cpp +++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp @@ -290,6 +290,19 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound m_prepare = true; } +bool TiledPage::hasMissingContent(const SkIRect& tileBounds) +{ + int neededTiles = tileBounds.width() * tileBounds.height(); + for (int j = 0; j < m_baseTileSize; j++) { + BaseTile& tile = m_baseTiles[j]; + if (tileBounds.contains(tile.x(), tile.y())) { + if (tile.frontTexture()) + neededTiles--; + } + } + return neededTiles > 0; +} + bool TiledPage::swapBuffersIfReady(const SkIRect& tileBounds, float scale, SwapMethod swap) { if (!m_glWebViewState) @@ -342,18 +355,9 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds) const float tileWidth = TilesManager::tileWidth() * m_invScale; const float tileHeight = TilesManager::tileHeight() * m_invScale; - SkIRect actualTileBounds = tileBounds; - actualTileBounds.fTop -= m_glWebViewState->expandedTileBoundsY(); - actualTileBounds.fBottom += m_glWebViewState->expandedTileBoundsY(); - actualTileBounds.fLeft -= m_glWebViewState->expandedTileBoundsX(); - actualTileBounds.fRight += m_glWebViewState->expandedTileBoundsX(); - - actualTileBounds.fTop = std::max(0, actualTileBounds.fTop); - actualTileBounds.fLeft = std::max(0, actualTileBounds.fLeft); - for (int j = 0; j < m_baseTileSize; j++) { BaseTile& tile = m_baseTiles[j]; - bool tileInView = actualTileBounds.contains(tile.x(), tile.y()); + bool tileInView = tileBounds.contains(tile.x(), tile.y()); if (tileInView) { SkRect rect; rect.fLeft = tile.x() * tileWidth; @@ -383,10 +387,6 @@ bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUse return true; } -void TiledPage::paintExtra(SkCanvas* canvas) -{ -} - TiledPage* TiledPage::sibling() { if (!m_glWebViewState) diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h index 718908d..960f3d5 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -73,7 +73,8 @@ public: // dirty (and thus repaint needed) bool updateTileDirtiness(const SkIRect& tileBounds); - // check to see if the page is ready for display + // returns true if the page can't draw the entire region (may still be stale) + bool hasMissingContent(const SkIRect& tileBounds); // swap 'buffers' by swapping each modified texture bool swapBuffersIfReady(const SkIRect& tileBounds, float scale, SwapMethod swap); @@ -83,7 +84,6 @@ public: // TilePainter implementation // used by individual tiles to generate the bitmap for their tile bool paint(BaseTile*, SkCanvas*, unsigned int*); - void paintExtra(SkCanvas*); // used by individual tiles to get the information about the current picture GLWebViewState* glWebViewState() { return m_glWebViewState; } diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 3182eef..b252303 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -257,11 +257,6 @@ bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* picture return m_updateManager.paint(tile, canvas, pictureUsed); } -void TiledTexture::paintExtra(SkCanvas* canvas) -{ - m_surface->paintExtra(canvas); -} - const TransformationMatrix* TiledTexture::transform() { return m_surface->transform(); diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h index 206961b..c6e9e09 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ b/Source/WebCore/platform/graphics/android/TiledTexture.h @@ -80,7 +80,6 @@ public: // TilePainter methods bool paint(BaseTile* tile, SkCanvas*, unsigned int*); - virtual void paintExtra(SkCanvas*); virtual const TransformationMatrix* transform(); float scale() { return m_scale; } 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/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 4e29870..5c4f0f3 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -470,6 +470,9 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo, void TransferQueue::setTextureUploadType(TextureUploadType type) { + if (m_currentUploadType == type) + return; + discardQueue(); android::Mutex::Autolock lock(m_transferQueueItemLocks); 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 |