Пример #1
0
// Return the context associated with the next logical typeface, or NULL if
// there are no more entries in the fallback chain.
SkScalerContext* SkScalerContext::allocNextContext() const {
#ifdef SK_BUILD_FOR_ANDROID
    SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
                                                       fRec.fOrigFontID,
                                                       fPaintOptionsAndroid);
    if (0 == newFace) {
        return NULL;
    }

    SkAutoTUnref<SkTypeface> aur(newFace);
    uint32_t newFontID = newFace->uniqueID();

    SkOrderedWriteBuffer androidBuffer(128);
    fPaintOptionsAndroid.flatten(androidBuffer);

    SkAutoDescriptor    ad(sizeof(fRec) + androidBuffer.size() + SkDescriptor::ComputeOverhead(2));
    SkDescriptor*       desc = ad.getDesc();

    desc->init();
    SkScalerContext::Rec* newRec =
    (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
                                          sizeof(fRec), &fRec);
    androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
                                               androidBuffer.size(), NULL));

    newRec->fFontID = newFontID;
    desc->computeChecksum();

    return newFace->createScalerContext(desc);
#else
    return NULL;
#endif
}
GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
                                                                 SkGlyphCache* glyphCache) {
    SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface()
                                               : glyphCache->getScalerContext()->getTypeface();
    const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getDescriptor();

    static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDomain();
    int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
    GrUniqueKey glyphKey;
    GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCount);
    reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0;
    reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0;
    if (strokeDataCount > 0) {
        fStroke.asUniqueKeyFragment(&builder[2]);
    }
    builder.finish();

    SkAutoTUnref<GrPathRange> glyphs(
        static_cast<GrPathRange*>(
            ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
    if (nullptr == glyphs) {
        glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStroke));
        ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
    } else {
        SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc));
    }

    return glyphs.detach();
}
Пример #3
0
// We're only interested in some fields of the SkPaint, so we have a custom
// operator== function.
bool SkPDFGraphicState::GSCanonicalEntry::operator==(
        const SkPDFGraphicState::GSCanonicalEntry& gs) const {
    const SkPaint* a = fPaint;
    const SkPaint* b = gs.fPaint;
    SkASSERT(a != NULL);
    SkASSERT(b != NULL);
    SkTypeface* aFace = a->getTypeface();
    SkTypeface* bFace = b->getTypeface();
    return SkColorGetA(a->getColor()) == SkColorGetA(b->getColor()) &&
           a->getStrokeCap() == b->getStrokeCap() &&
           a->getStrokeJoin() == b->getStrokeJoin() &&
           a->getTextSize() == b->getTextSize() &&
           a->getStrokeWidth() == b->getStrokeWidth() &&
           a->getStrokeMiter() == b->getStrokeMiter() &&
           (aFace == NULL) == (bFace == NULL) &&
           (aFace == NULL || aFace->uniqueID() == bFace->uniqueID());
}
/*  Returns the matching typeface, or NULL. If a typeface is found, its refcnt
    is not modified.
 */
