add paint::getFontBounds()
authorreed <reed@google.com>
Mon, 15 Dec 2014 21:27:26 +0000 (13:27 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 15 Dec 2014 21:27:26 +0000 (13:27 -0800)
BUG=skia:

Review URL: https://codereview.chromium.org/804903006

gm/fontmgr.cpp
include/core/SkPaint.h
src/core/SkPaint.cpp

index 99cff6e..865090a 100644 (file)
     #include "SkTypeface_win.h"
 #endif
 
-static void scale(SkRect* rect, SkScalar scale) {
-    rect->fLeft *= scale;
-    rect->fTop *= scale;
-    rect->fRight *= scale;
-    rect->fBottom *= scale;
-}
-
 // limit this just so we don't take too long to draw
 #define MAX_FAMILIES    30
 
@@ -233,8 +226,14 @@ private:
 
 class FontMgrBoundsGM : public skiagm::GM {
 public:
-    FontMgrBoundsGM() {
+    FontMgrBoundsGM(double scale, double skew)
+        : fScaleX(SkDoubleToScalar(scale))
+        , fSkewX(SkDoubleToScalar(skew))
+    {
         fName.set("fontmgr_bounds");
+        if (scale != 1 || skew != 0) {
+            fName.appendf("_%g_%g", scale, skew);
+        }
         fFM.reset(SkFontMgr::RefDefault());
     }
 
@@ -242,13 +241,11 @@ public:
                             SkColor boundsColor) {
         const char str[] = "jyHO[]{}@-_&%$";
 
-        const SkTypeface* tf = paint.getTypeface();
         for (int i = 0; str[i]; ++i) {
             canvas->drawText(&str[i], 1, x, y, paint);
         }
         
-        SkRect r = tf->getBounds();
-        scale(&r, paint.getTextSize());
+        SkRect r = paint.getFontBounds();
         r.offset(x, y);
         SkPaint p(paint);
         p.setColor(boundsColor);
@@ -270,6 +267,8 @@ protected:
         paint.setSubpixelText(true);
         paint.setTextSize(100);
         paint.setStyle(SkPaint::kStroke_Style);
+        paint.setTextScaleX(fScaleX);
+        paint.setTextSkewX(fSkewX);
 
         const SkColor boundsColors[2] = { SK_ColorRED, SK_ColorBLUE };
         
@@ -314,14 +313,17 @@ protected:
 private:
     SkAutoTUnref<SkFontMgr> fFM;
     SkString fName;
+    SkScalar fScaleX, fSkewX;
     typedef GM INHERITED;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
 DEF_GM( return SkNEW(FontMgrGM); )
-DEF_GM( return SkNEW(FontMgrBoundsGM); )
 DEF_GM( return SkNEW(FontMgrMatchGM); )
+DEF_GM( return SkNEW(FontMgrBoundsGM(1.0, 0)); )
+DEF_GM( return SkNEW(FontMgrBoundsGM(0.75, 0)); )
+DEF_GM( return SkNEW(FontMgrBoundsGM(1.0, -0.25)); )
 
 #ifdef SK_BUILD_FOR_WIN
     DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite())); )
index 464c6b2..68220f6 100644 (file)
@@ -921,6 +921,14 @@ public:
     void getPosTextPath(const void* text, size_t length,
                         const SkPoint pos[], SkPath* path) const;
 
+    /**
+     *  Return a rectangle that represents the union of the bounds of all
+     *  of the glyphs, but each one positioned at (0,0). This may be conservatively large, and
+     *  will not take into account any hinting, but will respect any text-scale-x or text-skew-x
+     *  on this paint.
+     */
+    SkRect getFontBounds() const;
+
     // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
     // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
     bool nothingToDraw() const;
index 162988b..ff08a0a 100644 (file)
@@ -1237,6 +1237,21 @@ void SkPaint::getPosTextPath(const void* textData, size_t length,
     }
 }
 
+SkRect SkPaint::getFontBounds() const {
+    SkMatrix m;
+    m.setScale(fTextSize * fTextScaleX, fTextSize);
+    m.postSkew(fTextSkewX, 0);
+
+    SkTypeface* typeface = this->getTypeface();
+    if (NULL == typeface) {
+        typeface = SkTypeface::GetDefaultTypeface();
+    }
+
+    SkRect bounds;
+    m.mapRect(&bounds, typeface->getBounds());
+    return bounds;
+}
+
 static void add_flattenable(SkDescriptor* desc, uint32_t tag,
                             SkWriteBuffer* buffer) {
     buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), NULL));