create_test_font.cpp revision 5fb6bd4b7e8d00b7f2543ca10ec9022b32632f29
1/*
2 * Copyright 2014 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 "SkPaint.h"
9#include "SkPath.h"
10#include "SkStream.h"
11#include "SkTArray.h"
12#include "SkTSort.h"
13#include "SkTypeface.h"
14#include <stdio.h>
15
16enum {
17    kEmSize = 4096
18};
19
20static void output_fixed(FILE* out, SkScalar num) {
21    SkASSERT(floor(num) == num);
22    int hex = (int) num * (65536 / kEmSize);
23    fprintf(out, "0x%08x", hex);
24}
25
26static void output_scalar(FILE* out, SkScalar num) {
27    num /= kEmSize;
28    if (num == (int) num) {
29       fprintf(out, "%d", (int) num);
30    } else {
31        SkString str;
32        str.printf("%1.6g", num);
33        int width = (int) str.size();
34        const char* cStr = str.c_str();
35        while (cStr[width - 1] == '0') {
36            --width;
37        }
38        str.resize(width);
39        fprintf(out, "%sf", str.c_str());
40    }
41}
42
43static void output_points(FILE* out, const SkPoint* pts, int count) {
44    for (int index = 0; index < count; ++index) {
45        SkASSERT(floor(pts[index].fX) == pts[index].fX);
46        output_scalar(out, pts[index].fX);
47        fprintf(out, ", ");
48        SkASSERT(floor(pts[index].fY) == pts[index].fY);
49        output_scalar(out, pts[index].fY);
50        if (index + 1 < count) {
51            fprintf(out, ", ");
52        }
53    }
54    fprintf(out, ");\n");
55}
56
57const char header[] =
58"/*\n"
59" * Copyright 2014 Google Inc.\n"
60" *\n"
61" * Use of this source code is governed by a BSD-style license that can be\n"
62" * found in the LICENSE file.\n"
63" */\n"
64"\n"
65"// this was auto-generated by TestFontCreator.cpp\n"
66"\n"
67"#include \"SkPaint.h\"\n"
68"#include \"SkPath.h\"\n"
69"#include \"SkTDArray.h\"\n"
70"\n"
71"namespace sk_tool_utils {\n"
72"\n"
73"SkPaint::FontMetrics create_font(SkTDArray<SkPath*>& pathArray,\n"
74"                                 SkTDArray<SkFixed>& widthArray) {";
75
76int tool_main(int argc, char** argv);
77int tool_main(int argc, char** argv) {
78    SkPaint paint;
79    paint.setAntiAlias(true);
80    paint.setTextAlign(SkPaint::kLeft_Align);
81    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
82    paint.setTextSize(kEmSize);
83    SkString filename("resources/DroidSans.ttf");
84    SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
85    if (!stream->isValid()) {
86        SkDebugf("Could not find resources/Roboto-Regular.ttf.\n");
87        return 1;
88    }
89    SkTypeface* typeface = SkTypeface::CreateFromStream(stream);
90    SkSafeUnref(paint.setTypeface(typeface));
91    FILE* out = fopen("./out/sk_tool_utils_font.cpp", "w");
92    fprintf(out, "%s\n", header);
93    fprintf(out, "    SkPath* path;\n");
94    for (unsigned short index = 0x20; index < 0x7F; ++index) {
95        SkPath path;
96        paint.getTextPath((const void*) &index, 2, 0, 0, &path);
97        SkPath::RawIter iter(path);
98        uint8_t verb;
99        SkPoint pts[4];
100        fprintf(out, "    path = SkNEW(SkPath); //");
101        if (index == '\\') {
102            fprintf(out, " blackslash\n");
103        } else if (index == ' ') {
104            fprintf(out, " space\n");
105        } else {
106            fprintf(out, " %c\n", (char) index);
107        }
108        fprintf(out, "    *pathArray.append() = path;\n");
109        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
110            switch (verb) {
111                case SkPath::kMove_Verb:
112                    fprintf(out, "    path->moveTo(");
113                    output_points(out, &pts[0], 1);
114                    continue;
115                case SkPath::kLine_Verb:
116                    fprintf(out, "    path->lineTo(");
117                    output_points(out, &pts[1], 1);
118                    break;
119                case SkPath::kQuad_Verb:
120                    fprintf(out, "    path->quadTo(");
121                    output_points(out, &pts[1], 2);
122                    break;
123                case SkPath::kCubic_Verb:
124                    fprintf(out, "    path->cubicTo(");
125                    output_points(out, &pts[1], 3);
126                    break;
127                case SkPath::kClose_Verb:
128                    fprintf(out, "    path->close();\n");
129                    break;
130                default:
131                    SkDEBUGFAIL("bad verb");
132                    return 1;
133            }
134        }
135        SkScalar width;
136        SkDEBUGCODE(int charCount =) paint.getTextWidths((const void*) &index, 2, &width);
137        SkASSERT(charCount == 1);
138        fprintf(out, "    *widthArray.append() = ");
139        output_fixed(out, width);
140        fprintf(out, ";\n\n");
141    }
142    SkPaint::FontMetrics metrics;
143    paint.getFontMetrics(&metrics);
144    fprintf(out, "    SkPaint::FontMetrics metrics = {\n");
145    fprintf(out, "        0x%08x, ", metrics.fFlags);
146    output_scalar(out, metrics.fTop); fprintf(out, ", ");
147    output_scalar(out, metrics.fAscent); fprintf(out, ", ");
148    output_scalar(out, metrics.fDescent); fprintf(out, ", ");
149    output_scalar(out, metrics.fBottom); fprintf(out, ", ");
150    output_scalar(out, metrics.fLeading); fprintf(out, ",\n        ");
151    output_scalar(out, metrics.fAvgCharWidth); fprintf(out, ", ");
152    output_scalar(out, metrics.fMaxCharWidth); fprintf(out, ", ");
153    output_scalar(out, metrics.fXMin); fprintf(out, ", ");
154    output_scalar(out, metrics.fXMax); fprintf(out, ",\n        ");
155    output_scalar(out, metrics.fXHeight); fprintf(out, ", ");
156    output_scalar(out, metrics.fCapHeight); fprintf(out, ", ");
157    output_scalar(out, metrics.fUnderlineThickness); fprintf(out, ", ");
158    output_scalar(out, metrics.fUnderlinePosition); fprintf(out, "\n    };\n");
159    fprintf(out, "    return metrics;\n");
160    fprintf(out, "}\n\n}\n");
161    fclose(out);
162    return 0;
163}
164
165#if !defined SK_BUILD_FOR_IOS
166int main(int argc, char * const argv[]) {
167    return tool_main(argc, (char**) argv);
168}
169#endif
170