diff options
Diffstat (limited to 'Source/WebCore/platform')
3 files changed, 215 insertions, 3 deletions
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/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 |