static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
    FamilyRec* curr = gFamilyHead;
    while (curr != NULL) {
        for (int i = 0; i < 4; i++) {
            SkTypeface* face = curr->fFaces[i];
            if (face != NULL && face->uniqueID() == uniqueID) {
                return face;
            }
        }
        curr = curr->fNext;
    }
    return NULL;
}
HB_Error harfbuzzSkiaGetTable(void* font, const HB_Tag tag, HB_Byte* buffer, HB_UInt* len)
{
    SkTypeface* typeface = static_cast<SkTypeface*>(font);

    if (!typeface) {
        ALOGD("Typeface cannot be null");
        return HB_Err_Invalid_Argument;
    }
    const size_t tableSize = SkFontHost::GetTableSize(typeface->uniqueID(), tag);
    if (!tableSize)
        return HB_Err_Invalid_Argument;
    // If Harfbuzz specified a NULL buffer then it's asking for the size of the table.
    if (!buffer) {
        *len = tableSize;
        return HB_Err_Ok;
    }

    if (*len < tableSize)
        return HB_Err_Invalid_Argument;
    SkFontHost::GetTableData(typeface->uniqueID(), tag, 0, tableSize, buffer);
    return HB_Err_Ok;
}
Пример #6
0
void ScriptRunLayoutShaper::getConversionFactor(unsigned int &x_ppem, unsigned int &y_ppem,
        int &x_scale, int &y_scale, const SkPaint *paint) {
    SkTypeface *typeface = paint->getTypeface();

    int textSize = paint->getTextSize();
    float scaleX = paint->getTextScaleX();
    x_ppem = floor(scaleX * textSize + 0.5);
    y_ppem = textSize;
    uint32_t unitsPerEm = SkFontHost::GetUnitsPerEm(typeface->uniqueID());
    // x_ and y_scale are the conversion factors from font design space
    // (unitsPerEm) to 1/64th of device pixels in 16.16 format.
    const int kDevicePixelFraction = 64;
    const int kMultiplyFor16Dot16 = 1 << 16;
    float emScale = kDevicePixelFraction * kMultiplyFor16Dot16 / (float)unitsPerEm;
    x_scale = emScale * scaleX * textSize;
    y_scale = emScale * textSize;
}
Пример #7
0
PassRefPtr<FontDataForRangeSet> FontFallbackIterator::uniqueOrNext(
    PassRefPtr<FontDataForRangeSet> candidate,
    const Vector<UChar32>& hintList) {
  SkTypeface* candidateTypeface =
      candidate->fontData()->platformData().typeface();
  if (!candidateTypeface)
    return next(hintList);

  uint32_t candidateId = candidateTypeface->uniqueID();
  if (m_uniqueFontDataForRangeSetsReturned.contains(candidateId)) {
    return next(hintList);
  }

  // We don't want to skip subsetted ranges because HarfBuzzShaper's behavior
  // depends on the subsetting.
  if (candidate->isEntireRange())
    m_uniqueFontDataForRangeSetsReturned.add(candidateId);
  return candidate;
}
uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
    if (face) {
        return face->uniqueID();
    }

    // We cache the default fontID, assuming it will not change during a boot
    // The initial value of 0 is fine, since a typeface's uniqueID should not
    // be zero.
    static uint32_t gDefaultFontID;
    
    if (0 == gDefaultFontID) {
        SkTypeface* defaultFace = SkFontHost::CreateTypeface(NULL, NULL,
                                                    SkTypeface::kNormal);
        SkASSERT(defaultFace);
        gDefaultFontID = defaultFace->uniqueID();
        defaultFace->unref();
    }
    return gDefaultFontID;
}
/*  Called once (ensured by the sentinel check at the beginning of our body).
    Initializes all the globals, and register the system fonts.
 */
static void load_system_fonts() {
    // check if we've already be called
    if (NULL != gDefaultNormal) {
        return;
    }
    
    const FontInitRec* rec = gSystemFonts;
    SkTypeface* firstInFamily = NULL;
    int fallbackCount = 0;

    for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
        // if we're the first in a new family, clear firstInFamily
        if (rec[i].fNames != NULL) {
            firstInFamily = NULL;
        }
        
        SkString name;
        SkTypeface::Style style;

        // we expect all the fonts, except the "fallback" fonts
        bool isExpected = (rec[i].fNames != gFBNames);
        if (!get_name_and_style(rec[i].fFileName, &name, &style, isExpected)) {
            continue;
        }

        SkTypeface* tf = SkNEW_ARGS(FileTypeface,
                                    (style,
                                     true,  // system-font (cannot delete)
                                     firstInFamily, // what family to join
                                     rec[i].fFileName) // filename
                                    );

        if (rec[i].fNames != NULL) {
            // see if this is one of our fallback fonts
            if (rec[i].fNames == gFBNames) {
            //    SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
            //             rec[i].fFileName, fallbackCount, tf->uniqueID());
                gFallbackFonts[fallbackCount++] = tf->uniqueID();
            }

            firstInFamily = tf;
            FamilyRec* family = find_family(tf);
            const char* const* names = rec[i].fNames;

            // record the default family if this is it
            if (names == DEFAULT_NAMES) {
                gDefaultFamily = family;
            }
            // add the names to map to this family
            while (*names) {
                add_name(*names, family);
                names += 1;
            }
        }
    }

    // do this after all fonts are loaded. This is our default font, and it
    // acts as a sentinel so we only execute load_system_fonts() once
    gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
    // now terminate our fallback list with the sentinel value
    gFallbackFonts[fallbackCount] = 0;
}
Пример #10
0
/*
 *  Called once (ensured by the sentinel check at the beginning of our body).
 *  Initializes all the globals, and register the system fonts.
 *
 *  gFamilyHeadAndNameListMutex must already be acquired.
 */
