Add standard fonts to all GMs.

Allow GM results to be compared across machines and platforms by
standardizing the fonts used by all tests.

This adds runtime flags to DM to use either the system font context (the
default), the fonts in the resources directory ( --resourceFonts ) or a set
of canonical paths generated from the fonts ( --portableFonts ).

This CL should leave the current DM results unchanged by default.

If the portable font data or resource font is missing when DM is run, it
falls back to using the system font context.

The create_test_font tool generates the paths and metrics read by DM
with the --portableFonts flag set, and generates the font substitution
tables read by DM with the --resourceFonts flag set.

If DM is run in SkDebug mode with the --reportUsedChars flag set, it
generates the corresponding data compiled into the create_test_font tool.

All GM tests set their typeface information by calling either

  sk_tool_utils::set_portable_typeface or
  sk_tool_utils::portable_typeface .

(The former takes the paint, the latter returns a SkTypeface.) These calls
can be removed in the future when the Font Manager can be superceded.

BUG=skia:2687
R=mtklein@google.com

Review URL: https://codereview.chromium.org/407183003
This commit is contained in:
Cary Clark 2014-07-31 08:58:44 -04:00
parent 3f22e8c44a
commit 992c7b03ef
69 changed files with 9644 additions and 3172 deletions

View File

@ -9,6 +9,8 @@
#include "SkString.h"
#include "Test.h"
#include "gm.h"
#include "sk_tool_utils.h"
#include "sk_tool_utils_flags.h"
#include "DMCpuGMTask.h"
#include "DMGpuGMTask.h"
@ -48,6 +50,8 @@ DEFINE_string(skps, "", "Directory to read skps from.");
DEFINE_bool(gms, true, "Run GMs?");
DEFINE_bool(tests, true, "Run tests?");
DEFINE_bool(reportUsedChars, false, "Output test font construction data to be pasted into"
" create_test_font.cpp.");
__SK_FORCE_IMAGE_DECODER_LINKING;
@ -238,7 +242,12 @@ int dm_main() {
tasks.wait();
SkDebugf("\n");
#ifdef SK_DEBUG
if (FLAGS_portableFonts && FLAGS_reportUsedChars) {
sk_tool_utils::report_used_chars();
}
#endif
SkTArray<SkString> failures;
reporter.getFailures(&failures);
report_failures(failures);

View File

@ -34,6 +34,7 @@ protected:
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(1500);
SkRect r;

View File

@ -26,8 +26,8 @@ public:
paint.setAntiAlias(true);
paint.setShader(s)->unref();
SkTypeface* orig = SkTypeface::CreateFromName("Times",
SkTypeface::kBold);
SkTypeface* orig = sk_tool_utils::create_portable_typeface("Times",
SkTypeface::kBold);
if (NULL == orig) {
orig = SkTypeface::RefDefault();
}

View File

@ -150,6 +150,7 @@ protected:
SkPaint txtPaint;
txtPaint.setTextSize(23.f);
txtPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&txtPaint);
txtPaint.setColor(SK_ColorDKGRAY);
SkScalar textW = txtPaint.measureText(kTxt, SK_ARRAY_COUNT(kTxt)-1);

View File

@ -280,6 +280,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
@ -324,6 +325,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,

View File

@ -55,7 +55,7 @@ protected:
//With freetype the default (normal hinting) can be really ugly.
//Most distros now set slight (vertical hinting only) in any event.
paint.setHinting(SkPaint::kSlight_Hinting);
SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal)));
sk_tool_utils::set_portable_typeface(&paint, "Times Roman", SkTypeface::kNormal);
const char* text = "Hamburgefons ooo mmm";
const size_t textLen = strlen(text);

View File

@ -15,7 +15,7 @@
#include "SkPaint.h"
static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
sk_tool_utils::set_portable_typeface(paint, name, style);
}
class DownsampleBitmapGM : public skiagm::GM {

View File

@ -111,6 +111,7 @@ protected:
blackPaint.setColor(SK_ColorBLACK);
blackPaint.setTextSize(titleHeight);
blackPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&blackPaint);
SkString title;
title.printf("Bitmap size: %d x %d", kBmpSize, kBmpSize);
canvas->drawText(title.c_str(), title.size(), 0,

View File

@ -40,6 +40,7 @@ protected:
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(72));
paint.setLooper(fLooper);

View File

@ -39,6 +39,7 @@ static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
paint.setImageFilter(imf);
paint.setColor(SK_ColorGREEN);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(r.height()/2);
paint.setTextAlign(SkPaint::kCenter_Align);
canvas->save();

View File

@ -63,6 +63,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Empty Paths Drawn Into Rectangle Clips With "
@ -105,6 +106,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(12 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,

View File

@ -14,7 +14,7 @@
#include "SkTypeface.h"
static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
sk_tool_utils::set_portable_typeface(paint, name, style);
}
static SkSize computeSize(const SkBitmap& bm, const SkMatrix& mat) {

View File

@ -59,8 +59,8 @@ protected:
int typefaceCount = 0;
for (size_t i = 0; i < SK_ARRAY_COUNT(gFamilyNames); ++i) {
for (size_t j = 0; j < SK_ARRAY_COUNT(gStyles); ++j) {
fTypefaces[typefaceCount++] = SkTypeface::CreateFromName(gFamilyNames[i],
gStyles[j]);
fTypefaces[typefaceCount++] = sk_tool_utils::create_portable_typeface(gFamilyNames[i],
gStyles[j]);
}
}
}

View File

@ -47,7 +47,7 @@ protected:
//With freetype the default (normal hinting) can be really ugly.
//Most distros now set slight (vertical hinting only) in any event.
paint.setHinting(SkPaint::kSlight_Hinting);
SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal)));
sk_tool_utils::set_portable_typeface(&paint, "Times Roman", SkTypeface::kNormal);
const char* text = "Hamburgefons ooo mmm";
const size_t textLen = strlen(text);

View File

@ -26,7 +26,7 @@ static SkShader* make_heatGradient(const SkPoint pts[2]) {
}
static bool setFont(SkPaint* paint, const char name[]) {
SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
SkTypeface* tf = sk_tool_utils::create_portable_typeface(name, SkTypeface::kNormal);
if (tf) {
paint->setTypeface(tf)->unref();
return true;

View File

@ -42,6 +42,7 @@ protected:
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(48));
canvas->translate(SkIntToScalar(10), SkIntToScalar(64));

View File

@ -52,7 +52,7 @@ protected:
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
if (!fProp) {
fProp.reset(SkTypeface::CreateFromName("Helvetica", SkTypeface::kNormal));
fProp.reset(sk_tool_utils::create_portable_typeface("Helvetica", SkTypeface::kNormal));
}
// There's a black pixel at 40, 40 for reference.

View File

@ -47,6 +47,7 @@ protected:
virtual SkISize onISize() { return SkISize::Make(500, 480); }
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
sk_tool_utils::set_portable_typeface(&paint);
SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
canvas->clipRect(r);
@ -75,6 +76,7 @@ protected:
virtual SkISize onISize() { return SkISize::Make(500, 480); }
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
sk_tool_utils::set_portable_typeface(&paint);
paint.setStyle(SkPaint::kFill_Style);
canvas->drawText("Normal Fill Text", 16, 0, 50, paint);
@ -127,6 +129,7 @@ protected:
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(26));
const SkISize& size = this->getISize();

View File

@ -158,6 +158,7 @@ protected:
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
textPaint.setTextSize(8);
canvas->drawText(kLabel1, strlen(kLabel1), 10, 60, textPaint);

View File

