1 /* 2 * Copyright 2009, The Android Open Source Project 3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "config.h" 28 29 #include "EmojiFont.h" 30 #include "GlyphPageTreeNode.h" 31 #include "SkTemplates.h" 32 #include "SkPaint.h" 33 #include "SkUtils.h" 34 #include "SimpleFontData.h" 35 36 using namespace android; 37 38 namespace WebCore { 39 40 #define NO_BREAK_SPACE_UNICHAR 0xA0 41 42 bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) 43 { 44 if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) { 45 SkDebugf("%s last char is high-surrogate", __FUNCTION__); 46 return false; 47 } 48 49 SkPaint paint; 50 fontData->platformData().setupPaint(&paint); 51 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); 52 53 SkAutoSTMalloc <GlyphPage::size, uint16_t> glyphStorage(length); 54 uint16_t* glyphs = glyphStorage.get(); 55 unsigned count = paint.textToGlyphs(buffer, bufferLength << 1, glyphs); 56 if (count != length) { 57 SkDebugf("%s count != length\n", __FUNCTION__); 58 return false; 59 } 60 61 unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero 62 63 // search for emoji. If we knew for sure that buffer was a contiguous range 64 // of chars, we could quick-reject the range to avoid this loop (usually) 65 if (EmojiFont::IsAvailable()) { 66 const UChar* curr = buffer; 67 for (unsigned i = 0; i < length; i++) { 68 SkUnichar uni = SkUTF16_NextUnichar(&curr); 69 uint16_t glyphID = glyphs[i]; 70 // only sniff if the normal font failed to recognize it 71 if (!glyphID) 72 glyphID = EmojiFont::UnicharToGlyph(uni); 73 setGlyphDataForIndex(offset + i, glyphID, fontData); 74 allGlyphs |= glyphID; 75 } 76 } else { 77 for (unsigned i = 0; i < length; i++) { 78 uint16_t glyphID = glyphs[i]; 79 setGlyphDataForIndex(offset + i, glyphID, fontData); 80 allGlyphs |= glyphID; 81 } 82 } 83 return allGlyphs != 0; 84 } 85 86 } 87