のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

GlyphPage::fill

  91 bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
     92 {
     93     if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) {
     94         SkDebugf("%s last char is high-surrogate", __FUNCTION__);
     95         return false;
     96     }
     97 
     98     SkPaint paint;
     99     fontData->platformData().setupPaint(&paint);
    100     paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    101 
    102     SkAutoSTMalloc <GlyphPage::size, uint16_t> glyphStorage(length);
    103     uint16_t* glyphs = glyphStorage.get();
    104     UChar *textBuffer = buffer;
    105     UChar vTextBuffer[bufferLength];
    106 
    107     if (fontData->platformData().orientation() == Vertical && !fontData->hasVerticalGlyphs()) {
    108         // Convert to vertical form if there is no vertical glyphs.
    109         convertToVerticalForms(buffer, vTextBuffer, bufferLength);
    110         textBuffer = vTextBuffer;
    111     }
    112 
    113     unsigned count = paint.textToGlyphs(textBuffer, bufferLength << 1, glyphs);
    114     if (count != length) {
    115         SkDebugf("%s count != length\n", __FUNCTION__);
    116         return false;
    117     }
    118 
    119     if (fontData->hasVerticalGlyphs()) {
    120         bool lookVariants = false;
    121         for (unsigned i = 0; i < bufferLength; ++i) {
    122             if (!Font::isCJKIdeograph(textBuffer[i])) {
    123                 lookVariants = true;
    124                 break;
    125             }
    126         }
    127         if (lookVariants) {
    128             if (substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength)) {
    129                 // Convert text to vertical forms if substituteWithVerticalGlyphs() fails to access vert tables.
    130                 convertToVerticalForms(buffer, vTextBuffer, bufferLength);
    131                 textBuffer = vTextBuffer;
    132 
    133                 unsigned count = paint.textToGlyphs(textBuffer, bufferLength << 1, glyphs);
    134                 if (count != length) {
    135                     SkDebugf("%s count != length\n", __FUNCTION__);
    136                     return false;
    137                 }
    138             }
    139         }
    140     }
    141 
    142     unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero
    143 
    144     // search for emoji. If we knew for sure that buffer was a contiguous range
    145     // of chars, we could quick-reject the range to avoid this loop (usually)
    146     if (EmojiFont::IsAvailable()) {
    147         const UChar* curr = textBuffer;
    148         for (unsigned i = 0; i < length; i++) {
    149             SkUnichar uni = SkUTF16_NextUnichar(&curr);
    150             uint16_t glyphID = glyphs[i];
    151             // only sniff if the normal font failed to recognize it
    152             if (!glyphID)
    153                 glyphID = EmojiFont::UnicharToGlyph(uni);
    154             setGlyphDataForIndex(offset + i, glyphID, fontData);
    155             allGlyphs |= glyphID;
    156         }
    157     } else {
    158         for (unsigned i = 0; i < length; i++) {
    159             uint16_t glyphID = glyphs[i];
    160             setGlyphDataForIndex(offset + i, glyphID, fontData);
    161             allGlyphs |= glyphID;
    162         }
    163     }
    164     return allGlyphs != 0;
    165 }