static void init_system_fonts() {
    // check if we've already been called
    if (gDefaultNormal) {
        return;
    }

    SkASSERT(gUniqueFontID == 0);

    load_font_info();

    FontInitRec* rec = gSystemFonts;
    SkTypeface* firstInFamily = NULL;
    int fallbackCount = 0;

    for (size_t i = 0; i < gNumSystemFonts; i++) {
        // if we're the first in a new family, clear firstInFamily
        if (rec[i].fNames != NULL) {
            firstInFamily = NULL;
        }

        bool isFixedWidth;
        SkString name;
        SkTypeface::Style style;

        // we expect all the fonts, except the "fallback" fonts
        bool isExpected = (rec[i].fNames != gFBNames);
        if (!get_name_and_style(rec[i].fFileName, &name, &style,
                                &isFixedWidth, isExpected)) {
            // We need to increase gUniqueFontID here so that the unique id of
            // each font matches its index in gSystemFonts array, as expected
            // by find_uniqueID.
            sk_atomic_inc(&gUniqueFontID);
            continue;
        }

        SkTypeface* tf = SkNEW_ARGS(FileTypeface,
                                    (style,
                                     true,  // system-font (cannot delete)
                                     firstInFamily, // what family to join
                                     rec[i].fFileName,
                                     isFixedWidth) // filename
                                    );
#if SK_DEBUG_FONTS
        SkDebugf("---- SkTypeface[%d] %s fontID %d",
                  i, rec[i].fFileName, tf->uniqueID());
#endif

        if (rec[i].fNames != NULL) {
            // see if this is one of our fallback fonts
            if (rec[i].fNames == gFBNames) {
#if SK_DEBUG_FONTS
                SkDebugf("---- adding %s as fallback[%d] fontID %d",
                          rec[i].fFileName, fallbackCount, tf->uniqueID());
#endif
                gFallbackFonts[fallbackCount++] = tf->uniqueID();

                // Use the font file name as the name of the typeface.
                const char **nameList = (const char**)malloc(2 * sizeof(char*));
                if (nameList == NULL) {
                    // shouldn't get here
                    SkDEBUGFAIL("Failed to allocate nameList");
                    break;
                }
                nameList[0] = rec[i].fFileName;
                nameList[1] = NULL;
                rec[i].fNames = nameList;
            }

            firstInFamily = tf;
            FamilyRec* family = find_family(tf);
            const char* const* names = rec[i].fNames;

            // record the default family if this is it
            if (names == gDefaultNames) {
                gDefaultFamily = family;
            }
            // add the names to map to this family
            while (*names) {
                add_name(*names, family);
                names += 1;
            }
        }
    }

    // do this after all fonts are loaded. This is our default font, and it
    // acts as a sentinel so we only execute load_system_fonts() once
    gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
    // now terminate our fallback list with the sentinel value
    gFallbackFonts[fallbackCount] = 0;

//    SkDEBUGCODE(dump_globals());
}
Пример #11
0
void
SkFontEmbeddedList::initFontsLocked()
{
    if( gDefaultNormal ) return;
    SkASSERT( gUniqueFontID == 0 );
    loadFontInfoLocked();

    SkTypeface * firstInFamily = NULL;

    for( int i = 0 ; i < gSystemFonts.count() ; i++ )
    {
        const char * const * names = gSystemFonts[i].fNames;

        if( names != NULL )
            firstInFamily = NULL;

        bool isFixedWidth;
        SkString name;
        SkTypeface::Style style;
        bool isExpected = ( names != gFBNames );

        if( !getNameAndStyle( gSystemFonts[i].fFileName, &name, &style, &isFixedWidth, isExpected ) )
        {
            sk_atomic_inc( &gUniqueFontID );
            continue;
        }

        SkString fullpath;
        SkTypeface * tf = NULL;

        getFullPathForSysFonts( &fullpath, gSystemFonts[i].fFileName );
        tf = SkNEW_ARGS( FileTypeface, ( style, true, fullpath.c_str(), isFixedWidth ) );
        addTypefaceLocked( tf, firstInFamily );

        if( names != NULL )
        {
            if( names == gFBNames )
            {
                FallbackFontRec fallbackRec;
                fallbackRec.fFontID = tf->uniqueID();
                fallbackRec.fVariant = gSystemFonts[i].fVariant;
                addFallbackFontLocked( fallbackRec, gSystemFonts[i].fLanguage );
            }

            firstInFamily = tf;
            FamilyRec * family = findFamilyLocked( tf );

            if( isDefaultSansFont( names ) == true )
            {
                FileTypeface * ftf = ( FileTypeface * )tf;
                SkFontData * font = SkNEW( SkFontData );

                if( font )
                {
                    font->setFamilyAndTypeface( family, ftf );
                    font->setFontFullPath( ftf->getFilePath() );
                    font->setWebFaceName( names[0] );
                    addFonts( font );
                }
                else
                {
                    HyLogef( "SkNEW( SkFontData ) (%s)", ftf->getFilePath() );
                    continue;
                }
            }

            while( *names )
            {
                addNameLocked( *names, family );
                names += 1;
            }
        }
    }

    finaliseFallbackFontListsLocked();
}