Beispiel #1
0
Glyph SimpleFontData::glyphForCharacter(UChar32 codepoint) const {
  uint16_t glyph;
  SkTypeface* typeface = platformData().typeface();
  RELEASE_ASSERT(typeface);
  typeface->charsToGlyphs(&codepoint, SkTypeface::kUTF32_Encoding, &glyph, 1);
  return glyph;
}
	bool setFont(const char * pFontName = NULL, int nSize = 0)
	{
		bool bRet = false;

		if (m_pPaint)
		{
			delete m_pPaint;
			m_pPaint = NULL;
		}

		do 
		{
			/* init paint */
			m_pPaint = new SkPaint();
			CC_BREAK_IF(! m_pPaint);
			m_pPaint->setColor(SK_ColorWHITE);
			m_pPaint->setTextSize(nSize);

			/* create font */
			SkTypeface *pTypeFace = SkTypeface::CreateFromName(pFontName, SkTypeface::kNormal);
			if (! pTypeFace)
			{
				CC_SAFE_DELETE(m_pPaint);
				break;
			}
			m_pPaint->setTypeface( pTypeFace );
			/* can not unref, I don't know why. It may be memory leak, but how to avoid? */
			pTypeFace->unref();

			bRet = true;
		} while (0);

		return bRet;
	}
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();
}
Beispiel #4
0
static void drawKernText(SkCanvas* canvas, const void* text, size_t len,
                         SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint) {
    SkTypeface* face = font.getTypefaceOrDefault();
    if (!face) {
        canvas->drawSimpleText(text, len, SkTextEncoding::kUTF8, x, y, font, paint);
        return;
    }

    SkAutoSTMalloc<128, uint16_t> glyphStorage(len);
    uint16_t* glyphs = glyphStorage.get();
    int glyphCount = font.textToGlyphs(text, len, SkTextEncoding::kUTF8, glyphs, len);
    if (glyphCount < 1) {
        return;
    }

    SkAutoSTMalloc<128, int32_t> adjustmentStorage(glyphCount - 1);
    int32_t* adjustments = adjustmentStorage.get();
    if (!face->getKerningPairAdjustments(glyphs, glyphCount, adjustments)) {
        canvas->drawSimpleText(text, len, SkTextEncoding::kUTF8, x, y, font, paint);
        return;
    }


    SkTextBlobBuilder builder;
    auto rec = builder.allocRunPos(font, glyphCount);
    memcpy(rec.glyphs, glyphs, glyphCount * sizeof(SkGlyphID));
    getGlyphPositions(font, glyphs, glyphCount, x, y, rec.points());
    applyKerning(rec.points(), adjustments, glyphCount, font);

    canvas->drawTextBlob(builder.make(), 0, 0, paint);
}
Beispiel #5
0
static SkScalar drawCharacter(SkCanvas* canvas, uint32_t character, SkScalar x,
                              SkScalar y, SkPaint& paint, SkFontMgr* fm,
                              const char* fontName, const char* bcp47[], int bcp47Count,
                              const SkFontStyle& fontStyle) {
    // find typeface containing the requested character and draw it
    SkString ch;
    ch.appendUnichar(character);
    SkTypeface* typeface = fm->matchFamilyStyleCharacter(fontName, fontStyle,
                                                         bcp47, bcp47Count, character);
    SkSafeUnref(paint.setTypeface(typeface));
    x = drawString(canvas, ch, x, y, paint) + 20;

    if (nullptr == typeface) {
        return x;
    }

    // repeat the process, but this time use the family name of the typeface
    // from the first pass.  This emulates the behavior in Blink where it
    // it expects to get the same glyph when following this pattern.
    SkString familyName;
    typeface->getFamilyName(&familyName);
    SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->fontStyle());
    SkSafeUnref(paint.setTypeface(typefaceCopy));
    return drawString(canvas, ch, x, y, paint) + 20;
}
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
                                       const char familyName[],
                                       SkTypeface::Style style) {
    load_system_fonts();

    SkAutoMutexAcquire  ac(gFamilyMutex);
    
    // clip to legal style bits
    style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
    
    SkTypeface* tf = NULL;

    if (NULL != familyFace) {
        tf = find_typeface(familyFace, style);
    } else if (NULL != familyName) {
//        SkDebugf("======= familyName <%s>\n", familyName);
        tf = find_typeface(familyName, style);
    }

    if (NULL == tf) {
        tf = find_best_face(gDefaultFamily, style);
    }

    // we ref(), since the symantic is to return a new instance
    tf->ref();
    return tf;
}
Beispiel #7
0
bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const
{
    if (U16_IS_LEAD(buffer[bufferLength-1])) {
        DLOG(ERROR) << "Last UTF-16 code unit is high-surrogate.";
        return false;
    }

    SkTypeface* typeface = platformData().typeface();
    if (!typeface) {
        DLOG(ERROR) << "fillGlyphPage called on an empty Skia typeface.";
        return false;
    }

    SkAutoSTMalloc<GlyphPage::size, uint16_t> glyphStorage(length);
    uint16_t* glyphs = glyphStorage.get();
    typeface->charsToGlyphs(buffer, SkTypeface::kUTF16_Encoding, glyphs, length);

    bool haveGlyphs = false;
    for (unsigned i = 0; i < length; i++) {
        if (glyphs[i]) {
            pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this);
            haveGlyphs = true;
        }
    }

    return haveGlyphs;
}
// 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
}
Beispiel #9
0
SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) {
    if (!SkTypeface_ValidScript(script)) {
        return NULL;
    }

    // ensure that our table is populated
    initFBScriptInfo();

    FBScriptInfo& scriptInfo = gFBScriptInfo[script];

    // ensure the element with that index actually maps to the correct script
    SkASSERT(scriptInfo.fScript == script);

    // if a suitable script could not be found then return NULL
    if (scriptInfo.fFontID == 0) {
        return NULL;
    }

    SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);

    // retrieve the typeface the corresponds to this fontID
    SkTypeface* tf = find_from_uniqueID(scriptInfo.fFontID);
    // we ref(), since the semantic is to return a new instance
    tf->ref();
    return tf;
}
bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill,
                                   unsigned offset,
                                   unsigned length,
                                   UChar* buffer,
                                   unsigned bufferLength) const {
  if (U16_IS_LEAD(buffer[bufferLength - 1])) {
    SkDebugf("%s last char is high-surrogate", __FUNCTION__);
    return false;
  }

  SkAutoSTMalloc<GlyphPage::size, uint16_t> glyphStorage(length);

  uint16_t* glyphs = glyphStorage.get();
  SkTypeface* typeface = platformData().typeface();
  typeface->charsToGlyphs(buffer, SkTypeface::kUTF16_Encoding, glyphs, length);

  bool haveGlyphs = false;
  for (unsigned i = 0; i < length; i++) {
    if (glyphs[i]) {
      pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this);
      haveGlyphs = true;
    }
  }

  return haveGlyphs;
}
Beispiel #11
0
SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic) {
    SkTDict<SkPdfStandardFontEntry>& standardFontMap = getStandardFonts();

    SkTypeface* typeface = NULL;
    SkPdfStandardFontEntry fontData;

    if (standardFontMap.find(fontName, &fontData)) {
        // TODO(edisonn): How does the bold/italic specified in standard definition combines with
        // the one in /font key? use OR for now.
        bold = bold || fontData.fIsBold;
        italic = italic || fontData.fIsItalic;

        typeface = SkTypeface::CreateFromName(
            fontData.fName,
            SkTypeface::Style((bold ? SkTypeface::kBold : 0) |
                              (italic ? SkTypeface::kItalic : 0)));
    } else {
        typeface = SkTypeface::CreateFromName(
            fontName,
            SkTypeface::kNormal);
    }

    if (typeface) {
        typeface->ref();
    }
    return typeface;
}
Beispiel #12
0
static void drawKernText(SkCanvas* canvas, const void* text, size_t len,
                         SkScalar x, SkScalar y, const SkPaint& paint) {
    SkTypeface* face = paint.getTypeface();
    if (!face) {
        canvas->drawText(text, len, x, y, paint);
        return;
    }

    SkAutoSTMalloc<128, uint16_t> glyphStorage(len);
    uint16_t* glyphs = glyphStorage.get();
    int glyphCount = paint.textToGlyphs(text, len, glyphs);
    if (glyphCount < 1) {
        return;
    }

    SkAutoSTMalloc<128, int32_t> adjustmentStorage(glyphCount - 1);
    int32_t* adjustments = adjustmentStorage.get();
    if (!face->getKerningPairAdjustments(glyphs, glyphCount, adjustments)) {
        canvas->drawText(text, len, x, y, paint);
        return;
    }

    SkPaint glyphPaint(paint);
    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

    SkAutoSTMalloc<128, SkPoint> posStorage(glyphCount);
    SkPoint* pos = posStorage.get();
    getGlyphPositions(glyphPaint, glyphs, glyphCount, x, y, pos);

    applyKerning(pos, adjustments, glyphCount, glyphPaint);
    canvas->drawPosText(glyphs, glyphCount * sizeof(uint16_t), pos, glyphPaint);
}
FONTDef
_DC::SelectObject(FONTDef font){
	if( !context_ )
		return NULL;
	
	if (_canvas) {
		LOGFONT lf;
		::GetObject(font, sizeof(LOGFONT), &lf);
		SkTypeface::Style style = SkTypeface::Style::kNormal;
		if (lf.lfItalic) {
			if (lf.lfWidth == FW_BOLD)
				style = SkTypeface::Style::kBoldItalic;
			else
				style = SkTypeface::Style::kItalic;
		}
		else {
			if (lf.lfWidth == FW_BOLD)
				style = SkTypeface::Style::kBold;
			else
				style = SkTypeface::Style::kNormal;
		}

		SkTypeface* tf = SkTypeface::CreateFromName(lf.lfFaceName, style);
		_skPaintText.setTypeface(tf);
		_skPaintText.setAntiAlias(true);
		_skPaintText.setTextSize(SkIntToScalar(lf.lfHeight));
		_skPaintText.setTextEncoding(SkPaint::TextEncoding::kUTF8_TextEncoding);
		tf->unref();
	}
	
	return (FONTDef)::SelectObject(context_, font);
	}
