Remove SkTextBox
Change-Id: I697135475fa9c1b7e803500b743f10c3877c1e10 Reviewed-on: https://skia-review.googlesource.com/129560 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
d90cd3b279
commit
1724db1658
1
BUILD.gn
1
BUILD.gn
@ -1579,6 +1579,7 @@ if (skia_enable_tools) {
|
||||
"src/utils/SkLuaCanvas.cpp",
|
||||
]
|
||||
deps = [
|
||||
":skshaper",
|
||||
"//third_party/lua",
|
||||
]
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ skia_utils_sources = [
|
||||
"$_include/utils/SkParsePath.h",
|
||||
"$_include/utils/SkRandom.h",
|
||||
"$_include/utils/SkShadowUtils.h",
|
||||
"$_include/utils/SkTextBox.h",
|
||||
|
||||
"$_src/utils/SkBase64.cpp",
|
||||
"$_src/utils/SkBase64.h",
|
||||
@ -58,7 +57,6 @@ skia_utils_sources = [
|
||||
"$_src/utils/SkShadowTessellator.cpp",
|
||||
"$_src/utils/SkShadowTessellator.h",
|
||||
"$_src/utils/SkShadowUtils.cpp",
|
||||
"$_src/utils/SkTextBox.cpp",
|
||||
"$_src/utils/SkThreadUtils_pthread.cpp",
|
||||
"$_src/utils/SkThreadUtils_win.cpp",
|
||||
"$_src/utils/SkWhitelistTypefaces.cpp",
|
||||
|
@ -1,87 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkTextBox_DEFINED
|
||||
#define SkTextBox_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
|
||||
/** \class SkTextBox
|
||||
|
||||
SkTextBox is a helper class for drawing 1 or more lines of text
|
||||
within a rectangle. The textbox is positioned and clipped by its Frame.
|
||||
The Margin rectangle controls where the text is drawn relative to
|
||||
the Frame. Line-breaks occur inside the Margin rectangle.
|
||||
|
||||
Spacing is a linear equation used to compute the distance between lines
|
||||
of text. Spacing consists of two scalars: mul and add, and the spacing
|
||||
between lines is computed as: spacing = paint.getTextSize() * mul + add
|
||||
*/
|
||||
class SkTextBox {
|
||||
public:
|
||||
SkTextBox();
|
||||
|
||||
enum Mode {
|
||||
kOneLine_Mode,
|
||||
kLineBreak_Mode,
|
||||
|
||||
kModeCount
|
||||
};
|
||||
Mode getMode() const { return (Mode)fMode; }
|
||||
void setMode(Mode);
|
||||
|
||||
enum SpacingAlign {
|
||||
kStart_SpacingAlign,
|
||||
kCenter_SpacingAlign,
|
||||
kEnd_SpacingAlign,
|
||||
|
||||
kSpacingAlignCount
|
||||
};
|
||||
SpacingAlign getSpacingAlign() const { return (SpacingAlign)fSpacingAlign; }
|
||||
void setSpacingAlign(SpacingAlign);
|
||||
|
||||
void getBox(SkRect*) const;
|
||||
void setBox(const SkRect&);
|
||||
void setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
|
||||
|
||||
void getSpacing(SkScalar* mul, SkScalar* add) const;
|
||||
void setSpacing(SkScalar mul, SkScalar add);
|
||||
|
||||
void draw(SkCanvas*, const char text[], size_t len, const SkPaint&);
|
||||
|
||||
void setText(const char text[], size_t len, const SkPaint&);
|
||||
void draw(SkCanvas*);
|
||||
int countLines() const;
|
||||
SkScalar getTextHeight() const;
|
||||
|
||||
sk_sp<SkTextBlob> snapshotTextBlob(SkScalar* computedBottom) const;
|
||||
|
||||
class Visitor {
|
||||
public:
|
||||
virtual ~Visitor() {}
|
||||
virtual void operator()(const char*, size_t, SkScalar x, SkScalar y, const SkPaint&) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
SkRect fBox;
|
||||
SkScalar fSpacingMul, fSpacingAdd;
|
||||
uint8_t fMode, fSpacingAlign;
|
||||
const char* fText;
|
||||
size_t fLen;
|
||||
const SkPaint* fPaint;
|
||||
|
||||
SkScalar visit(Visitor&, const char text[], size_t len, const SkPaint&) const;
|
||||
};
|
||||
|
||||
class SkTextLineBreaker {
|
||||
public:
|
||||
static int CountLines(const char text[], size_t len, const SkPaint&, SkScalar width);
|
||||
};
|
||||
|
||||
#endif
|
@ -26,6 +26,7 @@
|
||||
#include "SkPictureRecorder.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkRRect.h"
|
||||
#include "SkShaper.h"
|
||||
#include "SkString.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkTextBlob.h"
|
||||
@ -1960,7 +1961,6 @@ static int lsk_newRRect(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "SkTextBox.h"
|
||||
// Sk.newTextBlob(text, rect, paint)
|
||||
static int lsk_newTextBlob(lua_State* L) {
|
||||
const char* text = lua_tolstring(L, 1, nullptr);
|
||||
@ -1968,14 +1968,14 @@ static int lsk_newTextBlob(lua_State* L) {
|
||||
lua2rect(L, 2, &bounds);
|
||||
const SkPaint& paint = *get_obj<SkPaint>(L, 3);
|
||||
|
||||
SkTextBox box;
|
||||
box.setMode(SkTextBox::kLineBreak_Mode);
|
||||
box.setBox(bounds);
|
||||
box.setText(text, strlen(text), paint);
|
||||
SkShaper shaper(nullptr);
|
||||
|
||||
SkScalar newBottom;
|
||||
push_ref<SkTextBlob>(L, box.snapshotTextBlob(&newBottom));
|
||||
SkLua(L).pushScalar(newBottom);
|
||||
SkTextBlobBuilder builder;
|
||||
SkPoint end = shaper.shape(&builder, paint, text, strlen(text), true,
|
||||
{ bounds.left(), bounds.top() }, bounds.width());
|
||||
|
||||
push_ref<SkTextBlob>(L, builder.make());
|
||||
SkLua(L).pushScalar(end.fY);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -1,302 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkTextBox.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
static inline int is_ws(int c)
|
||||
{
|
||||
return !((c - 1) >> 5);
|
||||
}
|
||||
|
||||
static size_t linebreak(const char text[], const char stop[],
|
||||
const SkPaint& paint, SkScalar margin,
|
||||
size_t* trailing = nullptr)
|
||||
{
|
||||
size_t lengthBreak = paint.breakText(text, stop - text, margin);
|
||||
|
||||
//Check for white space or line breakers before the lengthBreak
|
||||
const char* start = text;
|
||||
const char* word_start = text;
|
||||
int prevWS = true;
|
||||
if (trailing) {
|
||||
*trailing = 0;
|
||||
}
|
||||
|
||||
while (text < stop) {
|
||||
const char* prevText = text;
|
||||
SkUnichar uni = SkUTF8_NextUnichar(&text);
|
||||
int currWS = is_ws(uni);
|
||||
|
||||
if (!currWS && prevWS) {
|
||||
word_start = prevText;
|
||||
}
|
||||
prevWS = currWS;
|
||||
|
||||
if (text > start + lengthBreak) {
|
||||
if (currWS) {
|
||||
// eat the rest of the whitespace
|
||||
while (text < stop && is_ws(SkUTF8_ToUnichar(text))) {
|
||||
text += SkUTF8_CountUTF8Bytes(text);
|
||||
}
|
||||
if (trailing) {
|
||||
*trailing = text - prevText;
|
||||
}
|
||||
} else {
|
||||
// backup until a whitespace (or 1 char)
|
||||
if (word_start == start) {
|
||||
if (prevText > start) {
|
||||
text = prevText;
|
||||
}
|
||||
} else {
|
||||
text = word_start;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ('\n' == uni) {
|
||||
size_t ret = text - start;
|
||||
size_t lineBreakSize = 1;
|
||||
if (text < stop) {
|
||||
uni = SkUTF8_NextUnichar(&text);
|
||||
if ('\r' == uni) {
|
||||
ret = text - start;
|
||||
++lineBreakSize;
|
||||
}
|
||||
}
|
||||
if (trailing) {
|
||||
*trailing = lineBreakSize;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ('\r' == uni) {
|
||||
size_t ret = text - start;
|
||||
size_t lineBreakSize = 1;
|
||||
if (text < stop) {
|
||||
uni = SkUTF8_NextUnichar(&text);
|
||||
if ('\n' == uni) {
|
||||
ret = text - start;
|
||||
++lineBreakSize;
|
||||
}
|
||||
}
|
||||
if (trailing) {
|
||||
*trailing = lineBreakSize;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return text - start;
|
||||
}
|
||||
|
||||
int SkTextLineBreaker::CountLines(const char text[], size_t len, const SkPaint& paint, SkScalar width)
|
||||
{
|
||||
const char* stop = text + len;
|
||||
int count = 0;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
do {
|
||||
count += 1;
|
||||
text += linebreak(text, stop, paint, width);
|
||||
} while (text < stop);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkTextBox::SkTextBox()
|
||||
{
|
||||
fBox.setEmpty();
|
||||
fSpacingMul = SK_Scalar1;
|
||||
fSpacingAdd = 0;
|
||||
fMode = kLineBreak_Mode;
|
||||
fSpacingAlign = kStart_SpacingAlign;
|
||||
}
|
||||
|
||||
void SkTextBox::setMode(Mode mode)
|
||||
{
|
||||
SkASSERT((unsigned)mode < kModeCount);
|
||||
fMode = SkToU8(mode);
|
||||
}
|
||||
|
||||
void SkTextBox::setSpacingAlign(SpacingAlign align)
|
||||
{
|
||||
SkASSERT((unsigned)align < kSpacingAlignCount);
|
||||
fSpacingAlign = SkToU8(align);
|
||||
}
|
||||
|
||||
void SkTextBox::getBox(SkRect* box) const
|
||||
{
|
||||
if (box)
|
||||
*box = fBox;
|
||||
}
|
||||
|
||||
void SkTextBox::setBox(const SkRect& box)
|
||||
{
|
||||
fBox = box;
|
||||
}
|
||||
|
||||
void SkTextBox::setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
|
||||
{
|
||||
fBox.set(left, top, right, bottom);
|
||||
}
|
||||
|
||||
void SkTextBox::getSpacing(SkScalar* mul, SkScalar* add) const
|
||||
{
|
||||
if (mul)
|
||||
*mul = fSpacingMul;
|
||||
if (add)
|
||||
*add = fSpacingAdd;
|
||||
}
|
||||
|
||||
void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
|
||||
{
|
||||
fSpacingMul = mul;
|
||||
fSpacingAdd = add;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkScalar SkTextBox::visit(Visitor& visitor, const char text[], size_t len,
|
||||
const SkPaint& paint) const {
|
||||
SkScalar marginWidth = fBox.width();
|
||||
|
||||
if (marginWidth <= 0 || len == 0) {
|
||||
return fBox.top();
|
||||
}
|
||||
|
||||
const char* textStop = text + len;
|
||||
|
||||
SkScalar x, y, scaledSpacing, height, fontHeight;
|
||||
SkPaint::FontMetrics metrics;
|
||||
|
||||
switch (paint.getTextAlign()) {
|
||||
case SkPaint::kLeft_Align:
|
||||
x = 0;
|
||||
break;
|
||||
case SkPaint::kCenter_Align:
|
||||
x = SkScalarHalf(marginWidth);
|
||||
break;
|
||||
default:
|
||||
x = marginWidth;
|
||||
break;
|
||||
}
|
||||
x += fBox.fLeft;
|
||||
|
||||
fontHeight = paint.getFontMetrics(&metrics);
|
||||
scaledSpacing = fontHeight * fSpacingMul + fSpacingAdd;
|
||||
height = fBox.height();
|
||||
|
||||
// compute Y position for first line
|
||||
{
|
||||
SkScalar textHeight = fontHeight;
|
||||
|
||||
if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign) {
|
||||
int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
|
||||
SkASSERT(count > 0);
|
||||
textHeight += scaledSpacing * (count - 1);
|
||||
}
|
||||
|
||||
switch (fSpacingAlign) {
|
||||
case kStart_SpacingAlign:
|
||||
y = 0;
|
||||
break;
|
||||
case kCenter_SpacingAlign:
|
||||
y = SkScalarHalf(height - textHeight);
|
||||
break;
|
||||
default:
|
||||
SkASSERT(fSpacingAlign == kEnd_SpacingAlign);
|
||||
y = height - textHeight;
|
||||
break;
|
||||
}
|
||||
y += fBox.fTop - metrics.fAscent;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
size_t trailing;
|
||||
len = linebreak(text, textStop, paint, marginWidth, &trailing);
|
||||
if (y + metrics.fDescent + metrics.fLeading > 0) {
|
||||
visitor(text, len - trailing, x, y, paint);
|
||||
}
|
||||
text += len;
|
||||
if (text >= textStop) {
|
||||
break;
|
||||
}
|
||||
y += scaledSpacing;
|
||||
if (y + metrics.fAscent >= fBox.fBottom) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return y + metrics.fDescent + metrics.fLeading;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CanvasVisitor : public SkTextBox::Visitor {
|
||||
SkCanvas* fCanvas;
|
||||
public:
|
||||
CanvasVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
|
||||
|
||||
void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) override {
|
||||
fCanvas->drawText(text, length, x, y, paint);
|
||||
}
|
||||
};
|
||||
|
||||
void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
|
||||
fText = text;
|
||||
fLen = len;
|
||||
fPaint = &paint;
|
||||
}
|
||||
|
||||
void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint) {
|
||||
CanvasVisitor sink(canvas);
|
||||
this->visit(sink, text, len, paint);
|
||||
}
|
||||
|
||||
void SkTextBox::draw(SkCanvas* canvas) {
|
||||
this->draw(canvas, fText, fLen, *fPaint);
|
||||
}
|
||||
|
||||
int SkTextBox::countLines() const {
|
||||
return SkTextLineBreaker::CountLines(fText, fLen, *fPaint, fBox.width());
|
||||
}
|
||||
|
||||
SkScalar SkTextBox::getTextHeight() const {
|
||||
SkScalar spacing = fPaint->getTextSize() * fSpacingMul + fSpacingAdd;
|
||||
return this->countLines() * spacing;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkTextBlob.h"
|
||||
|
||||
class TextBlobVisitor : public SkTextBox::Visitor {
|
||||
public:
|
||||
SkTextBlobBuilder fBuilder;
|
||||
|
||||
void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) override {
|
||||
SkPaint p(paint);
|
||||
p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||
const int count = paint.countText(text, length);
|
||||
paint.textToGlyphs(text, length, fBuilder.allocRun(p, count, x, y).glyphs);
|
||||
}
|
||||
};
|
||||
|
||||
sk_sp<SkTextBlob> SkTextBox::snapshotTextBlob(SkScalar* computedBottom) const {
|
||||
TextBlobVisitor visitor;
|
||||
SkScalar newB = this->visit(visitor, fText, fLen, *fPaint);
|
||||
if (computedBottom) {
|
||||
*computedBottom = newB;
|
||||
}
|
||||
return visitor.fBuilder.make();
|
||||
}
|
Loading…
Reference in New Issue
Block a user