@ -44,6 +44,7 @@ protected:
SkRandom rand;
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
for (int i = 0; i < 25; ++i) {
int x = rand.nextULessThan(WIDTH);
int y = rand.nextULessThan(HEIGHT);

View File

@ -50,6 +50,7 @@ protected:
};
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
textPaint.setTextSize(SkIntToScalar(100));
int posY = 0;
for (unsigned i = 0; i < SK_ARRAY_COUNT(str); i++) {

View File

@ -113,6 +113,7 @@ static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
paint.setImageFilter(imf);
paint.setColor(SK_ColorCYAN);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(r.height()/2);
paint.setTextAlign(SkPaint::kCenter_Align);
canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint);

View File

@ -45,6 +45,7 @@ static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) {
paint.setImageFilter(imf);
paint.setColor(SK_ColorGREEN);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(r.height()/2);
paint.setTextAlign(SkPaint::kCenter_Align);
canvas->save();

View File

@ -99,6 +99,7 @@ protected:
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xFFFFFFFF);
paint.setTextSize(SkIntToScalar(96));
const char* str = "e";

View File

@ -44,6 +44,7 @@ protected:
100))->unref();
canvas->saveLayer(NULL, &paint);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
const char* str = "The quick brown fox jumped over the lazy dog.";
SkRandom rand;
for (int i = 0; i < 25; ++i) {

View File

@ -57,6 +57,7 @@ protected:
};
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
textPaint.setTextSize(SkIntToScalar(100));
int posY = 0;
for (unsigned i = 0; i < SK_ARRAY_COUNT(str); i++) {

View File

@ -61,6 +61,7 @@ private:
canvas->drawRect(rect, paint);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(25));
paint.setColor(SK_ColorBLACK);
canvas->drawText(text, strlen(text), x, y, paint);

View File

@ -49,6 +49,7 @@ protected:
paint.setColor(SK_ColorBLACK);
paint.setDither(true);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setSubpixelText(subpixelTextEnabled);
paint.setLCDRenderText(lcdRenderTextEnabled);
paint.setTextSize(textHeight);

View File

@ -34,6 +34,7 @@ protected:
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xFFFFFFFF);
paint.setTextSize(SkIntToScalar(96));
const char* str = "e";

View File

@ -85,6 +85,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Line Drawn Into Rectangle Clips With "
@ -129,6 +130,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,
@ -227,6 +229,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Line Closed Drawn Into Rectangle Clips With "
@ -271,6 +274,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,

View File

@ -18,6 +18,7 @@ static SkColor kColor2 = SkColorSetARGB(0xff, 0x80, 0xff, 0);
static void draw_label(SkCanvas* canvas, const char* label,
const SkPoint& offset) {
SkPaint paint;
sk_tool_utils::set_portable_typeface(&paint);
size_t len = strlen(label);
SkScalar width = paint.measureText(label, len);

View File

@ -33,6 +33,7 @@ protected:
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xFFFFFFFF);
paint.setTextSize(SkIntToScalar(180));
SkPoint pts[2] = { SkPoint::Make(0, 0),

View File

@ -31,6 +31,7 @@ protected:
canvas.clear(0x0);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
const char* str1 = "ABC";
const char* str2 = "XYZ";
paint.setColor(0xFFFFFFFF);

View File

@ -32,6 +32,7 @@ protected:
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xD000D000);
paint.setTextSize(SkIntToScalar(96));
const char* str = "e";

View File

@ -52,8 +52,7 @@ static void test_rev(SkCanvas* canvas) {
SkPaint paint;
paint.setTextSize(SkIntToScalar(100));
SkTypeface* hira = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
SkSafeUnref(paint.setTypeface(hira));
sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
path.reset();
paint.getTextPath("e", 1, 50, 50, &path);
canvas->translate(0, 100);
@ -103,8 +102,7 @@ protected:
SkPaint paint;
paint.setTextSize(SkIntToScalar(100));
SkTypeface* hira = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
SkSafeUnref(paint.setTypeface(hira));
sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
path.reset();
paint.getTextPath("e", 1, 50, 50, &path);
canvas->translate(0, 100);

View File

@ -28,6 +28,7 @@ protected:
canvas->clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xFFFFFFFF);
paint.setTextSize(SkIntToScalar(96));
const char* str = "e";

View File

@ -37,6 +37,7 @@ private:
SkJSCanvas::SkJSCanvas(SkCanvas* target) : fTarget(target) {
fFillPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&fFillPaint);
fStrokePaint.setAntiAlias(true);
fStrokePaint.setStyle(SkPaint::kStroke_Style);
fStrokePaint.setStrokeWidth(SK_Scalar1);
@ -229,6 +230,7 @@ protected:
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setStrokeWidth(SkIntToScalar(4));
paint.setTextSize(SkIntToScalar(40));
paint.setTextAlign(SkPaint::kCenter_Align);

View File

@ -86,6 +86,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Quad Drawn Into Rectangle Clips With "
@ -130,6 +131,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,
@ -233,6 +235,7 @@ protected:
SkPaint titlePaint;
titlePaint.setColor(SK_ColorBLACK);
titlePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&titlePaint);
titlePaint.setLCDRenderText(true);
titlePaint.setTextSize(15 * SK_Scalar1);
const char title[] = "Quad Closed Drawn Into Rectangle Clips With "
@ -277,6 +280,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(color);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setLCDRenderText(true);
labelPaint.setTextSize(10 * SK_Scalar1);
canvas->drawText(gStyles[style].fName,

View File

@ -97,6 +97,7 @@ protected:
// stipple mask with a round rect soft clip
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(72);
paint.setShader(fShader.get());
paint.setMaskFilter(fMaskFilter.get());
@ -123,6 +124,7 @@ protected:
SkPaint paint2;
paint2.setColor(SK_ColorBLACK);
paint2.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint2);
paint2.setTextSize(72);
paint2.setStyle(SkPaint::kStroke_Style);
paint2.setStrokeWidth(1);

View File

@ -155,6 +155,7 @@ protected:
SkPaint paint;
paint.setDither(true);
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(pointSize));
canvas->save();

View File

@ -90,11 +90,13 @@ protected:
SkPaint fillPaint;
fillPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&fillPaint);
fillPaint.setTextSize(SkIntToScalar(kPointSize));
fillPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
SkPaint outlinePaint;
outlinePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&outlinePaint);
outlinePaint.setTextSize(SkIntToScalar(kPointSize));
outlinePaint.setStyle(SkPaint::kStroke_Style);
outlinePaint.setStrokeWidth(0.f);
@ -110,6 +112,7 @@ protected:
SkPaint labelPaint;
labelPaint.setColor(0xff000000);
labelPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelPaint);
labelPaint.setTextSize(12.f);
canvas->translate(15.f, 15.f);

View File

@ -76,6 +76,7 @@ protected:
SkPaint outlinePaint;
outlinePaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&outlinePaint);
outlinePaint.setTextSize(SkIntToScalar(kPointSize));
outlinePaint.setStyle(SkPaint::kStroke_Style);
outlinePaint.setStrokeWidth(0.f);
@ -109,6 +110,7 @@ protected:
SkPaint fillPaint;
fillPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&fillPaint);
fillPaint.setTextSize(SkIntToScalar(kPointSize));
fillPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
fillPaint.setShader(shader);

View File

@ -154,6 +154,7 @@ protected:
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
textPaint.setTextSize(SK_Scalar1*24);
int xOff = 0;

View File

