summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/gm/typeface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/gm/typeface.cpp')
-rw-r--r--chromium/third_party/skia/gm/typeface.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/chromium/third_party/skia/gm/typeface.cpp b/chromium/third_party/skia/gm/typeface.cpp
new file mode 100644
index 00000000000..f2c56a591ed
--- /dev/null
+++ b/chromium/third_party/skia/gm/typeface.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2012 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 "SkString.h"
+#include "SkTypeface.h"
+#include "SkTypes.h"
+
+static const char* gFaces[] = {
+ "Times Roman",
+ "Hiragino Maru Gothic Pro",
+ "Papyrus",
+ "Helvetica",
+ "Courier New"
+};
+
+class TypefaceGM : public skiagm::GM {
+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);
+ }
+ }
+
+ virtual ~TypefaceGM() {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gFaces); i++) {
+ SkSafeUnref(fFaces[i]);
+ }
+ delete [] fFaces;
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("typeface");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkString text("Typefaces are fun!");
+ SkScalar y = 0;
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ for (int i = 0; i < (int)SK_ARRAY_COUNT(gFaces); i++) {
+ this->drawWithFace(text, i, y, paint, canvas);
+ }
+ // Now go backwards
+ for (int i = SK_ARRAY_COUNT(gFaces) - 1; i >= 0; i--) {
+ this->drawWithFace(text, i, y, paint, canvas);
+ }
+ }
+
+private:
+ void drawWithFace(const SkString& text, int i, SkScalar& y, SkPaint& paint,
+ SkCanvas* canvas) {
+ paint.setTypeface(fFaces[i]);
+ y += paint.getFontMetrics(NULL);
+ canvas->drawText(text.c_str(), text.size(), 0, y, paint);
+ }
+
+ SkTypeface** fFaces;
+
+ typedef skiagm::GM INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void getGlyphPositions(const SkPaint& paint, const uint16_t glyphs[],
+ int count, SkScalar x, SkScalar y, SkPoint pos[]) {
+ SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding());
+
+ SkAutoSTMalloc<128, SkScalar> widthStorage(count);
+ SkScalar* widths = widthStorage.get();
+ paint.getTextWidths(glyphs, count * sizeof(uint16_t), widths);
+
+ for (int i = 0; i < count; ++i) {
+ pos[i].set(x, y);
+ x += widths[i];
+ }
+}
+
+static void applyKerning(SkPoint pos[], const int32_t adjustments[], int count,
+ const SkPaint& paint) {
+ SkScalar scale = paint.getTextSize() / paint.getTypeface()->getUnitsPerEm();
+
+ SkScalar globalAdj = 0;
+ for (int i = 0; i < count - 1; ++i) {
+ globalAdj += adjustments[i] * scale;
+ pos[i + 1].fX += globalAdj;
+ }
+}
+
+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);
+}
+
+static const struct {
+ const char* fName;
+ SkTypeface::Style fStyle;
+} gFaceStyles[] = {
+ { "sans-serif", SkTypeface::kNormal },
+ { "sans-serif", SkTypeface::kBold },
+ { "sans-serif", SkTypeface::kItalic },
+ { "sans-serif", SkTypeface::kBoldItalic },
+ { "serif", SkTypeface::kNormal },
+ { "serif", SkTypeface::kBold },
+ { "serif", SkTypeface::kItalic },
+ { "serif", SkTypeface::kBoldItalic },
+ { "monospace", SkTypeface::kNormal },
+ { "monospace", SkTypeface::kBold },
+ { "monospace", SkTypeface::kItalic },
+ { "monospace", SkTypeface::kBoldItalic },
+};
+
+static const int gFaceStylesCount = SK_ARRAY_COUNT(gFaceStyles);
+
+class TypefaceStylesGM : public skiagm::GM {
+ SkTypeface* fFaces[gFaceStylesCount];
+ bool fApplyKerning;
+
+public:
+ TypefaceStylesGM(bool applyKerning) : fApplyKerning(applyKerning) {
+ for (int i = 0; i < gFaceStylesCount; i++) {
+ fFaces[i] = SkTypeface::CreateFromName(gFaceStyles[i].fName,
+ gFaceStyles[i].fStyle);
+ }
+ }
+
+ virtual ~TypefaceStylesGM() {
+ for (int i = 0; i < gFaceStylesCount; i++) {
+ SkSafeUnref(fFaces[i]);
+ }
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ SkString name("typefacestyles");
+ if (fApplyKerning) {
+ name.append("_kerning");
+ }
+ return name;
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTextSize(SkIntToScalar(30));
+
+ const char* text = fApplyKerning ? "Type AWAY" : "Hamburgefons";
+ const size_t textLen = strlen(text);
+
+ SkScalar x = SkIntToScalar(10);
+ SkScalar dy = paint.getFontMetrics(NULL);
+ SkScalar y = dy;
+
+ if (fApplyKerning) {
+ paint.setSubpixelText(true);
+ } else {
+ paint.setLinearText(true);
+ }
+ for (int i = 0; i < gFaceStylesCount; i++) {
+ paint.setTypeface(fFaces[i]);
+ canvas->drawText(text, textLen, x, y, paint);
+ if (fApplyKerning) {
+ drawKernText(canvas, text, textLen, x + 240, y, paint);
+ }
+ y += dy;
+ }
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return new TypefaceGM; )
+DEF_GM( return new TypefaceStylesGM(false); )
+DEF_GM( return new TypefaceStylesGM(true); )