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; )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "SkFont.h"
|
||||
#include "SkFontPriv.h"
|
||||
#include "SkPath.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) {
|
||||
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));
|
||||
SkAutoSMalloc<512> storage(size);
|
||||
SkRSXform* xform = (SkRSXform*)storage.get();
|
||||
SkScalar* widths = (SkScalar*)(xform + count);
|
||||
|
||||
// Compute a conservative bounds so we can cull the draw
|
||||
const SkRect font = paint.getFontBounds();
|
||||
const SkScalar max = SkTMax(SkTMax(SkScalarAbs(font.fLeft), SkScalarAbs(font.fRight)),
|
||||
SkTMax(SkScalarAbs(font.fTop), SkScalarAbs(font.fBottom)));
|
||||
const SkRect fontb = SkFontPriv::GetFontBounds(font);
|
||||
const SkScalar max = SkTMax(SkTMax(SkScalarAbs(fontb.fLeft), SkScalarAbs(fontb.fRight)),
|
||||
SkTMax(SkScalarAbs(fontb.fTop), SkScalarAbs(fontb.fBottom)));
|
||||
const SkRect bounds = path.getBounds().makeOutset(max, max);
|
||||
|
||||
paint.getTextWidths(text, length, widths);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "SkCanvas.h"
|
||||
#include "SkCommonFlags.h"
|
||||
#include "SkFontMgr.h"
|
||||
#include "SkFontPriv.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkTypeface.h"
|
||||
@ -218,19 +219,19 @@ public:
|
||||
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)
|
||||
{
|
||||
SkPaint glyphPaint(paint);
|
||||
SkRect fontBounds = glyphPaint.getFontBounds();
|
||||
fontBounds.offset(x, y);
|
||||
SkPaint boundsPaint(glyphPaint);
|
||||
SkRect fontBounds = SkFontPriv::GetFontBounds(font).makeOffset(x, y);
|
||||
|
||||
SkPaint boundsPaint;
|
||||
boundsPaint.setAntiAlias(true);
|
||||
boundsPaint.setColor(boundsColor);
|
||||
boundsPaint.setStyle(SkPaint::kStroke_Style);
|
||||
canvas->drawRect(fontBounds, boundsPaint);
|
||||
|
||||
SkFontMetrics fm;
|
||||
glyphPaint.getFontMetrics(&fm);
|
||||
font.getMetrics(&fm);
|
||||
SkPaint metricsPaint(boundsPaint);
|
||||
metricsPaint.setStyle(SkPaint::kFill_Style);
|
||||
metricsPaint.setAlpha(0x40);
|
||||
@ -252,13 +253,12 @@ public:
|
||||
|
||||
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};
|
||||
glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
|
||||
for (int i = 0; i < numGlyphs; ++i) {
|
||||
SkGlyphID glyphId = i;
|
||||
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.fTop < min.fTop ) { min.fTop = cur.fTop ; top = i; }
|
||||
if (min.fRight < cur.fRight ) { min.fRight = cur.fRight; right = i; }
|
||||
@ -273,27 +273,30 @@ public:
|
||||
{fontBounds.centerX(), fontBounds.bottom()}
|
||||
};
|
||||
|
||||
SkPaint labelPaint;
|
||||
labelPaint.setAntiAlias(true);
|
||||
sk_tool_utils::set_portable_typeface(&labelPaint);
|
||||
SkFont labelFont;
|
||||
labelFont.setEdging(SkFont::Edging::kAntiAlias);
|
||||
labelFont.setTypeface(sk_tool_utils::create_portable_typeface());
|
||||
|
||||
if (FLAGS_veryVerbose) {
|
||||
SkString name;
|
||||
paint.getTypeface()->getFamilyName(&name);
|
||||
canvas->drawText(name.c_str(), name.size(),
|
||||
fontBounds.fLeft, fontBounds.fBottom, labelPaint);
|
||||
font.getTypeface()->getFamilyName(&name);
|
||||
canvas->drawSimpleText(name.c_str(), name.size(), kUTF8_SkTextEncoding,
|
||||
fontBounds.fLeft, fontBounds.fBottom, labelFont, SkPaint());
|
||||
}
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(str); ++i) {
|
||||
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 glyphPaint;
|
||||
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) {
|
||||
SkString glyphStr;
|
||||
glyphStr.appendS32(str[i]);
|
||||
canvas->drawText(glyphStr.c_str(), glyphStr.size(),
|
||||
location[i].fX, location[i].fY, labelPaint);
|
||||
canvas->drawSimpleText(glyphStr.c_str(), glyphStr.size(), kUTF8_SkTextEncoding,
|
||||
location[i].fX, location[i].fY, labelFont, SkPaint());
|
||||
}
|
||||
|
||||
}
|
||||
@ -310,12 +313,12 @@ protected:
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setSubpixelText(true);
|
||||
paint.setTextSize(100);
|
||||
paint.setTextScaleX(fScaleX);
|
||||
paint.setTextSkewX(fSkewX);
|
||||
SkFont font;
|
||||
font.setEdging(SkFont::Edging::kAntiAlias);
|
||||
font.setSubpixel(true);
|
||||
font.setSize(100);
|
||||
font.setScaleX(fScaleX);
|
||||
font.setSkewX(fSkewX);
|
||||
|
||||
const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
|
||||
|
||||
@ -330,13 +333,13 @@ protected:
|
||||
for (int i = 0; i < count; ++i) {
|
||||
sk_sp<SkFontStyleSet> set(fm->createStyleSet(i));
|
||||
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
|
||||
// the glyphs which make up the maximum extent.
|
||||
if (paint.getTypeface() && paint.getTypeface()->countGlyphs() < 1000) {
|
||||
SkRect fontBounds = paint.getFontBounds();
|
||||
if (font.getTypeface() && font.getTypeface()->countGlyphs() < 1000) {
|
||||
SkRect fontBounds = SkFontPriv::GetFontBounds(font);
|
||||
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;
|
||||
index += 1;
|
||||
if (x > 900) {
|
||||
|
@ -975,18 +975,6 @@ public:
|
||||
*/
|
||||
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.
|
||||
Returns the number of glyph indices represented by text.
|
||||
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
|
||||
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) {
|
||||
TRACE_EVENT0("skia", TRACE_FUNC);
|
||||
if (byteLength) {
|
||||
sk_msan_assert_initialized(text, SkTAddOffset<const void>(text, byteLength));
|
||||
SkPaint tmp(paint);
|
||||
font.LEGACY_applyToPaint(&tmp);
|
||||
tmp.setTextEncoding(encoding);
|
||||
this->onDrawText(text, byteLength, x, y, tmp);
|
||||
}
|
||||
}
|
||||
|
@ -527,3 +527,18 @@ void SkFont::LEGACY_applyPaintFlags(uint32_t paintFlags) {
|
||||
}
|
||||
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*);
|
||||
|
||||
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 {
|
||||
|
@ -541,18 +541,6 @@ int SkPaint::getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds
|
||||
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
|
||||
// a shader, then we can't compute a const luminance for it :(
|
||||
static bool just_a_color(const SkPaint& paint, SkColor* color) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "SkTextBlob.h"
|
||||
|
||||
#include "SkFontPriv.h"
|
||||
#include "SkGlyphRun.h"
|
||||
#include "SkPaintPriv.h"
|
||||
#include "SkReadBuffer.h"
|
||||
@ -328,7 +328,8 @@ SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run
|
||||
|
||||
SkPaint 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()) {
|
||||
// Empty font bounds are likely a font bug. TightBounds has a better chance of
|
||||
// producing useful results in this case.
|
||||
|
Loading…
Reference in New Issue
Block a user