|  | /* | 
|  | * Copyright 2013 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "gm.h" | 
|  | #include "SkCanvas.h" | 
|  | #include "SkFontMgr.h" | 
|  | #include "SkGraphics.h" | 
|  | #include "SkTypeface.h" | 
|  |  | 
|  | #ifdef SK_BUILD_FOR_WIN | 
|  | #include "SkTypeface_win.h" | 
|  | #endif | 
|  |  | 
|  | // limit this just so we don't take too long to draw | 
|  | #define MAX_FAMILIES    30 | 
|  |  | 
|  | static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x, | 
|  | SkScalar y, const SkPaint& paint) { | 
|  | canvas->drawText(text.c_str(), text.size(), x, y, paint); | 
|  | return x + paint.measureText(text.c_str(), text.size()); | 
|  | } | 
|  |  | 
|  | class FontMgrGM : public skiagm::GM { | 
|  | public: | 
|  | FontMgrGM(SkFontMgr* fontMgr = NULL) { | 
|  | SkGraphics::SetFontCacheLimit(16 * 1024 * 1024); | 
|  |  | 
|  | fName.set("fontmgr_iter"); | 
|  | if (fontMgr) { | 
|  | fName.append("_factory"); | 
|  | fFM.reset(fontMgr); | 
|  | } else { | 
|  | fFM.reset(SkFontMgr::RefDefault()); | 
|  | } | 
|  | } | 
|  |  | 
|  | protected: | 
|  | virtual SkString onShortName() { | 
|  | return fName; | 
|  | } | 
|  |  | 
|  | virtual SkISize onISize() { | 
|  | return SkISize::Make(640, 1024); | 
|  | } | 
|  |  | 
|  | virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 
|  | SkScalar y = 20; | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | paint.setLCDRenderText(true); | 
|  | paint.setSubpixelText(true); | 
|  | paint.setTextSize(17); | 
|  |  | 
|  | SkFontMgr* fm = fFM; | 
|  | int count = SkMin32(fm->countFamilies(), MAX_FAMILIES); | 
|  |  | 
|  | for (int i = 0; i < count; ++i) { | 
|  | SkString fname; | 
|  | fm->getFamilyName(i, &fname); | 
|  | paint.setTypeface(NULL); | 
|  | (void)drawString(canvas, fname, 20, y, paint); | 
|  |  | 
|  | SkScalar x = 220; | 
|  |  | 
|  | SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i)); | 
|  | for (int j = 0; j < set->count(); ++j) { | 
|  | SkString sname; | 
|  | SkFontStyle fs; | 
|  | set->getStyle(j, &fs, &sname); | 
|  | sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic()); | 
|  |  | 
|  | SkSafeUnref(paint.setTypeface(set->createTypeface(j))); | 
|  | x = drawString(canvas, sname, x, y, paint) + 20; | 
|  | } | 
|  | y += 24; | 
|  | } | 
|  | } | 
|  |  | 
|  | virtual uint32_t onGetFlags() const SK_OVERRIDE { | 
|  | // fontdescriptors (and therefore serialization) don't yet understand | 
|  | // these new styles, so skip tests that exercise that for now. | 
|  |  | 
|  | // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold), | 
|  | // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer. | 
|  |  | 
|  | return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag; | 
|  | } | 
|  |  | 
|  | private: | 
|  | SkAutoTUnref<SkFontMgr> fFM; | 
|  | SkString fName; | 
|  | typedef GM INHERITED; | 
|  | }; | 
|  |  | 
|  | class FontMgrMatchGM : public skiagm::GM { | 
|  | SkAutoTUnref<SkFontMgr> fFM; | 
|  |  | 
|  | public: | 
|  | FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) { | 
|  | SkGraphics::SetFontCacheLimit(16 * 1024 * 1024); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | virtual SkString onShortName() { | 
|  | return SkString("fontmgr_match"); | 
|  | } | 
|  |  | 
|  | virtual SkISize onISize() { | 
|  | return SkISize::Make(640, 1024); | 
|  | } | 
|  |  | 
|  | void iterateFamily(SkCanvas* canvas, const SkPaint& paint, | 
|  | SkFontStyleSet* fset) { | 
|  | SkPaint p(paint); | 
|  | SkScalar y = 0; | 
|  |  | 
|  | for (int j = 0; j < fset->count(); ++j) { | 
|  | SkString sname; | 
|  | SkFontStyle fs; | 
|  | fset->getStyle(j, &fs, &sname); | 
|  |  | 
|  | sname.appendf(" [%d %d]", fs.weight(), fs.width()); | 
|  |  | 
|  | SkSafeUnref(p.setTypeface(fset->createTypeface(j))); | 
|  | (void)drawString(canvas, sname, 0, y, p); | 
|  | y += 24; | 
|  | } | 
|  | } | 
|  |  | 
|  | void exploreFamily(SkCanvas* canvas, const SkPaint& paint, | 
|  | SkFontStyleSet* fset) { | 
|  | SkPaint p(paint); | 
|  | SkScalar y = 0; | 
|  |  | 
|  | for (int weight = 100; weight <= 900; weight += 200) { | 
|  | for (int width = 1; width <= 9; width += 2) { | 
|  | SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant); | 
|  | SkTypeface* face = fset->matchStyle(fs); | 
|  | if (face) { | 
|  | SkString str; | 
|  | str.printf("request [%d %d]", fs.weight(), fs.width()); | 
|  | p.setTypeface(face)->unref(); | 
|  | (void)drawString(canvas, str, 0, y, p); | 
|  | y += 24; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | paint.setLCDRenderText(true); | 
|  | paint.setSubpixelText(true); | 
|  | paint.setTextSize(17); | 
|  |  | 
|  | static const char* gNames[] = { | 
|  | "Helvetica Neue", "Arial" | 
|  | }; | 
|  |  | 
|  | SkAutoTUnref<SkFontStyleSet> fset; | 
|  | for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) { | 
|  | fset.reset(fFM->matchFamily(gNames[i])); | 
|  | if (fset->count() > 0) { | 
|  | break; | 
|  | } | 
|  | } | 
|  | if (NULL == fset.get()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | canvas->translate(20, 40); | 
|  | this->exploreFamily(canvas, paint, fset); | 
|  | canvas->translate(150, 0); | 
|  | this->iterateFamily(canvas, paint, fset); | 
|  | } | 
|  |  | 
|  | virtual uint32_t onGetFlags() const SK_OVERRIDE { | 
|  | // fontdescriptors (and therefore serialization) don't yet understand | 
|  | // these new styles, so skip tests that exercise that for now. | 
|  | return kSkipPicture_Flag | kSkipPipe_Flag; | 
|  | } | 
|  |  | 
|  | private: | 
|  | typedef GM INHERITED; | 
|  | }; | 
|  |  | 
|  | ////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | DEF_GM( return SkNEW(FontMgrGM); ) | 
|  | DEF_GM( return SkNEW(FontMgrMatchGM); ) | 
|  |  | 
|  | #ifdef SK_BUILD_FOR_WIN | 
|  | DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite())); ) | 
|  | #endif |