| Index: src/core/SkTypeface.cpp | 
| diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp | 
| index 84cbdbfe6643b034374f97231604b1ce5b8c82a2..c537d4aa2d8c46e9d78de06c346f1e0e89094a16 100644 | 
| --- a/src/core/SkTypeface.cpp | 
| +++ b/src/core/SkTypeface.cpp | 
| @@ -278,9 +278,61 @@ SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics( | 
| return result; | 
| } | 
|  | 
| -/////////////////////////////////////////////////////////////////////////////// | 
| - | 
| bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count, | 
| int32_t adjustments[]) const { | 
| return false; | 
| } | 
| + | 
| +/////////////////////////////////////////////////////////////////////////////// | 
| + | 
| +#include "SkDescriptor.h" | 
| +#include "SkPaint.h" | 
| + | 
| +struct SkTypeface::BoundsComputer { | 
| +    const SkTypeface& fTypeface; | 
| + | 
| +    BoundsComputer(const SkTypeface& tf) : fTypeface(tf) {} | 
| + | 
| +    SkRect* operator()() const { | 
| +        SkRect* rect = SkNEW(SkRect); | 
| +        if (!fTypeface.onComputeBounds(rect)) { | 
| +            rect->setEmpty(); | 
| +        } | 
| +        return rect; | 
| +    } | 
| +}; | 
| + | 
| +SkRect SkTypeface::getBounds() const { | 
| +    return *fLazyBounds.get(BoundsComputer(*this)); | 
| +} | 
| + | 
| +bool SkTypeface::onComputeBounds(SkRect* bounds) const { | 
| +    // we use a big size to ensure lots of significant bits from the scalercontext. | 
| +    // then we scale back down to return our final answer (at 1-pt) | 
| +    const SkScalar textSize = 2048; | 
| +    const SkScalar invTextSize = 1 / textSize; | 
| + | 
| +    SkPaint paint; | 
| +    paint.setTypeface(const_cast<SkTypeface*>(this)); | 
| +    paint.setTextSize(textSize); | 
| +    paint.setLinearText(true); | 
| + | 
| +    SkScalerContext::Rec rec; | 
| +    SkScalerContext::MakeRec(paint, NULL, NULL, &rec); | 
| + | 
| +    SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1)); | 
| +    SkDescriptor*    desc = ad.getDesc(); | 
| +    desc->init(); | 
| +    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); | 
| + | 
| +    SkAutoTDelete<SkScalerContext> ctx(this->createScalerContext(desc, true)); | 
| +    if (ctx.get()) { | 
| +        SkPaint::FontMetrics fm; | 
| +        ctx->getFontMetrics(&fm); | 
| +        bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize, | 
| +                    fm.fXMax * invTextSize, fm.fBottom * invTextSize); | 
| +        return true; | 
| +    } | 
| +    return false; | 
| +} | 
| + | 
|  |