Skip to content

Commit

Permalink
add textutils
Browse files Browse the repository at this point in the history
These are meant to enable several things (eventually)

- fission Align off of paint
- fission TextEncoding off of paint
- fission SkFont of of paint

The first one is explicitly enabled here. The others will (I plan) follow later.

The final state of the world (the goal)
- paint has no font-ish parameters (no typeface or size)
- font has no paint-ish parameters (no aa or lcd)
- neither has alignment or encoding

Bug: skia:8493, skia:8501
Change-Id: I5fcb945b6bcab30ef5e7019dfccb682661f56230
Reviewed-on: https://skia-review.googlesource.com/c/165061
Auto-Submit: Mike Reed <[email protected]>
Reviewed-by: Mike Reed <[email protected]>
Commit-Queue: Mike Reed <[email protected]>
  • Loading branch information
reed-at-google authored and Skia Commit-Bot committed Oct 25, 2018
1 parent 1648976 commit 331ccfd
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 40 deletions.
32 changes: 17 additions & 15 deletions gm/aaxfermodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "SkColorPriv.h"
#include "SkPath.h"
#include "SkShader.h"
#include "SkTextUtils.h"

enum {
kXfermodeCount = (int)SkBlendMode::kLastMode + 1 + 1, // extra for arith
Expand Down Expand Up @@ -106,14 +107,14 @@ class AAXfermodesGM : public skiagm::GM {
canvas->save();

if (kShape_Pass == drawingPass) {
fLabelPaint.setTextAlign(SkPaint::kCenter_Align);
canvas->drawString("Src Unknown",
SkTextUtils::DrawString(canvas, "Src Unknown",
kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing / 2,
kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3, fLabelPaint);
canvas->drawString("Src Opaque",
kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3, fLabelPaint,
SkPaint::kCenter_Align);
SkTextUtils::DrawString(canvas, "Src Opaque",
kLabelSpacing + kShapeTypeSpacing * 1.5f + kShapeSpacing / 2 +
kPaintSpacing, kSubtitleSpacing / 2 + fLabelPaint.getTextSize() / 3,
fLabelPaint);
fLabelPaint, SkPaint::kCenter_Align);
}

canvas->translate(0, kSubtitleSpacing + kShapeSpacing/2);
Expand Down Expand Up @@ -179,23 +180,24 @@ class AAXfermodesGM : public skiagm::GM {
SkPaint titlePaint(fLabelPaint);
titlePaint.setTextSize(9 * titlePaint.getTextSize() / 8);
titlePaint.setFakeBoldText(true);
titlePaint.setTextAlign(SkPaint::kCenter_Align);
canvas->drawString("Porter Duff",
kLabelSpacing + 4 * kShapeTypeSpacing,
kTitleSpacing / 2 + titlePaint.getTextSize() / 3, titlePaint);
canvas->drawString("Advanced",
kXfermodeTypeSpacing + kLabelSpacing + 4 * kShapeTypeSpacing,
kTitleSpacing / 2 + titlePaint.getTextSize() / 3, titlePaint);
SkTextUtils::DrawString(canvas, "Porter Duff",
kLabelSpacing + 4 * kShapeTypeSpacing,
kTitleSpacing / 2 + titlePaint.getTextSize() / 3, titlePaint,
SkPaint::kCenter_Align);
SkTextUtils::DrawString(canvas, "Advanced",
kXfermodeTypeSpacing + kLabelSpacing + 4 * kShapeTypeSpacing,
kTitleSpacing / 2 + titlePaint.getTextSize() / 3, titlePaint,
SkPaint::kCenter_Align);

draw_pass(canvas, kShape_Pass);
canvas->restore();
}

void drawModeName(SkCanvas* canvas, SkBlendMode mode) {
const char* modeName = SkBlendMode_Name(mode);
fLabelPaint.setTextAlign(SkPaint::kRight_Align);
canvas->drawString(modeName, kLabelSpacing - kShapeSize / 4,
fLabelPaint.getTextSize() / 4, fLabelPaint);
SkTextUtils::DrawString(canvas, modeName, kLabelSpacing - kShapeSize / 4,
fLabelPaint.getTextSize() / 4, fLabelPaint,
SkPaint::kRight_Align);
}

void setupShapePaint(SkCanvas* canvas, SkColor color, SkBlendMode mode, SkPaint* paint) {
Expand Down
6 changes: 3 additions & 3 deletions gm/androidblendmodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "gm.h"
#include "sk_tool_utils.h"
#include "SkBitmap.h"
#include "SkTextUtils.h"

namespace skiagm {

Expand Down Expand Up @@ -67,7 +68,6 @@ class AndroidBlendModesGM : public GM {
SkPaint textPaint;
textPaint.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&textPaint);
textPaint.setTextAlign(SkPaint::kCenter_Align);

sk_tool_utils::draw_checkerboard(canvas,
kWhite,
Expand All @@ -94,10 +94,10 @@ class AndroidBlendModesGM : public GM {
this->drawTile(canvas, xOffset, yOffset, mode);
canvas->restoreToCount(saveCount);

canvas->drawString(SkBlendMode_Name(mode),
SkTextUtils::DrawString(canvas, SkBlendMode_Name(mode),
xOffset + kBitmapSize/2.0f,
yOffset + kBitmapSize,
textPaint);
textPaint, SkPaint::kCenter_Align);

xOffset += 256;
if (xOffset >= 1024) {
Expand Down
10 changes: 4 additions & 6 deletions gm/tilemodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkTextUtils.h"
#include "SkUTF.h"
// effects
#include "SkGradientShader.h"
Expand Down Expand Up @@ -104,8 +105,7 @@ class TilingGM : public skiagm::GM {
p.setDither(true);
str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);

p.setTextAlign(SkPaint::kCenter_Align);
canvas->drawString(str, x + r.width()/2, y, p);
SkTextUtils::DrawString(canvas, str, x + r.width()/2, y, p, SkPaint::kCenter_Align);

x += r.width() * 4 / 3;
}
Expand Down Expand Up @@ -223,22 +223,20 @@ class Tiling2GM : public skiagm::GM {
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++) {
SkString str(gModeNames[kx]);
canvas->drawString(str, x + r.width()/2, y, p);
SkTextUtils::DrawString(canvas, str, x + r.width()/2, y, p, SkPaint::kCenter_Align);
x += r.width() * 4 / 3;
}

y += SkIntToScalar(16) + h;
p.setTextAlign(SkPaint::kRight_Align);

for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
x = SkIntToScalar(16) + w;

SkString str(gModeNames[ky]);
canvas->drawString(str, x, y + h/2, p);
SkTextUtils::DrawString(canvas, str, x, y + h/2, p, SkPaint::kRight_Align);

x += SkIntToScalar(50);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
Expand Down
11 changes: 5 additions & 6 deletions gm/tilemodes_scaled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkTextUtils.h"
#include "SkUTF.h"

// effects
Expand Down Expand Up @@ -106,8 +107,8 @@ class ScaledTilingGM : public skiagm::GM {
sk_tool_utils::set_portable_typeface(&p);
str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);

p.setTextAlign(SkPaint::kCenter_Align);
canvas->drawString(str, scale*(x + r.width()/2), y, p);
SkTextUtils::DrawString(canvas, str, scale*(x + r.width()/2), y, p,
SkPaint::kCenter_Align);

x += r.width() * 4 / 3;
}
Expand Down Expand Up @@ -224,22 +225,20 @@ class ScaledTiling2GM : public skiagm::GM {
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++) {
SkString str(gModeNames[kx]);
canvas->drawString(str, x + r.width()/2, y, p);
SkTextUtils::DrawString(canvas, str, x + r.width()/2, y, p, SkPaint::kCenter_Align);
x += r.width() * 4 / 3;
}

y += SkIntToScalar(16) + h;
p.setTextAlign(SkPaint::kRight_Align);

for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
x = SkIntToScalar(16) + w;

SkString str(gModeNames[ky]);
canvas->drawString(str, x, y + h/2, p);
SkTextUtils::DrawString(canvas, str, x, y + h/2, p, SkPaint::kRight_Align);

x += SkIntToScalar(50);
for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
Expand Down
7 changes: 4 additions & 3 deletions gm/windowrectangles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "sk_tool_utils.h"
#include "SkClipStack.h"
#include "SkRRect.h"
#include "SkTextUtils.h"

#include "GrAppliedClip.h"
#include "GrCaps.h"
Expand Down Expand Up @@ -265,7 +266,6 @@ void WindowRectanglesMaskGM::stencilCheckerboard(GrRenderTargetContext* rtc, boo
void WindowRectanglesMaskGM::fail(SkCanvas* canvas) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setTextAlign(SkPaint::kCenter_Align);
paint.setTextSize(20);
sk_tool_utils::set_portable_typeface(&paint);

Expand All @@ -275,8 +275,9 @@ void WindowRectanglesMaskGM::fail(SkCanvas* canvas) {
canvas->clipRect(SkRect::Make(kCoverRect));
canvas->clear(SK_ColorWHITE);

canvas->drawString(errorMsg, SkIntToScalar((kCoverRect.left() + kCoverRect.right())/2),
SkIntToScalar((kCoverRect.top() + kCoverRect.bottom())/2 - 10), paint);
SkTextUtils::DrawString(canvas, errorMsg, SkIntToScalar((kCoverRect.left() + kCoverRect.right())/2),
SkIntToScalar((kCoverRect.top() + kCoverRect.bottom())/2 - 10), paint,
SkPaint::kCenter_Align);
}

DEF_GM( return new WindowRectanglesMaskGM(); )
Expand Down
6 changes: 3 additions & 3 deletions gm/xfermodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "sk_tool_utils.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkTextUtils.h"

enum SrcType {
//! A WxH image with a rectangle in the lower right.
Expand Down Expand Up @@ -227,7 +228,6 @@ class XfermodesGM : public skiagm::GM {
SkPaint labelP;
labelP.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelP);
labelP.setTextAlign(SkPaint::kCenter_Align);

const int W = 5;

Expand Down Expand Up @@ -258,8 +258,8 @@ class XfermodesGM : public skiagm::GM {

#if 1
const char* label = SkBlendMode_Name(gModes[i].fMode);
canvas->drawString(label,
x + w/2, y - labelP.getTextSize()/2, labelP);
SkTextUtils::DrawString(canvas, label, x + w/2, y - labelP.getTextSize()/2,
labelP, SkPaint::kCenter_Align);
#endif
x += w + SkIntToScalar(10);
if ((i % W) == W - 1) {
Expand Down
7 changes: 4 additions & 3 deletions gm/xfermodes2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "SkShader.h"
#include "SkBlendModePriv.h"
#include "SkColorPriv.h"
#include "SkTextUtils.h"

namespace skiagm {

Expand All @@ -35,7 +36,6 @@ class Xfermodes2GM : public GM {
SkPaint labelP;
labelP.setAntiAlias(true);
sk_tool_utils::set_portable_typeface(&labelP);
labelP.setTextAlign(SkPaint::kCenter_Align);

const int W = 6;

Expand Down Expand Up @@ -72,8 +72,9 @@ class Xfermodes2GM : public GM {
canvas->restore();

#if 1
canvas->drawString(SkBlendMode_Name(mode),
x + w/2, y - labelP.getTextSize()/2, labelP);
SkTextUtils::DrawString(canvas, SkBlendMode_Name(mode),
x + w/2, y - labelP.getTextSize()/2, labelP,
SkPaint::kCenter_Align);
#endif
x += w + SkIntToScalar(10);
if ((m % W) == W - 1) {
Expand Down
2 changes: 1 addition & 1 deletion gm/xfermodes3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "SkSurface.h"
#include "SkBlendModePriv.h"
#include "SkColorPriv.h"

#include "SkTextUtils.h"
#include "GrContext.h"

namespace skiagm {
Expand Down
1 change: 1 addition & 0 deletions gn/utils.gni
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ skia_utils_sources = [
"$_src/utils/SkShadowTessellator.cpp",
"$_src/utils/SkShadowTessellator.h",
"$_src/utils/SkShadowUtils.cpp",
"$_src/utils/SkTextUtils.cpp",
"$_src/utils/SkThreadUtils_pthread.cpp",
"$_src/utils/SkThreadUtils_win.cpp",
"$_src/utils/SkUTF.cpp",
Expand Down
31 changes: 31 additions & 0 deletions include/utils/SkTextUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#ifndef SkTextUtils_DEFINED
#define SkTextUtils_DEFINED

#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkFont.h"
#include "SkString.h"

class SkTextUtils {
public:
static void DrawText(SkCanvas*, const void* text, size_t size, SkScalar x, SkScalar y,
const SkPaint&, SkPaint::Align = SkPaint::kLeft_Align);

static void DrawString(SkCanvas* canvas, const char text[], SkScalar x, SkScalar y,
const SkPaint& paint, SkPaint::Align align = SkPaint::kLeft_Align) {
DrawText(canvas, text, strlen(text), x, y, paint, align);
}
static void DrawString(SkCanvas* canvas, const SkString& str, SkScalar x, SkScalar y,
const SkPaint& paint, SkPaint::Align align = SkPaint::kLeft_Align) {
DrawText(canvas, str.c_str(), str.size(), x, y, paint, align);
}
};

#endif
53 changes: 53 additions & 0 deletions src/utils/SkTextUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "SkTextUtils.h"

void SkTextUtils::DrawText(SkCanvas* canvas, const void* text, size_t size, SkScalar x, SkScalar y,
const SkPaint& origPaint, SkPaint::Align align) {
int count = origPaint.countText(text, size);
if (!count) {
return;
}

SkPaint paint(origPaint);
SkAutoSTArray<32, uint16_t> glyphStorage;
const uint16_t* glyphs;

if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
glyphStorage.reset(count);
paint.textToGlyphs(text, size, glyphStorage.get());
glyphs = glyphStorage.get();
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
} else {
glyphs = static_cast<const uint16_t*>(text);
}

SkAutoSTArray<32, SkScalar> widthStorage(count);
SkScalar* widths = widthStorage.get();
paint.getTextWidths(glyphs, count * sizeof(uint16_t), widths);

if (align != SkPaint::kLeft_Align) {
SkScalar offset = 0;
for (int i = 0; i < count; ++i) {
offset += widths[i];
}
if (align == SkPaint::kCenter_Align) {
offset *= 0.5f;
}
x -= offset;
}

// Turn widths into h-positions
for (int i = 0; i < count; ++i) {
SkScalar w = widths[i];
widths[i] = x;
x += w;
}
canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), widths, y, paint);
}

0 comments on commit 331ccfd

Please sign in to comment.