@ -80,6 +80,7 @@ protected:
canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
SkPaint paint;
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0x80FF0000);
const Proc procs[] = {

View File

@ -48,12 +48,10 @@ protected:
paint.setTextSize(SkIntToScalar(100));
paint.setStrokeWidth(SkIntToScalar(5));
SkTypeface* face = SkTypeface::CreateFromName("Papyrus", SkTypeface::kNormal);
SkSafeUnref(paint.setTypeface(face));
sk_tool_utils::set_portable_typeface(&paint, "Papyrus");
show_bold(canvas, "Hello", 5, x, y, paint);
face = SkTypeface::CreateFromName("Hiragino Maru Gothic Pro", SkTypeface::kNormal);
SkSafeUnref(paint.setTypeface(face));
sk_tool_utils::set_portable_typeface(&paint, "Hiragino Maru Gothic Pro");
const unsigned char hyphen[] = { 0xE3, 0x83, 0xBC };
show_bold(canvas, hyphen, SK_ARRAY_COUNT(hyphen), x + SkIntToScalar(300), y, paint);

View File

@ -87,6 +87,7 @@ protected:
if (true) { test_nulldev(canvas); }
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(kBelowThreshold_TextSize);
draw_text_set(canvas, paint);

View File

@ -188,6 +188,7 @@ protected:
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setTextSize(SkIntToScalar(56));
SkScalar x = SkIntToScalar(20);

View File

@ -34,6 +34,7 @@ protected:
canvas.clear(0xFF000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xD000D000);
paint.setTextSize(SkIntToScalar(50));
const char* str = "e";

View File

@ -100,6 +100,7 @@ protected:
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
p.setDither(true);
str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
@ -139,6 +140,7 @@ protected:
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
canvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
}
@ -221,6 +223,7 @@ protected:
SkPaint p;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
p.setTextAlign(SkPaint::kCenter_Align);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {

View File

@ -110,6 +110,7 @@ protected:
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
p.setDither(true);
p.setLooper(fLooper);
str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
@ -151,6 +152,7 @@ protected:
SkPaint p;
SkString str;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
p.setLooper(fLooper);
str.printf("%s, %s", gColorTypeNames[i], gFilterNames[j]);
canvas->drawText(str.c_str(), str.size(), scale*x, scale*(y + r.height() * 2 / 3), p);
@ -234,6 +236,7 @@ protected:
SkPaint p;
p.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&p);
p.setTextAlign(SkPaint::kCenter_Align);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {

View File

@ -30,6 +30,7 @@ static void drawGrad(SkCanvas* canvas, const SkScalar d0[], const SkScalar d1[])
SkColor colors[] = { SK_ColorGREEN, SK_ColorRED };
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
SkString str;
str.printf("%g,%g,%g %g,%g,%g",

View File

@ -24,7 +24,7 @@ public:
TypefaceGM() {
fFaces = new SkTypeface*[SK_ARRAY_COUNT(gFaces)];
for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) {
fFaces[i] = SkTypeface::CreateFromName(gFaces[i], SkTypeface::kNormal);
fFaces[i] = sk_tool_utils::create_portable_typeface(gFaces[i], SkTypeface::kNormal);
}
}
@ -159,8 +159,8 @@ class TypefaceStylesGM : public skiagm::GM {
public:
TypefaceStylesGM(bool applyKerning) : fApplyKerning(applyKerning) {
for (int i = 0; i < gFaceStylesCount; i++) {
fFaces[i] = SkTypeface::CreateFromName(gFaceStyles[i].fName,
gFaceStyles[i].fStyle);
fFaces[i] = sk_tool_utils::create_portable_typeface(gFaceStyles[i].fName,
gFaceStyles[i].fStyle);
}
}

View File

@ -59,10 +59,10 @@ protected:
SkScalar h = SkIntToScalar(size.fHeight);
SK_COMPILE_ASSERT(4 == SK_ARRAY_COUNT(fTypefacesToUnref), typeface_cnt);
fTypefacesToUnref[0] = SkTypeface::CreateFromName("sans-serif", SkTypeface::kNormal);
fTypefacesToUnref[1] = SkTypeface::CreateFromName("sans-serif", SkTypeface::kBold);
fTypefacesToUnref[2] = SkTypeface::CreateFromName("serif", SkTypeface::kNormal);
fTypefacesToUnref[3] = SkTypeface::CreateFromName("serif", SkTypeface::kBold);
fTypefacesToUnref[0] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kNormal);
fTypefacesToUnref[1] = sk_tool_utils::create_portable_typeface("sans-serif", SkTypeface::kBold);
fTypefacesToUnref[2] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kNormal);
fTypefacesToUnref[3] = sk_tool_utils::create_portable_typeface("serif", SkTypeface::kBold);
SkRandom random;
for (int i = 0; i < kCnt; ++i) {

View File

@ -21,8 +21,8 @@ public:
VertText2GM() {
const int pointSize = 24;
textHeight = SkIntToScalar(pointSize);
fProp = SkTypeface::CreateFromName("Helvetica", SkTypeface::kNormal);
fMono = SkTypeface::CreateFromName("Courier New", SkTypeface::kNormal);
fProp = sk_tool_utils::create_portable_typeface("Helvetica", SkTypeface::kNormal);
fMono = sk_tool_utils::create_portable_typeface("Courier New", SkTypeface::kNormal);
}
virtual ~VertText2GM() {

View File

@ -34,6 +34,7 @@ protected:
canvas.clear(0x00000000);
SkPaint paint;
paint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&paint);
paint.setColor(0xD000D000);
paint.setTextSize(SkIntToScalar(96));
const char* str = "e";

View File

@ -225,6 +225,7 @@ protected:
SkPaint labelP;
labelP.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelP);
labelP.setTextAlign(SkPaint::kCenter_Align);
const int W = 5;

View File

@ -34,6 +34,7 @@ protected:
SkPaint labelP;
labelP.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelP);
labelP.setTextAlign(SkPaint::kCenter_Align);
const int W = 6;

View File

@ -46,6 +46,7 @@ protected:
SkPaint labelP;
labelP.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelP);
static const SkColor kSolidColors[] = {
SK_ColorTRANSPARENT,

View File

@ -17,7 +17,6 @@
'bench_pictures',
'bench_record',
'bench_playback',
'create_test_font',
'dump_record',
'filter',
'gpuveto',
@ -95,7 +94,11 @@
'../tools/sk_tool_utils.cpp',
'../tools/sk_tool_utils_font.cpp',
],
'include_dirs': [
'../src/fonts',
],
'dependencies': [
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
],
'direct_dependent_settings': {
@ -630,20 +633,6 @@
'tools.gyp:picture_utils',
],
},
{
'target_name': 'create_test_font',
'type': 'executable',
'sources': [
'../tools/create_test_font.cpp',
],
'include_dirs': [
'../src/core',
],
'dependencies': [
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
],
},
{
'target_name': 'test_image_decoder',
'type': 'executable',
@ -723,5 +712,26 @@
],
},
],
['skia_os == "mac"',
{
'targets': [
{
'target_name': 'create_test_font',
'type': 'executable',
'sources': [
'../tools/create_test_font.cpp',
],
'include_dirs': [
'../src/core',
],
'dependencies': [
'flags.gyp:flags',
'skia_lib.gyp:skia_lib',
'resources',
],
},
],
},
],
],
}

View File