Beispiel #14
0
static void charsToGlyphsNull_proc(int loops, const SkPaint& paint, const void* text,
                                   size_t len, int glyphCount) {
    SkTypeface::Encoding encoding = paint2Encoding(paint);

    SkTypeface* face = paint.getTypeface();
    for (int i = 0; i < loops; ++i) {
        face->charsToGlyphs(text, encoding, NULL, glyphCount);
    }
}
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription,
                                                    const AtomicString& family)
{
    const char* name = 0;
    CString s;

    if (family.length() == 0) {
        static const struct {
            FontDescription::GenericFamilyType mType;
            const char* mName;
        } fontDescriptions[] = {
            { FontDescription::SerifFamily, "serif" },
            { FontDescription::SansSerifFamily, "sans-serif" },
            { FontDescription::MonospaceFamily, "monospace" },
            { FontDescription::CursiveFamily, "cursive" },
            { FontDescription::FantasyFamily, "fantasy" }
        };

        FontDescription::GenericFamilyType type = fontDescription.genericFamily();
        for (unsigned i = 0; i < SK_ARRAY_COUNT(fontDescriptions); i++) {
            if (type == fontDescriptions[i].mType) {
                name = fontDescriptions[i].mName;
                break;
            }
        }
        // if we fall out of the loop, it's ok for name to still be 0
    }
    else {    // convert the name to utf8
        s = family.string().utf8();
        name = s.data();
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;

    // FIXME:  This #ifdef can go away once we're firmly using the new Skia.
    // During the transition, this makes the code compatible with both versions.
#ifdef SK_USE_OLD_255_TO_256
    SkTypeface* tf = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
#else
    SkTypeface* tf = SkTypeface::Create(name, static_cast<SkTypeface::Style>(style));
#endif
    if (!tf)
        return 0;

    FontPlatformData* result =
        new FontPlatformData(tf,
                             fontDescription.computedSize(),
                             (style & SkTypeface::kBold) && !tf->isBold(),
                             (style & SkTypeface::kItalic) && !tf->isItalic());
    tf->unref();
    return result;
}
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription,
                                                    const AtomicString& family)
{
    const char* name = 0;
    CString s;

    // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
    // the fallback name (like "monospace") that fontconfig understands.
    if (!family.length() || family.startsWith("-webkit-")) {
        static const struct {
            FontDescription::GenericFamilyType mType;
            const char* mName;
        } fontDescriptions[] = {
            { FontDescription::SerifFamily, "serif" },
            { FontDescription::SansSerifFamily, "sans-serif" },
            { FontDescription::MonospaceFamily, "monospace" },
            { FontDescription::CursiveFamily, "cursive" },
            { FontDescription::FantasyFamily, "fantasy" }
        };

        FontDescription::GenericFamilyType type = fontDescription.genericFamily();
        for (unsigned i = 0; i < SK_ARRAY_COUNT(fontDescriptions); i++) {
            if (type == fontDescriptions[i].mType) {
                name = fontDescriptions[i].mName;
                break;
            }
        }
        if (!name)
            name = "";
    } else {
        // convert the name to utf8
        s = family.string().utf8();
        name = s.data();
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;

    SkTypeface* tf = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
    if (!tf)
        return 0;

    FontPlatformData* result =
        new FontPlatformData(tf,
                             name,
                             fontDescription.computedSize(),
                             (style & SkTypeface::kBold) && !tf->isBold(),
                             (style & SkTypeface::kItalic) && !tf->isItalic(),
                             fontDescription.orientation(),
                             fontDescription.textOrientation());
    tf->unref();
    return result;
}
ACanvasSkia::~ACanvasSkia()
{
	for(std::map<AString,SkTypeface*>::iterator it=m_aFontType.begin();it!=m_aFontType.end();it++)
	{
		SkTypeface* p = it->second;
		p->unref();
	}
	m_aFontType.clear();
	Free();
}
Beispiel #18
0
DEF_TEST(Paint_cmap, reporter) {
    // need to implement charsToGlyphs on other backends (e.g. linux, win)
    // before we can run this tests everywhere
    return;

    static const int NGLYPHS = 64;

    SkUnichar src[NGLYPHS];
    SkUnichar dst[NGLYPHS]; // used for utf8, utf16, utf32 storage

    static const struct {
        size_t (*fSeedTextProc)(const SkUnichar[], void* dst, int count);
        SkPaint::TextEncoding   fEncoding;
    } gRec[] = {
        { uni_to_utf8,  SkPaint::kUTF8_TextEncoding },
        { uni_to_utf16, SkPaint::kUTF16_TextEncoding },
        { uni_to_utf32, SkPaint::kUTF32_TextEncoding },
    };

    SkRandom rand;
    SkPaint paint;
    paint.setTypeface(SkTypeface::RefDefault())->unref();
    SkTypeface* face = paint.getTypeface();

    for (int i = 0; i < 1000; ++i) {
        // generate some random text
        for (int j = 0; j < NGLYPHS; ++j) {
            src[j] = ' ' + j;
        }
        // inject some random chars, to sometimes abort early
        src[rand.nextU() & 63] = rand.nextU() & 0xFFF;

        for (size_t k = 0; k < SK_ARRAY_COUNT(gRec); ++k) {
            paint.setTextEncoding(gRec[k].fEncoding);

            size_t len = gRec[k].fSeedTextProc(src, dst, NGLYPHS);

            uint16_t    glyphs0[NGLYPHS], glyphs1[NGLYPHS];

            bool contains = paint.containsText(dst, len);
            int nglyphs = paint.textToGlyphs(dst, len, glyphs0);
            int first = face->charsToGlyphs(dst, paint2encoding(paint), glyphs1, NGLYPHS);
            int index = find_first_zero(glyphs1, NGLYPHS);

            REPORTER_ASSERT(reporter, NGLYPHS == nglyphs);
            REPORTER_ASSERT(reporter, index == first);
            REPORTER_ASSERT(reporter, 0 == memcmp(glyphs0, glyphs1, NGLYPHS * sizeof(uint16_t)));
            if (contains) {
                REPORTER_ASSERT(reporter, NGLYPHS == first);
            } else {
                REPORTER_ASSERT(reporter, NGLYPHS > first);
            }
        }
    }
}
Beispiel #19
0
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    char*       storage = 0;
    const char* name = 0;

    if (family.length() == 0) {
        static const struct {
            FontDescription::GenericFamilyType  mType;
            const char*                         mName;
        } gNames[] = {
            { FontDescription::SerifFamily,     "serif" },
            { FontDescription::SansSerifFamily, "sans-serif" },
            { FontDescription::MonospaceFamily, "monospace" },
            { FontDescription::CursiveFamily,   "cursive" },
            { FontDescription::FantasyFamily,   "fantasy" }
        };

        FontDescription::GenericFamilyType type = fontDescription.genericFamily();
        for (unsigned i = 0; i < SK_ARRAY_COUNT(gNames); i++)
        {
            if (type == gNames[i].mType)
            {
                name = gNames[i].mName;
                break;
            }
        }
        // if we fall out of the loop, its ok for name to still be 0
    }
    else {    // convert the name to utf8
        storage = AtomicStringToUTF8String(family);
        name = storage;
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;

    SkTypeface* tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style);

    if (!tf)
        return 0;

    FontPlatformData* result = new FontPlatformData(tf,
                                                    name,
                                                    fontDescription.computedSize(),
                                                    (style & SkTypeface::kBold) && !tf->isBold(),
                                                    (style & SkTypeface::kItalic) && !tf->isItalic());
    tf->unref();

    sk_free(storage);
    return result;
}
Beispiel #20
0
static void charsToGlyphs_proc(int loops, const SkPaint& paint, const void* text,
                               size_t len, int glyphCount) {
    SkTypeface::Encoding encoding = paint2Encoding(paint);
    uint16_t glyphs[NGLYPHS];
    SkASSERT(glyphCount <= NGLYPHS);

    SkTypeface* face = paint.getTypeface();
    for (int i = 0; i < loops; ++i) {
        face->charsToGlyphs(text, encoding, glyphs, glyphCount);
    }
}
Beispiel #21
0
/**
 *  This guy is public. It first searches the cache, and if a match is not found,
 *  it creates a new face.
 */
SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
    LOGFONT lf = origLF;
    make_canonical(&lf);
    SkTypeface* face = SkTypefaceCache::FindByProc(FindByLogFont, &lf);
    if (face) {
        face->ref();
    } else {
        face = LogFontTypeface::Create(lf);
        SkTypefaceCache::Add(face, get_style(lf));
    }
    return face;
}
Beispiel #22
0
SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, const SkFontStyle& style, bool isFixedWidth)
{
    SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));

    if (typeface) {
        typeface->ref();
    } else {
        typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
        SkTypefaceCache::Add(typeface, style);
    }

    return typeface;
}
/*  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;
}
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    char* storage = 0;
    const char* name = 0;
    FontPlatformData* result = 0;

    if (family.length()) {
        storage = AtomicStringToUTF8String(family);
        name = storage;
    } else
        name = getFallbackFontName(fontDescription);

    int style = SkTypeface::kNormal;
#ifndef FONT_SOFTWARE_RENDER
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;
#endif

    // CreateFromName always returns a typeface, falling back to a default font
    // if the one requested is not found. Calling Equal() with a null pointer
    // serves to compare the returned font against the default, with the caveat
    // that the default is always of normal style. If we detect the default, we
    // ignore it and allow WebCore to give us the next font on the CSS fallback
    // list. The only exception is if the family name is a commonly used generic
    // family, as when called by getSimilarFontPlatformData() and
    // getLastResortFallbackFont(). In this case, the default font is an
    // acceptable result.

    SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);

    if (!SkTypeface::Equal(tf, 0) || isFallbackFamily(family.string())) {
        // We had to use normal styling to see if this was a default font. If
        // we need bold or italic, replace with the corrected typeface.
        if (style != SkTypeface::kNormal) {
            tf->unref();
            tf = SkTypeface::CreateFromName(name, (SkTypeface::Style)style);
        }

        result = new FontPlatformData(tf, fontDescription.computedSize(),
                            (style & SkTypeface::kBold),
                            (style & SkTypeface::kItalic) && !tf->isItalic(),
                            fontDescription.orientation(),
                            fontDescription.textOrientation());
    }

    tf->unref();
    sk_free(storage);
    return result;
}
Beispiel #25
0
DEF_TEST(FontHostStream, reporter) {
    {
        SkPaint paint;
        paint.setColor(SK_ColorGRAY);
        paint.setTextSize(SkIntToScalar(30));

        SkTypeface* fTypeface = SkTypeface::CreateFromName("Georgia",
                                                           SkTypeface::kNormal);
        SkSafeUnref(paint.setTypeface(fTypeface));

        SkIRect origRect = SkIRect::MakeWH(64, 64);
        SkBitmap origBitmap;
        create(&origBitmap, origRect);
        SkCanvas origCanvas(origBitmap);

        SkIRect streamRect = SkIRect::MakeWH(64, 64);
        SkBitmap streamBitmap;
        create(&streamBitmap, streamRect);
        SkCanvas streamCanvas(streamBitmap);

        SkPoint point = SkPoint::Make(24, 32);

        // Test: origTypeface and streamTypeface from orig data draw the same
        drawBG(&origCanvas);
        origCanvas.drawText("A", 1, point.fX, point.fY, paint);

        SkTypeface* origTypeface = paint.getTypeface();
        SkAutoTUnref<SkTypeface> aur;
        if (NULL == origTypeface) {
            origTypeface = aur.reset(SkTypeface::RefDefault());
        }

        int ttcIndex;
        SkAutoTDelete<SkStreamAsset> fontData(origTypeface->openStream(&ttcIndex));
        SkTypeface* streamTypeface = SkTypeface::CreateFromStream(fontData.detach());

        SkFontDescriptor desc;
        bool isLocalStream = false;
        streamTypeface->getFontDescriptor(&desc, &isLocalStream);
        REPORTER_ASSERT(reporter, isLocalStream);

        SkSafeUnref(paint.setTypeface(streamTypeface));
        drawBG(&streamCanvas);
        streamCanvas.drawPosText("A", 1, &point, paint);

        REPORTER_ASSERT(reporter,
                        compare(origBitmap, origRect, streamBitmap, streamRect));
    }
    //Make sure the typeface is deleted and removed.
    SkGraphics::PurgeFontCache();
}
Beispiel #26
0
    GlyphGenerator(const SkTypeface& typeface, const SkScalerContextEffects& effects,
                   const SkDescriptor& desc)
        : fScalerContext(typeface.createScalerContext(effects, &desc))
#ifdef SK_DEBUG
        , fDesc(desc.copy())
#endif
    {}
Beispiel #27
0
std::unique_ptr<SkScalerContext> SkGlyphCache::CreateScalerContext(
        const SkDescriptor& desc,
        const SkScalerContextEffects& effects,
        const SkTypeface& typeface) {
    auto scaler = typeface.createScalerContext(effects, &desc, true /* can fail */);

    // Check if we can create a scaler-context before creating the glyphcache.
    // If not, we may have exhausted OS/font resources, so try purging the
    // cache once and try again
    // pass true the first time, to notice if the scalercontext failed,
    if (scaler == nullptr) {
        get_globals().purgeAll();
        scaler = typeface.createScalerContext(effects, &desc, false /* must succeed */);
    }
    return scaler;
}
Beispiel #28
0
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    const char* name = 0;

    // If a fallback font is being created (e.g. "-webkit-monospace"), convert
    // it in to the fallback name (e.g. "monospace").
    if (!family.length() || family.startsWith("-webkit-"))
        name = getFallbackFontName(fontDescription);
    else
        name = family.string().utf8().data();

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;

    SkTypeface* typeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
    FontPlatformData* result = 0;

    // CreateFromName always returns a typeface, falling back to a default font
    // if the one requested could not be found. Calling Equal() with a null
    // pointer will compare the returned font against the default, with the
    // caveat that the default is always of normal style. When that happens,
    // ignore the default font and allow WebCore to provide the next font on the
    // CSS fallback list. The only exception to this occurs when the family name
    // is a commonly used generic family, which is the case when called by
    // getSimilarFontPlatformData() or getLastResortFallbackFont(). In that case
    // the default font is an acceptable result.

    if (!SkTypeface::Equal(typeface, 0) || isFallbackFamily(family.string())) {
        if (style != SkTypeface::kNormal) {
            typeface->unref();
            typeface = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
        }

        result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
                                      (style & SkTypeface::kBold) && !typeface->isBold(),
                                      (style & SkTypeface::kItalic) && !typeface->isItalic(),
                                      fontDescription.orientation(),
                                      fontDescription.textOrientation());
    }

    typeface->unref();
    return result;
}
Beispiel #29
0
SkTypeface* SkCreateFallbackTypefaceForChar(SkUnichar uni,
                                            SkTypeface::Style style) {
    {
        SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);
        load_system_fonts();
    }

    SkTypeface* tf = findFallbackTypefaceForChar(uni);
    if (!tf) {
        return NULL;
    }
    SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);
    tf = find_typeface(tf, style);
    // we ref(), since the semantic is to return a new instance
    tf->ref();
    return tf;
}
Beispiel #30
0
    GlyphGenerator(const SkTypeface& typeface, const SkDescriptor& desc)
        : fScalerContext(typeface.createScalerContext(&desc))
#ifdef SK_DEBUG
        , fDesc(desc.copy())
#endif
    {
        fFlipMatrix.setScale(1, -1);
    }