hide paint's getFontBounds
Bug: skia: Change-Id: I26b693e32d0dadfe47710a29296eceb8ec90ee0c Reviewed-on: https://skia-review.googlesource.com/c/174308 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
parent
5138990abe
commit
7d1eb33aec
@ -98,6 +98,8 @@ private:
|
|||||||
DEF_GM( return new DrawAtlasGM; )
|
DEF_GM( return new DrawAtlasGM; )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include "SkFont.h"
|
||||||
|
#include "SkFontPriv.h"
|
||||||
#include "SkPath.h"
|
#include "SkPath.h"
|
||||||
#include "SkPathMeasure.h"
|
#include "SkPathMeasure.h"
|
||||||
|
|
||||||
@ -106,16 +108,18 @@ static void draw_text_on_path(SkCanvas* canvas, const void* text, size_t length,
|
|||||||
float baseline_offset) {
|
float baseline_offset) {
|
||||||
SkPathMeasure meas(path, false);
|
SkPathMeasure meas(path, false);
|
||||||
|
|
||||||
int count = paint.countText(text, length);
|
SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
|
||||||
|
|
||||||
|
int count = font.countText(text, length, kUTF8_SkTextEncoding);
|
||||||
size_t size = count * (sizeof(SkRSXform) + sizeof(SkScalar));
|
size_t size = count * (sizeof(SkRSXform) + sizeof(SkScalar));
|
||||||
SkAutoSMalloc<512> storage(size);
|
SkAutoSMalloc<512> storage(size);
|
||||||
SkRSXform* xform = (SkRSXform*)storage.get();
|
SkRSXform* xform = (SkRSXform*)storage.get();
|
||||||
SkScalar* widths = (SkScalar*)(xform + count);
|
SkScalar* widths = (SkScalar*)(xform + count);
|
||||||
|
|
||||||
// Compute a conservative bounds so we can cull the draw
|
// Compute a conservative bounds so we can cull the draw
|
||||||
const SkRect font = paint.getFontBounds();
|
const SkRect fontb = SkFontPriv::GetFontBounds(font);
|
||||||
const SkScalar max = SkTMax(SkTMax(SkScalarAbs(font.fLeft), SkScalarAbs(font.fRight)),
|
const SkScalar max = SkTMax(SkTMax(SkScalarAbs(fontb.fLeft), SkScalarAbs(fontb.fRight)),
|
||||||
SkTMax(SkScalarAbs(font.fTop), SkScalarAbs(font.fBottom)));
|
SkTMax(SkScalarAbs(fontb.fTop), SkScalarAbs(fontb.fBottom)));
|
||||||
const SkRect bounds = path.getBounds().makeOutset(max, max);
|
const SkRect bounds = path.getBounds().makeOutset(max, max);
|
||||||
|
|
||||||
paint.getTextWidths(text, length, widths);
|
paint.getTextWidths(text, length, widths);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkCommonFlags.h"
|
#include "SkCommonFlags.h"
|
||||||
#include "SkFontMgr.h"
|
#include "SkFontMgr.h"
|
||||||
|
#include "SkFontPriv.h"
|
||||||
#include "SkPath.h"
|
#include "SkPath.h"
|
||||||
#include "SkGraphics.h"
|
#include "SkGraphics.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
@ -218,19 +219,19 @@ public:
|
|||||||
fFM = SkFontMgr::RefDefault();
|
fFM = SkFontMgr::RefDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_bounds(SkCanvas* canvas, const SkPaint& paint, SkScalar x, SkScalar y,
|
static void show_bounds(SkCanvas* canvas, const SkFont& font, SkScalar x, SkScalar y,
|
||||||
SkColor boundsColor)
|
SkColor boundsColor)
|
||||||
{
|
{
|
||||||
SkPaint glyphPaint(paint);
|
SkRect fontBounds = SkFontPriv::GetFontBounds(font).makeOffset(x, y);
|
||||||
SkRect fontBounds = glyphPaint.getFontBounds();
|
|
||||||
fontBounds.offset(x, y);
|
SkPaint boundsPaint;
|
||||||
SkPaint boundsPaint(glyphPaint);
|
boundsPaint.setAntiAlias(true);
|
||||||
boundsPaint.setColor(boundsColor);
|
boundsPaint.setColor(boundsColor);
|
||||||
boundsPaint.setStyle(SkPaint::kStroke_Style);
|
boundsPaint.setStyle(SkPaint::kStroke_Style);
|
||||||
canvas->drawRect(fontBounds, boundsPaint);
|
canvas->drawRect(fontBounds, boundsPaint);
|
||||||
|
|
||||||
SkFontMetrics fm;
|
SkFontMetrics fm;
|
||||||
glyphPaint.getFontMetrics(&fm);
|
font.getMetrics(&fm);
|
||||||
SkPaint metricsPaint(boundsPaint);
|
SkPaint metricsPaint(boundsPaint);
|
||||||
metricsPaint.setStyle(SkPaint::kFill_Style);
|
metricsPaint.setStyle(SkPaint::kFill_Style);
|
||||||
metricsPaint.setAlpha(0x40);
|
metricsPaint.setAlpha(0x40);
|
||||||
@ -252,13 +253,12 @@ public:
|
|||||||
|
|
||||||
SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
|
SkGlyphID left = 0, right = 0, top = 0, bottom = 0;
|
||||||
{
|
{
|
||||||
int numGlyphs = glyphPaint.getTypeface()->countGlyphs();
|
int numGlyphs = font.getTypeface()->countGlyphs();
|
||||||
SkRect min = {0, 0, 0, 0};
|
SkRect min = {0, 0, 0, 0};
|
||||||
glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
|
|
||||||
for (int i = 0; i < numGlyphs; ++i) {
|
for (int i = 0; i < numGlyphs; ++i) {
|
||||||
SkGlyphID glyphId = i;
|
SkGlyphID glyphId = i;
|
||||||
SkRect cur;
|
SkRect cur;
|
||||||
glyphPaint.measureText(&glyphId, sizeof(glyphId), &cur);
|
font.getBounds(&glyphId, 1, &cur, nullptr);
|
||||||
if (cur.fLeft < min.fLeft ) { min.fLeft = cur.fLeft; left = i; }
|
if (cur.fLeft < min.fLeft ) { min.fLeft = cur.fLeft; left = i; }
|
||||||
if (cur.fTop < min.fTop ) { min.fTop = cur.fTop ; top = i; }
|
if (cur.fTop < min.fTop ) { min.fTop = cur.fTop ; top = i; }
|
||||||
if (min.fRight < cur.fRight ) { min.fRight = cur.fRight; right = i; }
|
if (min.fRight < cur.fRight ) { min.fRight = cur.fRight; right = i; }
|
||||||
@ -273,27 +273,30 @@ public:
|
|||||||
{fontBounds.centerX(), fontBounds.bottom()}
|
{fontBounds.centerX(), fontBounds.bottom()}
|
||||||
};
|
};
|
||||||
|
|
||||||
SkPaint labelPaint;
|
SkFont labelFont;
|
||||||
labelPaint.setAntiAlias(true);
|
labelFont.setEdging(SkFont::Edging::kAntiAlias);
|
||||||
sk_tool_utils::set_portable_typeface(&labelPaint);
|
labelFont.setTypeface(sk_tool_utils::create_portable_typeface());
|
||||||
|
|
||||||
if (FLAGS_veryVerbose) {
|
if (FLAGS_veryVerbose) {
|
||||||
SkString name;
|
SkString name;
|
||||||
paint.getTypeface()->getFamilyName(&name);
|
font.getTypeface()->getFamilyName(&name);
|
||||||
canvas->drawText(name.c_str(), name.size(),
|
canvas->drawSimpleText(name.c_str(), name.size(), kUTF8_SkTextEncoding,
|
||||||
fontBounds.fLeft, fontBounds.fBottom, labelPaint);
|
fontBounds.fLeft, fontBounds.fBottom, labelFont, SkPaint());
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
|
for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
|
||||||
SkPath path;
|
SkPath path;
|
||||||
glyphPaint.getTextPath(&str[i], sizeof(str[0]), x, y, &path);
|
font.getPath(str[i], &path);
|
||||||
|
path.offset(x, y);
|
||||||
SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
|
SkPaint::Style style = path.isEmpty() ? SkPaint::kFill_Style : SkPaint::kStroke_Style;
|
||||||
|
SkPaint glyphPaint;
|
||||||
glyphPaint.setStyle(style);
|
glyphPaint.setStyle(style);
|
||||||
canvas->drawText(&str[i], sizeof(str[0]), x, y, glyphPaint);
|
canvas->drawSimpleText(&str[i], sizeof(str[0]), kGlyphID_SkTextEncoding, x, y, font, glyphPaint);
|
||||||
|
|
||||||
if (FLAGS_veryVerbose) {
|
if (FLAGS_veryVerbose) {
|
||||||
SkString glyphStr;
|
SkString glyphStr;
|
||||||
glyphStr.appendS32(str[i]);
|
glyphStr.appendS32(str[i]);
|
||||||
canvas->drawText(glyphStr.c_str(), glyphStr.size(),
|
canvas->drawSimpleText(glyphStr.c_str(), glyphStr.size(), kUTF8_SkTextEncoding,
|
||||||
location[i].fX, location[i].fY, labelPaint);
|
location[i].fX, location[i].fY, labelFont, SkPaint());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -310,12 +313,12 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onDraw(SkCanvas* canvas) override {
|
void onDraw(SkCanvas* canvas) override {
|
||||||
SkPaint paint;
|
SkFont font;
|
||||||
paint.setAntiAlias(true);
|
font.setEdging(SkFont::Edging::kAntiAlias);
|
||||||
paint.setSubpixelText(true);
|
font.setSubpixel(true);
|
||||||
paint.setTextSize(100);
|
font.setSize(100);
|
||||||
paint.setTextScaleX(fScaleX);
|
font.setScaleX(fScaleX);
|
||||||
paint.setTextSkewX(fSkewX);
|
font.setSkewX(fSkewX);
|
||||||
|
|
||||||
const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
|
const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
|
||||||
|
|
||||||
@ -330,13 +333,13 @@ protected:
|
|||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
|
sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
|
||||||
for (int j = 0; j < set->count() && j < 3; ++j) {
|
for (int j = 0; j < set->count() && j < 3; ++j) {
|
||||||
paint.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
|
font.setTypeface(sk_sp<SkTypeface>(set->createTypeface(j)));
|
||||||
// Fonts with lots of glyphs are interesting, but can take a long time to find
|
// Fonts with lots of glyphs are interesting, but can take a long time to find
|
||||||
// the glyphs which make up the maximum extent.
|
// the glyphs which make up the maximum extent.
|
||||||
if (paint.getTypeface() && paint.getTypeface()->countGlyphs() < 1000) {
|
if (font.getTypeface() && font.getTypeface()->countGlyphs() < 1000) {
|
||||||
SkRect fontBounds = paint.getFontBounds();
|
SkRect fontBounds = SkFontPriv::GetFontBounds(font);
|
||||||
x -= fontBounds.fLeft;
|
x -= fontBounds.fLeft;
|
||||||
show_bounds(canvas, paint, x, y, boundsColors[index & 1]);
|
show_bounds(canvas, font, x, y, boundsColors[index & 1]);
|
||||||
x += fontBounds.fRight + 20;
|
x += fontBounds.fRight + 20;
|
||||||
index += 1;
|
index += 1;
|
||||||
if (x > 900) {
|
if (x > 900) {
|
||||||
|
@ -975,18 +975,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
SkScalar getFontSpacing() const { return this->getFontMetrics(nullptr); }
|
SkScalar getFontSpacing() const { return this->getFontMetrics(nullptr); }
|
||||||
|
|
||||||
/** Returns the union of bounds of all glyphs.
|
|
||||||
Returned dimensions are computed by font manager from font data,
|
|
||||||
ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
|
|
||||||
|
|
||||||
If text size is large, text scale is one, and text skew is zero,
|
|
||||||
returns the bounds as:
|
|
||||||
{ SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
|
|
||||||
|
|
||||||
@return union of bounds of all glyphs
|
|
||||||
*/
|
|
||||||
SkRect getFontBounds() const;
|
|
||||||
|
|
||||||
/** Converts text into glyph indices.
|
/** Converts text into glyph indices.
|
||||||
Returns the number of glyph indices represented by text.
|
Returns the number of glyph indices represented by text.
|
||||||
SkTextEncoding specifies how text represents characters or glyphs.
|
SkTextEncoding specifies how text represents characters or glyphs.
|
||||||
|
@ -2530,13 +2530,14 @@ void SkCanvas::drawString(const SkString& string, SkScalar x, SkScalar y, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// These call the (virtual) onDraw... method
|
// These call the (virtual) onDraw... method
|
||||||
void SkCanvas::drawSimpleText(const void* text, size_t byteLength, SkTextEncoding,
|
void SkCanvas::drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
|
||||||
SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint) {
|
SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint) {
|
||||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||||
if (byteLength) {
|
if (byteLength) {
|
||||||
sk_msan_assert_initialized(text, SkTAddOffset<const void>(text, byteLength));
|
sk_msan_assert_initialized(text, SkTAddOffset<const void>(text, byteLength));
|
||||||
SkPaint tmp(paint);
|
SkPaint tmp(paint);
|
||||||
font.LEGACY_applyToPaint(&tmp);
|
font.LEGACY_applyToPaint(&tmp);
|
||||||
|
tmp.setTextEncoding(encoding);
|
||||||
this->onDrawText(text, byteLength, x, y, tmp);
|
this->onDrawText(text, byteLength, x, y, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,3 +527,18 @@ void SkFont::LEGACY_applyPaintFlags(uint32_t paintFlags) {
|
|||||||
}
|
}
|
||||||
this->setEdging(edging);
|
this->setEdging(edging);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SkRect SkFontPriv::GetFontBounds(const SkFont& font) {
|
||||||
|
SkMatrix m;
|
||||||
|
m.setScale(font.getSize() * font.getScaleX(), font.getSize());
|
||||||
|
m.postSkew(font.getSkewX(), 0);
|
||||||
|
|
||||||
|
SkTypeface* typeface = SkFontPriv::GetTypefaceOrDefault(font);
|
||||||
|
|
||||||
|
SkRect bounds;
|
||||||
|
m.mapRect(&bounds, typeface->getBounds());
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,19 @@ public:
|
|||||||
typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**, const char*);
|
typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**, const char*);
|
||||||
|
|
||||||
static GlyphCacheProc GetGlyphCacheProc(SkTextEncoding encoding, bool needFullMetrics);
|
static GlyphCacheProc GetGlyphCacheProc(SkTextEncoding encoding, bool needFullMetrics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the union of bounds of all glyphs.
|
||||||
|
Returned dimensions are computed by font manager from font data,
|
||||||
|
ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
|
||||||
|
|
||||||
|
If text size is large, text scale is one, and text skew is zero,
|
||||||
|
returns the bounds as:
|
||||||
|
{ SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
|
||||||
|
|
||||||
|
@return union of bounds of all glyphs
|
||||||
|
*/
|
||||||
|
static SkRect GetFontBounds(const SkFont&);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkAutoToGlyphs {
|
class SkAutoToGlyphs {
|
||||||
|
@ -541,18 +541,6 @@ int SkPaint::getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkRect SkPaint::getFontBounds() const {
|
|
||||||
SkMatrix m;
|
|
||||||
m.setScale(fTextSize * fTextScaleX, fTextSize);
|
|
||||||
m.postSkew(fTextSkewX, 0);
|
|
||||||
|
|
||||||
SkTypeface* typeface = SkPaintPriv::GetTypefaceOrDefault(*this);
|
|
||||||
|
|
||||||
SkRect bounds;
|
|
||||||
m.mapRect(&bounds, typeface->getBounds());
|
|
||||||
return bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if the paint is just a single color (i.e. not a shader). If its
|
// return true if the paint is just a single color (i.e. not a shader). If its
|
||||||
// a shader, then we can't compute a const luminance for it :(
|
// a shader, then we can't compute a const luminance for it :(
|
||||||
static bool just_a_color(const SkPaint& paint, SkColor* color) {
|
static bool just_a_color(const SkPaint& paint, SkColor* color) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
|
#include "SkFontPriv.h"
|
||||||
#include "SkGlyphRun.h"
|
#include "SkGlyphRun.h"
|
||||||
#include "SkPaintPriv.h"
|
#include "SkPaintPriv.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
@ -328,7 +328,8 @@ SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run
|
|||||||
|
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
run.font().applyToPaint(&paint);
|
run.font().applyToPaint(&paint);
|
||||||
const SkRect fontBounds = paint.getFontBounds();
|
SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
|
||||||
|
const SkRect fontBounds = SkFontPriv::GetFontBounds(font);
|
||||||
if (fontBounds.isEmpty()) {
|
if (fontBounds.isEmpty()) {
|
||||||
// Empty font bounds are likely a font bug. TightBounds has a better chance of
|
// Empty font bounds are likely a font bug. TightBounds has a better chance of
|
||||||
// producing useful results in this case.
|
// producing useful results in this case.
|
||||||
|
Loading…
Reference in New Issue
Block a user