@ -1661,9 +1661,7 @@ static void cleanup_for_filename(SkString* name) {
}
#endif
namespace sk_tool_utils {
extern bool gEnablePortableTypeface;
};
DECLARE_bool(portableFonts);
bool SampleWindow::onHandleChar(SkUnichar uni) {
{
@ -1719,7 +1717,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
toggleFPS();
break;
case 'F':
sk_tool_utils::gEnablePortableTypeface ^= true;
FLAGS_portableFonts ^= true;
this->inval(NULL);
break;
case 'g':

View File

@ -8,6 +8,7 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDescriptor.h"
#include "SkFontDescriptor.h"
#include "SkGlyph.h"
#include "SkMask.h"
// #include "SkOTUtils.h"
@ -15,126 +16,171 @@
#include "SkTestScalerContext.h"
#include "SkTypefaceCache.h"
class SkTestTypeface : public SkTypeface {
public:
SkTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& , SkTDArray<SkFixed>& ),
SkTypeface::Style style)
: SkTypeface(style, SkTypefaceCache::NewFontID(), false) {
fMetrics = (*funct)(fPaths, fWidths);
SkTestFont::SkTestFont(const SkTestFontData& fontData)
: INHERITED()
, fCharCodes(fontData.fCharCodes)
, fCharCodesCount(fontData.fCharCodesCount)
, fWidths(fontData.fWidths)
, fMetrics(fontData.fMetrics)
, fName(fontData.fName)
, fPaths(NULL)
{
init(fontData.fPoints, fontData.fVerbs);
#ifdef SK_DEBUG
sk_bzero(fDebugBits, sizeof(fDebugBits));
sk_bzero(fDebugOverage, sizeof(fDebugOverage));
#endif
}
SkTestFont::~SkTestFont() {
for (unsigned index = 0; index < fCharCodesCount; ++index) {
SkDELETE(fPaths[index]);
}
SkDELETE_ARRAY(fPaths);
}
virtual ~SkTestTypeface() {
fPaths.deleteAll();
}
#ifdef SK_DEBUG
void getAdvance(SkGlyph* glyph) {
glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)];
glyph->fAdvanceY = 0;
}
#include "SkThread.h"
SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);
void getFontMetrics(SkPaint::FontMetrics* metrics) {
*metrics = fMetrics;
}
#endif
void getMetrics(SkGlyph* glyph) {
glyph->fAdvanceX = fWidths[SkGlyph::ID2Code(glyph->fID)];
glyph->fAdvanceY = 0;
}
void getPath(const SkGlyph& glyph, SkPath* path) {
*path = *fPaths[SkGlyph::ID2Code(glyph.fID)];
}
protected:
virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE;
virtual void onFilterRec(SkScalerContextRec* rec) const SK_OVERRIDE {
rec->setHinting(SkPaint::kNo_Hinting);
rec->fMaskFormat = SkMask::kA8_Format;
}
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo ,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const SK_OVERRIDE {
// pdf only
SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
info->fEmSize = 0;
info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
info->fStyle = 0;
info->fFontName.set("SkiaTest");
info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
info->fItalicAngle = 0;
info->fAscent = 0;
info->fDescent = 0;
info->fStemV = 0;
info->fCapHeight = 0;
info->fBBox = SkIRect::MakeEmpty();
return info;
}
virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
SkASSERT(0); // don't expect to get here
return NULL;
}
virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE {
SkASSERT(0); // don't expect to get here
}
virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
uint16_t glyphs[], int glyphCount) const SK_OVERRIDE {
SkASSERT(encoding == kUTF8_Encoding);
for (int index = 0; index < glyphCount; ++index) {
int ch = ((unsigned char*) chars)[index];
SkASSERT(ch < 0x7F);
if (ch < 0x20) {
glyphs[index] = 0;
} else {
glyphs[index] = ch - 0x20;
int SkTestFont::codeToIndex(SkUnichar charCode) const {
#ifdef SK_DEBUG // detect missing test font data
{
SkAutoMutexAcquire ac(gUsedCharsMutex);
if (charCode >= ' ' && charCode <= '~') {
int bitOffset = charCode - ' ';
fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
} else {
int index = 0;
while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
&& index < (int) sizeof(fDebugOverage)) {
++index;
}
SkASSERT(index < (int) sizeof(fDebugOverage));
if (fDebugOverage[index] == 0) {
fDebugOverage[index] = charCode;
}
}
return glyphCount;
}
virtual int onCountGlyphs() const SK_OVERRIDE {
return fPaths.count();
#endif
for (unsigned index = 0; index < fCharCodesCount; ++index) {
if (fCharCodes[index] == (unsigned) charCode) {
return (int) index;
}
}
SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
fDebugName, fDebugStyle));
return 0;
}
virtual int onGetUPEM() const SK_OVERRIDE {
SkASSERT(0); // don't expect to get here
return 1;
void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
for (unsigned index = 0; index < fCharCodesCount; ++index) {
SkPath* path = SkNEW(SkPath);
SkPath::Verb verb;
while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kMove_Verb:
path->moveTo(pts[0], pts[1]);
pts += 2;
break;
case SkPath::kLine_Verb:
path->lineTo(pts[0], pts[1]);
pts += 2;
break;
case SkPath::kQuad_Verb:
path->quadTo(pts[0], pts[1], pts[2], pts[3]);
pts += 4;
break;
case SkPath::kCubic_Verb:
path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
pts += 6;
break;
case SkPath::kClose_Verb:
path->close();
break;
default:
SkDEBUGFAIL("bad verb");
return;
}
}
fPaths[index] = path;
}
}
SkTestTypeface::SkTestTypeface(SkTestFont* testFont, SkTypeface::Style style)
: SkTypeface(style, SkTypefaceCache::NewFontID(), false)
, fTestFont(testFont) {
}
virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE {
SkString familyName("SkiaTest");
SkString language("und"); //undetermined
SkASSERT(0); // incomplete
return NULL;
// return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
void SkTestTypeface::getAdvance(SkGlyph* glyph) {
glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
glyph->fAdvanceY = 0;
}
void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
*metrics = fTestFont->fMetrics;
}
void SkTestTypeface::getMetrics(SkGlyph* glyph) {
glyph->fAdvanceX = fTestFont->fWidths[SkGlyph::ID2Code(glyph->fID)];
glyph->fAdvanceY = 0;
}
void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
*path = *fTestFont->fPaths[SkGlyph::ID2Code(glyph.fID)];
}
void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
rec->setHinting(SkPaint::kNo_Hinting);
rec->fMaskFormat = SkMask::kA8_Format;
}
SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo ,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const {
// pdf only
SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
info->fEmSize = 0;
info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
info->fStyle = 0;
info->fFontName.set(fTestFont->fName);
info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
info->fItalicAngle = 0;
info->fAscent = 0;
info->fDescent = 0;
info->fStemV = 0;
info->fCapHeight = 0;
info->fBBox = SkIRect::MakeEmpty();
return info;
}
void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
desc->setFamilyName(fTestFont->fName);
desc->setFontFileName(fTestFont->fName);
*isLocal = false;
}
int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
uint16_t glyphs[], int glyphCount) const {
SkASSERT(encoding == kUTF16_Encoding);
for (int index = 0; index < glyphCount; ++index) {
SkUnichar ch = ((SkUnichar*) chars)[index];
glyphs[index] = fTestFont->codeToIndex(ch);
}
return glyphCount;
}
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE {
return 0;
}
virtual size_t onGetTableData(SkFontTableTag tag, size_t offset,
size_t length, void* data) const SK_OVERRIDE {
return 0;
}
private:
SkTDArray<SkPath* > fPaths;
SkTDArray<SkFixed> fWidths;
SkPaint::FontMetrics fMetrics;
friend class SkTestScalerContext;
};
SkTypeface* CreateTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& pathArray,
SkTDArray<SkFixed>& widthArray),
SkTypeface::Style style) {
SkTypeface* test = SkNEW_ARGS(SkTestTypeface, (funct, style));
return test;
SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
SkString familyName(fTestFont->fName);
SkString language("und"); //undetermined
SkASSERT(0); // incomplete
return NULL;
// return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
}
class SkTestScalerContext : public SkScalerContext {
@ -156,10 +202,8 @@ protected:
}
virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
uint8_t ch = (uint8_t) uni;
SkASSERT(ch < 0x7f);
uint16_t glyph;
(void) fFace->onCharsToGlyphs((const void *) &ch, SkTypeface::kUTF8_Encoding, &glyph, 1);
(void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
return glyph;
}

