2012-07-27 20:39:19 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2013-10-30 15:07:03 +00:00
|
|
|
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);
|
2013-10-31 07:01:53 +00:00
|
|
|
|
2013-10-30 15:07:03 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
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 },
|
2012-07-27 20:39:19 +00:00
|
|
|
};
|
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
static const int gFaceStylesCount = SK_ARRAY_COUNT(gFaceStyles);
|
|
|
|
|
|
|
|
class TypefaceStylesGM : public skiagm::GM {
|
|
|
|
SkTypeface* fFaces[gFaceStylesCount];
|
2013-10-30 15:07:03 +00:00
|
|
|
bool fApplyKerning;
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
public:
|
2015-05-21 13:15:28 +00:00
|
|
|
TypefaceStylesGM(bool applyKerning)
|
|
|
|
: fApplyKerning(applyKerning) {
|
|
|
|
memset(fFaces, 0, sizeof(fFaces));
|
2013-02-26 16:57:16 +00:00
|
|
|
}
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
virtual ~TypefaceStylesGM() {
|
|
|
|
for (int i = 0; i < gFaceStylesCount; i++) {
|
|
|
|
SkSafeUnref(fFaces[i]);
|
|
|
|
}
|
|
|
|
}
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
protected:
|
2015-05-21 13:15:28 +00:00
|
|
|
void onOnceBeforeDraw() override {
|
|
|
|
for (int i = 0; i < gFaceStylesCount; i++) {
|
2015-07-24 18:08:01 +00:00
|
|
|
fFaces[i] = SkTypeface::CreateFromName(
|
|
|
|
sk_tool_utils::platform_font_name(gFaceStyles[i].fName), gFaceStyles[i].fStyle);
|
2015-05-21 13:15:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-26 01:17:31 +00:00
|
|
|
SkString onShortName() override {
|
2013-10-30 15:07:03 +00:00
|
|
|
SkString name("typefacestyles");
|
|
|
|
if (fApplyKerning) {
|
|
|
|
name.append("_kerning");
|
|
|
|
}
|
2015-07-24 18:08:01 +00:00
|
|
|
name.append(sk_tool_utils::major_platform_os_name());
|
2013-10-30 15:07:03 +00:00
|
|
|
return name;
|
2013-02-26 16:57:16 +00:00
|
|
|
}
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2015-03-26 01:17:31 +00:00
|
|
|
SkISize onISize() override {
|
2013-02-26 16:57:16 +00:00
|
|
|
return SkISize::Make(640, 480);
|
|
|
|
}
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2015-03-26 01:17:31 +00:00
|
|
|
void onDraw(SkCanvas* canvas) override {
|
2013-02-26 16:57:16 +00:00
|
|
|
SkPaint paint;
|
|
|
|
paint.setAntiAlias(true);
|
|
|
|
paint.setTextSize(SkIntToScalar(30));
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-10-30 15:07:03 +00:00
|
|
|
const char* text = fApplyKerning ? "Type AWAY" : "Hamburgefons";
|
2013-02-26 16:57:16 +00:00
|
|
|
const size_t textLen = strlen(text);
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
SkScalar x = SkIntToScalar(10);
|
2015-08-27 14:41:13 +00:00
|
|
|
SkScalar dy = paint.getFontMetrics(nullptr);
|
2013-02-26 16:57:16 +00:00
|
|
|
SkScalar y = dy;
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-10-30 15:07:03 +00:00
|
|
|
if (fApplyKerning) {
|
|
|
|
paint.setSubpixelText(true);
|
|
|
|
} else {
|
|
|
|
paint.setLinearText(true);
|
|
|
|
}
|
2013-02-26 16:57:16 +00:00
|
|
|
for (int i = 0; i < gFaceStylesCount; i++) {
|
|
|
|
paint.setTypeface(fFaces[i]);
|
|
|
|
canvas->drawText(text, textLen, x, y, paint);
|
2013-10-30 15:07:03 +00:00
|
|
|
if (fApplyKerning) {
|
|
|
|
drawKernText(canvas, text, textLen, x + 240, y, paint);
|
|
|
|
}
|
2013-02-26 16:57:16 +00:00
|
|
|
y += dy;
|
|
|
|
}
|
|
|
|
}
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
private:
|
|
|
|
typedef skiagm::GM INHERITED;
|
|
|
|
};
|
2013-02-27 07:10:10 +00:00
|
|
|
|
2013-02-26 16:57:16 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2012-07-27 20:39:19 +00:00
|
|
|
|
2013-10-30 15:07:03 +00:00
|
|
|
DEF_GM( return new TypefaceStylesGM(false); )
|
|
|
|
DEF_GM( return new TypefaceStylesGM(true); )
|