fontmgr.cpp revision 7103344b64f3f0df88e76857c16edc8eedb58366
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "gm.h" 9#include "SkCanvas.h" 10#include "SkFontMgr.h" 11#include "SkGraphics.h" 12#include "SkTypeface.h" 13 14// limit this just so we don't take too long to draw 15#define MAX_FAMILIES 30 16 17static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x, 18 SkScalar y, const SkPaint& paint) { 19 canvas->drawText(text.c_str(), text.size(), x, y, paint); 20 return x + paint.measureText(text.c_str(), text.size()); 21} 22 23class FontMgrGM : public skiagm::GM { 24public: 25 FontMgrGM() { 26 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024); 27 } 28 29protected: 30 virtual SkString onShortName() { 31 return SkString("fontmgr_iter"); 32 } 33 34 virtual SkISize onISize() { 35 return SkISize::Make(640, 1024); 36 } 37 38 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 39 SkScalar y = 20; 40 SkPaint paint; 41 paint.setAntiAlias(true); 42 paint.setLCDRenderText(true); 43 paint.setSubpixelText(true); 44 paint.setTextSize(17); 45 46 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); 47 int count = SkMin32(fm->countFamilies(), MAX_FAMILIES); 48 49 for (int i = 0; i < count; ++i) { 50 SkString fname; 51 fm->getFamilyName(i, &fname); 52 paint.setTypeface(NULL); 53 (void)drawString(canvas, fname, 20, y, paint); 54 55 SkScalar x = 220; 56 57 SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i)); 58 for (int j = 0; j < set->count(); ++j) { 59 SkString sname; 60 SkFontStyle fs; 61 set->getStyle(j, &fs, &sname); 62 sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.isItalic()); 63 64 SkSafeUnref(paint.setTypeface(set->createTypeface(j))); 65 x = drawString(canvas, sname, x, y, paint) + 20; 66 } 67 y += 24; 68 } 69 } 70 71 virtual uint32_t onGetFlags() const SK_OVERRIDE { 72 // fontdescriptors (and therefore serialization) don't yet understand 73 // these new styles, so skip tests that exercise that for now. 74 75 // If certain fonts are picked up (e.g. Microsoft Jhenghei 20MB for Regular, 12MB for Bold), 76 // the resulting pdf can be ~700MB and crashes Chrome's PDF viewer. 77 78 return kSkipPicture_Flag | kSkipPipe_Flag | kSkipPDF_Flag; 79 } 80 81private: 82 typedef GM INHERITED; 83}; 84 85class FontMgrMatchGM : public skiagm::GM { 86 SkAutoTUnref<SkFontMgr> fFM; 87 88public: 89 FontMgrMatchGM() : fFM(SkFontMgr::RefDefault()) { 90 SkGraphics::SetFontCacheLimit(16 * 1024 * 1024); 91 } 92 93protected: 94 virtual SkString onShortName() { 95 return SkString("fontmgr_match"); 96 } 97 98 virtual SkISize onISize() { 99 return SkISize::Make(640, 1024); 100 } 101 102 void iterateFamily(SkCanvas* canvas, const SkPaint& paint, 103 SkFontStyleSet* fset) { 104 SkPaint p(paint); 105 SkScalar y = 0; 106 107 for (int j = 0; j < fset->count(); ++j) { 108 SkString sname; 109 SkFontStyle fs; 110 fset->getStyle(j, &fs, &sname); 111 112 sname.appendf(" [%d %d]", fs.weight(), fs.width()); 113 114 SkSafeUnref(p.setTypeface(fset->createTypeface(j))); 115 (void)drawString(canvas, sname, 0, y, p); 116 y += 24; 117 } 118 } 119 120 void exploreFamily(SkCanvas* canvas, const SkPaint& paint, 121 SkFontStyleSet* fset) { 122 SkPaint p(paint); 123 SkScalar y = 0; 124 125 for (int weight = 100; weight <= 900; weight += 200) { 126 for (int width = 1; width <= 9; width += 2) { 127 SkFontStyle fs(weight, width, SkFontStyle::kUpright_Slant); 128 SkTypeface* face = fset->matchStyle(fs); 129 if (face) { 130 SkString str; 131 str.printf("request [%d %d]", fs.weight(), fs.width()); 132 p.setTypeface(face)->unref(); 133 (void)drawString(canvas, str, 0, y, p); 134 y += 24; 135 } 136 } 137 } 138 } 139 140 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 141 SkPaint paint; 142 paint.setAntiAlias(true); 143 paint.setLCDRenderText(true); 144 paint.setSubpixelText(true); 145 paint.setTextSize(17); 146 147 static const char* gNames[] = { 148 "Helvetica Neue", "Arial" 149 }; 150 151 SkFontStyleSet* fset = NULL; 152 for (size_t i = 0; i < SK_ARRAY_COUNT(gNames); ++i) { 153 fset = fFM->matchFamily(gNames[i]); 154 if (fset && fset->count() > 0) { 155 break; 156 } 157 } 158 159 if (NULL == fset) { 160 return; 161 } 162 SkAutoUnref aur(fset); 163 164 canvas->translate(20, 40); 165 this->exploreFamily(canvas, paint, fset); 166 canvas->translate(150, 0); 167 this->iterateFamily(canvas, paint, fset); 168 } 169 170 virtual uint32_t onGetFlags() const SK_OVERRIDE { 171 // fontdescriptors (and therefore serialization) don't yet understand 172 // these new styles, so skip tests that exercise that for now. 173 return kSkipPicture_Flag | kSkipPipe_Flag; 174 } 175 176private: 177 typedef GM INHERITED; 178}; 179 180////////////////////////////////////////////////////////////////////////////// 181 182DEF_GM( return SkNEW(FontMgrGM); ) 183DEF_GM( return SkNEW(FontMgrMatchGM); ) 184