View File

@ -10,11 +10,103 @@
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"
#include "SkTypeface.h"
SkTypeface* CreateTestTypeface(SkPaint::FontMetrics (*funct)(SkTDArray<SkPath*>& pathArray,
SkTDArray<SkFixed>& widthArray),
SkTypeface::Style style);
class SkTestFont;
struct SkTestFontData {
const SkScalar* fPoints;
const unsigned char* fVerbs;
const unsigned* fCharCodes;
const size_t fCharCodesCount;
const SkFixed* fWidths;
const SkPaint::FontMetrics& fMetrics;
const char* fName;
SkTypeface::Style fStyle;
SkTestFont* fFontCache;
};
class SkTestFont : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkTestFont)
SkTestFont(const SkTestFontData& );
virtual ~SkTestFont();
int codeToIndex(SkUnichar charCode) const;
void init(const SkScalar* pts, const unsigned char* verbs);
#ifdef SK_DEBUG // detect missing test font data
mutable unsigned char fDebugBits[16];
mutable SkUnichar fDebugOverage[8];
const char* fDebugName;
SkTypeface::Style fDebugStyle;
const char* debugFontName() const { return fName; }
#endif
private:
const unsigned* fCharCodes;
const size_t fCharCodesCount;
const SkFixed* fWidths;
const SkPaint::FontMetrics& fMetrics;
const char* fName;
SkPath** fPaths;
friend class SkTestTypeface;
typedef SkRefCnt INHERITED;
};
class SkTestTypeface : public SkTypeface {
public:
SkTestTypeface(SkTestFont* , SkTypeface::Style style);
virtual ~SkTestTypeface() {
SkSafeUnref(fTestFont);
}
void getAdvance(SkGlyph* glyph);
void getFontMetrics(SkPaint::FontMetrics* metrics);
void getMetrics(SkGlyph* glyph);
void getPath(const SkGlyph& glyph, SkPath* path);
protected:
virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE;
virtual void onFilterRec(SkScalerContextRec* rec) const SK_OVERRIDE;
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::PerGlyphInfo ,
const uint32_t* glyphIDs,
uint32_t glyphIDsCount) const SK_OVERRIDE;
virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
SkASSERT(0); // don't expect to get here
return NULL;
}
virtual void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const SK_OVERRIDE;
virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
virtual int onCountGlyphs() const SK_OVERRIDE {
return (int) fTestFont->fCharCodesCount;
}
virtual int onGetUPEM() const SK_OVERRIDE {
SkASSERT(0); // don't expect to get here
return 1;
}
virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE {
return 0;
}
virtual size_t onGetTableData(SkFontTableTag tag, size_t offset,
size_t length, void* data) const SK_OVERRIDE {
return 0;
}
private:
SkTestFont* fTestFont;
friend class SkTestScalerContext;
};
SkTypeface* CreateTestTypeface(const char* name, SkTypeface::Style style);
#endif

View File

@ -5,28 +5,156 @@
* found in the LICENSE file.
*/
// running create_test_font generates ./tools/test_font_data.cpp
// which is read by ./tools/sk_tool_utils_font.cpp
#include "Resources.h"
#include "SkOSFile.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkStream.h"
#include "SkTArray.h"
#include "SkTSort.h"
#include "SkTypeface.h"
#include "SkUtils.h"
#include <stdio.h>
enum {
kEmSize = 4096
// the folllowing include is generated by running dm with
// --portableFonts --reportUsedChars
#include "test_font_data_chars.cpp"
#define DEFAULT_FONT_NAME "Liberation Sans"
static struct FontDesc {
const char* fName;
SkTypeface::Style fStyle;
const char* fFont;
const char* fFile;
const char* fCharsUsed;
int fFontIndex;
} gFonts[] = {
{"Courier New", SkTypeface::kNormal, "Courier New", "Courier New.ttf",
gCourierNew},
{"Courier New", SkTypeface::kBold, "Courier New", "Courier New Bold.ttf",
gCourierNew_Bold},
{"Courier New", SkTypeface::kItalic, "Courier New", "Courier New Italic.ttf",
gCourierNew_Italic},
{"Courier New", SkTypeface::kBoldItalic, "Courier New", "Courier New Bold Italic.ttf",
gCourierNew_BoldItalic},
{"Helvetica", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
gLiberationSans},
{"Helvetica", SkTypeface::kBold, "Liberation Sans", "LiberationSans-Bold.ttf",
gLiberationSans_Bold},
{"Helvetica", SkTypeface::kItalic, "Liberation Sans", "LiberationSans-Italic.ttf",
gLiberationSans_Italic},
{"Helvetica", SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
gLiberationSans_BoldItalic},
{"Hiragino Maru Gothic Pro", SkTypeface::kNormal, "Hiragino Maru Gothic Pro", "Pro W4.otf",
gHiraginoMaruGothicPro},
{"Liberation Sans", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
gLiberationSans},
{"Liberation Sans", SkTypeface::kBold, "Liberation Sans", "LiberationSans-Bold.ttf",
gLiberationSans_Bold},
{"Liberation Sans", SkTypeface::kItalic, "Liberation Sans", "LiberationSans-Italic.ttf",
gLiberationSans_Italic},
{"Liberation Sans", SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
gLiberationSans_BoldItalic},
{"monospace", SkTypeface::kNormal, "Courier New", "Courier New.ttf",
gCourierNew},
{"monospace", SkTypeface::kBold, "Courier New", "Courier New Bold.ttf",
gCourierNew_Bold},
{"monospace", SkTypeface::kItalic, "Courier New", "Courier New Italic.ttf",
gCourierNew_Italic},
{"monospace", SkTypeface::kBoldItalic, "Courier New", "Courier New Bold Italic.ttf",
gCourierNew_BoldItalic},
{"Papyrus", SkTypeface::kNormal, "Papyrus", "Papyrus.ttc",
gPapyrus},
{"sans-serif", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
gLiberationSans},
{"sans-serif", SkTypeface::kBold, "Liberation Sans", "LiberationSans-Bold.ttf",
gLiberationSans_Bold},
{"sans-serif", SkTypeface::kItalic, "Liberation Sans", "LiberationSans-Italic.ttf",
gLiberationSans_Italic},
{"sans-serif", SkTypeface::kBoldItalic, "Liberation Sans", "LiberationSans-BoldItalic.ttf",
gLiberationSans_BoldItalic},
{"serif", SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
gTimesNewRoman},
{"serif", SkTypeface::kBold, "Times New Roman", "Times New Roman Bold.ttf",
gTimesNewRoman_Bold},
{"serif", SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
gTimesNewRoman_Italic},
{"serif", SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
gTimesNewRoman_BoldItalic},
{"Times", SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
gTimesNewRoman},
{"Times", SkTypeface::kBold, "Times New Roman", "Times New Roman Bold.ttf",
gTimesNewRoman_Bold},
{"Times", SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
gTimesNewRoman_Italic},
{"Times", SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
gTimesNewRoman_BoldItalic},
{"Times New Roman", SkTypeface::kNormal, "Times New Roman", "Times New Roman.ttf",
gTimesNewRoman},
{"Times New Roman", SkTypeface::kBold, "Times New Roman", "Times New Roman Bold.ttf",
gTimesNewRoman_Bold},
{"Times New Roman", SkTypeface::kItalic, "Times New Roman", "Times New Roman Italic.ttf",
gTimesNewRoman_Italic},
{"Times New Roman", SkTypeface::kBoldItalic, "Times New Roman", "Times New Roman Bold Italic.ttf",
gTimesNewRoman_BoldItalic},
{"Times Roman", SkTypeface::kNormal, "Liberation Sans", "LiberationSans-Regular.ttf",
gLiberationSans},
};
static void output_fixed(FILE* out, SkScalar num) {
SkASSERT(floor(num) == num);
int hex = (int) num * (65536 / kEmSize);
fprintf(out, "0x%08x", hex);
const int gFontsCount = (int) SK_ARRAY_COUNT(gFonts);
const char* gStyleName[] = {
"kNormal",
"kBold",
"kItalic",
"kBoldItalic",
};
const char gHeader[] =
"/*\n"
" * Copyright 2014 Google Inc.\n"
" *\n"
" * Use of this source code is governed by a BSD-style license that can be\n"
" * found in the LICENSE file.\n"
" */\n"
"\n"
"// Auto-generated by ";
static FILE* font_header() {
SkString outPath(SkOSPath::SkPathJoin(".", "tools"));
outPath = SkOSPath::SkPathJoin(outPath.c_str(), "test_font_data.cpp");
FILE* out = fopen(outPath.c_str(), "w");
fprintf(out, "%s%s\n\n", gHeader, SkOSPath::SkBasename(__FILE__).c_str());
return out;
}
static void output_scalar(FILE* out, SkScalar num) {
num /= kEmSize;
enum {
kMaxLineLength = 80,
};
static ptrdiff_t last_line_length(const SkString& str) {
const char* first = str.c_str();
const char* last = first + str.size();
const char* ptr = last;
while (ptr > first && *--ptr != '\n')
;
return last - ptr - 1;
}
static void output_fixed(SkScalar num, int emSize, SkString* out) {
int hex = (int) (num * 65536 / emSize);
out->appendf("0x%08x,", hex);
*out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
}
static void output_scalar(SkScalar num, int emSize, SkString* out) {
num /= emSize;
if (num == (int) num) {
fprintf(out, "%d", (int) num);
out->appendS32((int) num);
} else {
SkString str;
str.printf("%1.6g", num);
@ -35,135 +163,288 @@ static void output_scalar(FILE* out, SkScalar num) {
while (cStr[width - 1] == '0') {
--width;
}
str.resize(width);
fprintf(out, "%sf", str.c_str());
str.remove(width, str.size() - width);
out->appendf("%sf", str.c_str());
}
*out += ',';
*out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
}
static int output_points(const SkPoint* pts, int emSize, int count, SkString* ptsOut) {
for (int index = 0; index < count; ++index) {
// SkASSERT(floor(pts[index].fX) == pts[index].fX);
output_scalar(pts[index].fX, emSize, ptsOut);
// SkASSERT(floor(pts[index].fY) == pts[index].fY);
output_scalar(pts[index].fY, emSize, ptsOut);
}
return count;
}
static void output_path_data(const SkPaint& paint, const char* used,
int emSize, SkString* ptsOut, SkTDArray<SkPath::Verb>* verbs,
SkTDArray<unsigned>* charCodes, SkTDArray<SkScalar>* widths) {
while (*used) {
SkUnichar index = SkUTF8_NextUnichar(&used);
SkPath path;
paint.getTextPath((const void*) &index, 2, 0, 0, &path);
SkPath::RawIter iter(path);
SkPath::Verb verb;
SkPoint pts[4];
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
*verbs->append() = verb;
switch (verb) {
case SkPath::kMove_Verb:
output_points(&pts[0], emSize, 1, ptsOut);
break;
case SkPath::kLine_Verb:
output_points(&pts[1], emSize, 1, ptsOut);
break;
case SkPath::kQuad_Verb:
output_points(&pts[1], emSize, 2, ptsOut);
break;
case SkPath::kCubic_Verb:
output_points(&pts[1], emSize, 3, ptsOut);
break;
case SkPath::kClose_Verb:
break;
default:
SkDEBUGFAIL("bad verb");
SkASSERT(0);
}
}
*verbs->append() = SkPath::kDone_Verb;
*charCodes->append() = index;
SkScalar width;
SkDEBUGCODE(int charCount =) paint.getTextWidths((const void*) &index, 2, &width);
SkASSERT(charCount == 1);
// SkASSERT(floor(width) == width); // not true for Hiragino Maru Gothic Pro
*widths->append() = width;
}
}
static void output_points(FILE* out, const SkPoint* pts, int count) {
static int offset_str_len(unsigned num) {
if (num == (unsigned) -1) {
return 10;
}
unsigned result = 1;
unsigned ref = 10;
while (ref <= num) {
++result;
ref *= 10;
}
return result;
}
static SkString strip_spaces(const SkString& str) {
SkString result;
int count = (int) str.size();
for (int index = 0; index < count; ++index) {
SkASSERT(floor(pts[index].fX) == pts[index].fX);
output_scalar(out, pts[index].fX);
fprintf(out, ", ");
SkASSERT(floor(pts[index].fY) == pts[index].fY);
output_scalar(out, pts[index].fY);
if (index + 1 < count) {
fprintf(out, ", ");
char c = str[index];
if (c != ' ' && c != '-') {
result += c;
}
}
fprintf(out, ");\n");
return result;
}
const char header[] =
"/*\n"
" * Copyright 2014 Google Inc.\n"
" *\n"
" * Use of this source code is governed by a BSD-style license that can be\n"
" * found in the LICENSE file.\n"
" */\n"
"\n"
"// this was auto-generated by TestFontCreator.cpp\n"
"\n"
"#include \"SkPaint.h\"\n"
"#include \"SkPath.h\"\n"
"#include \"SkTDArray.h\"\n"
"\n"
"namespace sk_tool_utils {\n"
"\n"
"SkPaint::FontMetrics create_font(SkTDArray<SkPath*>& pathArray,\n"
" SkTDArray<SkFixed>& widthArray) {";
static SkString strip_final(const SkString& str) {
SkString result(str);
if (result.endsWith("\n")) {
result.remove(result.size() - 1, 1);
}
if (result.endsWith(" ")) {
result.remove(result.size() - 1, 1);
}
if (result.endsWith(",")) {
result.remove(result.size() - 1, 1);
}
return result;
}
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
static void output_font(SkTypeface* face, const char* name, SkTypeface::Style style,
const char* used, FILE* out) {
int emSize = face->getUnitsPerEm() * 2;
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextAlign(SkPaint::kLeft_Align);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
paint.setTextSize(kEmSize);
SkString filename("resources/DroidSans.ttf");
SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
if (!stream->isValid()) {
SkDebugf("Could not find resources/Roboto-Regular.ttf.\n");
return 1;
}
SkTypeface* typeface = SkTypeface::CreateFromStream(stream);
SkSafeUnref(paint.setTypeface(typeface));
FILE* out = fopen("./out/sk_tool_utils_font.cpp", "w");
fprintf(out, "%s\n", header);
fprintf(out, " SkPath* path;\n");
for (unsigned short index = 0x20; index < 0x7F; ++index) {
SkPath path;
paint.getTextPath((const void*) &index, 2, 0, 0, &path);
SkPath::RawIter iter(path);
uint8_t verb;
SkPoint pts[4];
fprintf(out, " path = SkNEW(SkPath); //");
if (index == '\\') {
fprintf(out, " blackslash\n");
} else if (index == ' ') {
fprintf(out, " space\n");
} else {
fprintf(out, " %c\n", (char) index);
}
fprintf(out, " *pathArray.append() = path;\n");
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kMove_Verb:
fprintf(out, " path->moveTo(");
output_points(out, &pts[0], 1);
continue;
case SkPath::kLine_Verb:
fprintf(out, " path->lineTo(");
output_points(out, &pts[1], 1);
break;
case SkPath::kQuad_Verb:
fprintf(out, " path->quadTo(");
output_points(out, &pts[1], 2);
break;
case SkPath::kCubic_Verb:
fprintf(out, " path->cubicTo(");
output_points(out, &pts[1], 3);
break;
case SkPath::kClose_Verb:
fprintf(out, " path->close();\n");
break;
default:
SkDEBUGFAIL("bad verb");
return 1;
paint.setTextSize(emSize);
SkSafeUnref(paint.setTypeface(face));
SkTDArray<SkPath::Verb> verbs;
SkTDArray<unsigned> charCodes;
SkTDArray<SkScalar> widths;
SkString ptsOut;
output_path_data(paint, used, emSize, &ptsOut, &verbs, &charCodes, &widths);
SkString fontnameStr(name);
SkString strippedStr = strip_spaces(fontnameStr);
strippedStr.appendf("%s", gStyleName[style]);
const char* fontname = strippedStr.c_str();
fprintf(out, "const SkScalar %sPoints[] = {\n", fontname);
ptsOut = strip_final(ptsOut);
fprintf(out, "%s", ptsOut.c_str());
fprintf(out, "\n};\n\n");
fprintf(out, "const unsigned char %sVerbs[] = {\n", fontname);
int verbCount = verbs.count();
int outChCount = 0;
for (int index = 0; index < verbCount;) {
SkPath::Verb verb = verbs[index];
SkASSERT(verb >= SkPath::kMove_Verb && verb <= SkPath::kDone_Verb);
SkASSERT((unsigned) verb == (unsigned char) verb);
fprintf(out, "%u", verb);
if (++index < verbCount) {
outChCount += 3;
fprintf(out, "%c", ',');
if (outChCount >= kMaxLineLength) {
outChCount = 0;
fprintf(out, "%c", '\n');
} else {
fprintf(out, "%c", ' ');
}
}
SkScalar width;
SkDEBUGCODE(int charCount =) paint.getTextWidths((const void*) &index, 2, &width);
SkASSERT(charCount == 1);
fprintf(out, " *widthArray.append() = ");
output_fixed(out, width);
fprintf(out, ";\n\n");
}
fprintf(out, "\n};\n\n");
fprintf(out, "const unsigned %sCharCodes[] = {\n", fontname);
int offsetCount = charCodes.count();
for (int index = 0; index < offsetCount;) {
unsigned offset = charCodes[index];
fprintf(out, "%u", offset);
if (++index < offsetCount) {
outChCount += offset_str_len(offset) + 2;
fprintf(out, "%c", ',');
if (outChCount >= kMaxLineLength) {
outChCount = 0;
fprintf(out, "%c", '\n');
} else {
fprintf(out, "%c", ' ');
}
}
}
fprintf(out, "\n};\n\n");
SkString widthsStr;
fprintf(out, "const SkFixed %sWidths[] = {\n", fontname);
for (int index = 0; index < offsetCount; ++index) {
output_fixed(widths[index], emSize, &widthsStr);
}
widthsStr = strip_final(widthsStr);
fprintf(out, "%s\n};\n\n", widthsStr.c_str());
fprintf(out, "const int %sCharCodesCount = (int) SK_ARRAY_COUNT(%sCharCodes);\n\n",
fontname, fontname);
SkPaint::FontMetrics metrics;
paint.getFontMetrics(&metrics);
fprintf(out, " SkPaint::FontMetrics metrics = {\n");
fprintf(out, " 0x%08x, ", metrics.fFlags);
output_scalar(out, metrics.fTop); fprintf(out, ", ");
output_scalar(out, metrics.fAscent); fprintf(out, ", ");
output_scalar(out, metrics.fDescent); fprintf(out, ", ");
output_scalar(out, metrics.fBottom); fprintf(out, ", ");
output_scalar(out, metrics.fLeading); fprintf(out, ",\n ");
output_scalar(out, metrics.fAvgCharWidth); fprintf(out, ", ");
output_scalar(out, metrics.fMaxCharWidth); fprintf(out, ", ");
output_scalar(out, metrics.fXMin); fprintf(out, ", ");
output_scalar(out, metrics.fXMax); fprintf(out, ",\n ");
output_scalar(out, metrics.fXHeight); fprintf(out, ", ");
output_scalar(out, metrics.fCapHeight); fprintf(out, ", ");
output_scalar(out, metrics.fUnderlineThickness); fprintf(out, ", ");
output_scalar(out, metrics.fUnderlinePosition); fprintf(out, "\n };\n");
fprintf(out, " return metrics;\n");
fprintf(out, "}\n\n}\n");
fprintf(out, "const SkPaint::FontMetrics %sMetrics = {\n", fontname);
SkString metricsStr;
metricsStr.printf("0x%08x, ", metrics.fFlags);
output_scalar(metrics.fTop, emSize, &metricsStr);
output_scalar(metrics.fAscent, emSize, &metricsStr);
output_scalar(metrics.fDescent, emSize, &metricsStr);
output_scalar(metrics.fBottom, emSize, &metricsStr);
output_scalar(metrics.fLeading, emSize, &metricsStr);
output_scalar(metrics.fAvgCharWidth, emSize, &metricsStr);
output_scalar(metrics.fMaxCharWidth, emSize, &metricsStr);
output_scalar(metrics.fXMin, emSize, &metricsStr);
output_scalar(metrics.fXMax, emSize, &metricsStr);
output_scalar(metrics.fXHeight, emSize, &metricsStr);
output_scalar(metrics.fCapHeight, emSize, &metricsStr);
output_scalar(metrics.fUnderlineThickness, emSize, &metricsStr);
output_scalar(metrics.fUnderlinePosition, emSize, &metricsStr);
metricsStr = strip_final(metricsStr);
fprintf(out, "%s\n};\n\n", metricsStr.c_str());
}
struct FontWritten {
const char* fName;
SkTypeface::Style fStyle;
};
static SkTDArray<FontWritten> gWritten;
static int written_index(const FontDesc& fontDesc) {
for (int index = 0; index < gWritten.count(); ++index) {
const FontWritten& writ = gWritten[index];
if (!strcmp(fontDesc.fFont, writ.fName) && fontDesc.fStyle == writ.fStyle) {
return index;
}
}
return -1;
}
static void generate_fonts(FILE* out) {
for (int index = 0; index < gFontsCount; ++index) {
FontDesc& fontDesc = gFonts[index];
int fontIndex = written_index(fontDesc);
if (fontIndex >= 0) {
fontDesc.fFontIndex = fontIndex;
continue;
}
SkTypeface* systemTypeface = SkTypeface::CreateFromName(fontDesc.fFont, fontDesc.fStyle);
SkASSERT(systemTypeface);
SkString filepath(GetResourcePath(fontDesc.fFile));
SkASSERT(sk_exists(filepath.c_str()));
SkTypeface* resourceTypeface = SkTypeface::CreateFromFile(filepath.c_str());
SkASSERT(resourceTypeface);
output_font(resourceTypeface, fontDesc.fFont, fontDesc.fStyle, fontDesc.fCharsUsed, out);
fontDesc.fFontIndex = gWritten.count();
FontWritten* writ = gWritten.append();
writ->fName = fontDesc.fFont;
writ->fStyle = fontDesc.fStyle;
}
}
static void generate_index(const char* defaultName, FILE* out) {
int fontCount = gWritten.count();
fprintf(out,
"static SkTestFontData gTestFonts[] = {\n");
int fontIndex;
for (fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
const FontWritten& writ = gWritten[fontIndex];
const char* name = writ.fName;
SkString strippedStr = strip_spaces(SkString(name));
strippedStr.appendf("%s", gStyleName[writ.fStyle]);
const char* strip = strippedStr.c_str();
fprintf(out,
" { %sPoints, %sVerbs, %sCharCodes,\n"
" %sCharCodesCount, %sWidths,\n"
" %sMetrics, \"%s\", SkTypeface::%s, NULL\n"
" },\n",
strip, strip, strip, strip, strip, strip, name, gStyleName[writ.fStyle]);
}
fprintf(out, "};\n\n");
fprintf(out, "const int gTestFontsCount = (int) SK_ARRAY_COUNT(gTestFonts);\n\n");
fprintf(out,
"struct SubFont {\n"
" const char* fName;\n"
" SkTypeface::Style fStyle;\n"
" SkTestFontData& fFont;\n"
" const char* fFile;\n"
"};\n\n"
"const SubFont gSubFonts[] = {\n");
int defaultIndex = -1;
for (int subIndex = 0; subIndex < gFontsCount; subIndex++) {
const FontDesc& desc = gFonts[subIndex];
if (!strcmp(defaultName, desc.fName)) {
defaultIndex = subIndex;
}
fprintf(out,
" { \"%s\", SkTypeface::%s, gTestFonts[%d], \"%s\"},\n", desc.fName,
gStyleName[desc.fStyle], desc.fFontIndex, desc.fFile);
}
fprintf(out, "};\n\n");
fprintf(out, "const int gSubFontsCount = (int) SK_ARRAY_COUNT(gSubFonts);\n\n");
SkASSERT(defaultIndex >= 0);
fprintf(out, "const int gDefaultFontIndex = %d;\n", defaultIndex);
}
int main(int , char * const []) {
#ifndef SK_BUILD_FOR_MAC
#error "use fonts installed on Mac"
#endif
FILE* out = font_header();
generate_fonts(out);
generate_index(DEFAULT_FONT_NAME, out);
fclose(out);
return 0;
}
#if !defined SK_BUILD_FOR_IOS
int main(int argc, char * const argv[]) {
return tool_main(argc, (char**) argv);
}
#endif

View File

@ -6,15 +6,17 @@
*/
#include "sk_tool_utils.h"
#include "../src/fonts/SkTestScalerContext.h"
#include "sk_tool_utils_flags.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkTestScalerContext.h"
DEFINE_bool(portableFonts, false, "Use portable fonts");
DEFINE_bool(resourceFonts, false, "Use resource fonts");
namespace sk_tool_utils {
bool gEnablePortableTypeface = false;
const char* colortype_name(SkColorType ct) {
switch (ct) {
case kUnknown_SkColorType: return "Unknown";
@ -30,12 +32,21 @@ const char* colortype_name(SkColorType ct) {
}
}
SkPaint::FontMetrics create_font(SkTDArray<SkPath*>& , SkTDArray<SkFixed>& );
void set_portable_typeface(SkPaint* paint, SkTypeface::Style style) {
if (gEnablePortableTypeface) {
SkSafeUnref(paint->setTypeface(CreateTestTypeface(create_font, style)));
SkTypeface* create_portable_typeface(const char* name, SkTypeface::Style style) {
SkTypeface* face;
if (FLAGS_portableFonts) {
face = create_font(name, style);
} else if (FLAGS_resourceFonts) {
face = resource_font(name, style);
} else {
face = SkTypeface::CreateFromName(name, style);
}
return face;
}
void set_portable_typeface(SkPaint* paint, const char* name, SkTypeface::Style style) {
SkTypeface* face = create_portable_typeface(name, style);
SkSafeUnref(paint->setTypeface(face));
}
void write_pixels(SkCanvas* canvas, const SkBitmap& bitmap, int x, int y,

View File

@ -8,22 +8,25 @@
#ifndef sk_tool_utils_DEFINED
#define sk_tool_utils_DEFINED
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkImageInfo.h"
#include "SkPaint.h"
#include "SkTypeface.h"
namespace sk_tool_utils {
class SkBitmap;
class SkCanvas;
class SkPaint;
class SkTestFont;
extern bool gEnablePortableTypeface;
namespace sk_tool_utils {
const char* colortype_name(SkColorType);
/**
* Sets the paint to use a platform-independent text renderer.
*/
void set_portable_typeface(SkPaint* paint, SkTypeface::Style style = SkTypeface::kNormal);
void set_portable_typeface(SkPaint* paint, const char* name = NULL,
SkTypeface::Style style = SkTypeface::kNormal);
SkTypeface* create_portable_typeface(const char* name, SkTypeface::Style style);
void report_used_chars();
/**
* Call canvas->writePixels() by using the pixels from bitmap, but with an info that claims
@ -31,6 +34,10 @@ namespace sk_tool_utils {
*/
void write_pixels(SkCanvas*, const SkBitmap&, int x, int y, SkColorType, SkAlphaType);
// private to sk_tool_utils
SkTypeface* create_font(const char* name, SkTypeface::Style );
SkTypeface* resource_font(const char* name, SkTypeface::Style );
} // namespace sk_tool_utils
#endif // sk_tool_utils_DEFINED

View File

@ -0,0 +1,16 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef sk_tool_utils_flags_DEFINED
#define sk_tool_utils_flags_DEFINED
#include "SkCommandLineFlags.h"
DECLARE_bool(portableFonts);
DECLARE_bool(resourceFonts);
#endif // sk_tool_utils_flags_DEFINED

File diff suppressed because it is too large Load Diff

8622
tools/test_font_data.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// Auto-generated by sk_tool_utils_font.cpp
const char gCourierNew[] =
" !/<>ACHMTWYabcdefgilmnoprstuy";
const char gCourierNew_Bold[] =
" AHTWYabefgmnoprsuy";
const char gCourierNew_Italic[] =
" AHTWYabefgmnoprsuy";
const char gCourierNew_BoldItalic[] =
" AHTWYabefgmnoprsuy";
const char gLiberationSans[] =
" !#%&')*+-./1245679:;<=>?@ABCDEFHIJKLMNOPQRSTVWXYZ[\\]^`abcdefgilmnopqrstuvwxyz";
const char gLiberationSans_Bold[] =
" !\"#$%&'()*+-./012356789:;=>?ABCDEFGHIJLMORSTUVWXYZ[]^_abdefghijklmnopqrsuvwxyz";
const char gLiberationSans_Italic[] =
" AHTWYabefgmnoprsuy";
const char gLiberationSans_BoldItalic[] =
" !,-./012345689:ABCDEFGHIKLMNOPQRSTUWXYZ[\\]_abcdefghijklmnopqrstuvwxyz";
const char gHiraginoMaruGothicPro[] =
" !Tacefnprsuy" "\xE3" "\x83" "\xBC";
const char gPapyrus[] =
" !HTaceflnoprsuy";
const char gTimesNewRoman[] =
" !\"#$%&'()*+,-./123456789;<=>?@ABCDEFGHIJKLMNPQRSTVWXYZ[\\]^_`abcdefgijklmnopqrstuvwxyz";
const char gTimesNewRoman_Bold[] =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz";
const char gTimesNewRoman_Italic[] =
" AHTWYabefgmnoprsuy";
const char gTimesNewRoman_BoldItalic[] =
" AHTWYabefgmnoprsuy";