font/basicfont: add Descent and Left fields.

A face's glyph height (the height of the glyph image) isn't necessarily
the inter-line spacing: f.Ascent + f.Descent isn't always f.Height.

Similarly, a face's glyph image's left side isn't always dot.X.

Change-Id: I86594c52b8d31bf652ac34a695e9270ac635a5bc
Reviewed-on: https://go-review.googlesource.com/24481
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/font/basicfont/basicfont.go b/font/basicfont/basicfont.go
index c6b2b68..1acc79f 100644
--- a/font/basicfont/basicfont.go
+++ b/font/basicfont/basicfont.go
@@ -19,8 +19,8 @@
 // exclusive on the high end.
 //
 // If Low <= r && r < High, then the rune r is mapped to the sub-image of
-// Face.Mask whose bounds are image.Rect(0, y, Face.Width, y+Face.Height),
-// where y equals (int(r-Low) + Offset) * Face.Height.
+// Face.Mask whose bounds are image.Rect(0, y*h, Face.Width, (y+1)*h),
+// where y = (int(r-Low) + Offset) and h = (Face.Ascent + Face.Descent).
 type Range struct {
 	Low, High rune
 	Offset    int
@@ -38,6 +38,7 @@
 	Width:   6,
 	Height:  13,
 	Ascent:  11,
+	Descent: 2,
 	Mask:    mask7x13,
 	Ranges: []Range{
 		{'\u0020', '\u007f', 0},
@@ -53,12 +54,15 @@
 	Advance int
 	// Width is the glyph width, in pixels.
 	Width int
-	// Height is the glyph height, in pixels.
+	// Height is the inter-line height, in pixels.
 	Height int
 	// Ascent is the glyph ascent, in pixels.
 	Ascent int
-
-	// TODO: do we also need Top and Left fields?
+	// Descent is the glyph descent, in pixels.
+	Descent int
+	// Left is the left side bearing, in pixels. A positive value means that
+	// all of a glyph is to the right of the dot.
+	Left int
 
 	// Mask contains all of the glyph masks. Its width is typically the Face's
 	// Width, and its height a multiple of the Face's Height.
@@ -75,7 +79,7 @@
 	return font.Metrics{
 		Height:  fixed.I(f.Height),
 		Ascent:  fixed.I(f.Ascent),
-		Descent: fixed.I(f.Height - f.Ascent),
+		Descent: fixed.I(f.Descent),
 	}
 }
 
@@ -88,7 +92,7 @@
 			if rr < rng.Low || rng.High <= rr {
 				continue
 			}
-			maskp.Y = (int(rr-rng.Low) + rng.Offset) * f.Height
+			maskp.Y = (int(rr-rng.Low) + rng.Offset) * (f.Ascent + f.Descent)
 			ok = true
 			break loop
 		}
@@ -97,16 +101,16 @@
 		return image.Rectangle{}, nil, image.Point{}, 0, false
 	}
 
-	minX := int(dot.X+32) >> 6
-	minY := int(dot.Y+32)>>6 - f.Ascent
+	x := int(dot.X+32)>>6 + f.Left
+	y := int(dot.Y+32) >> 6
 	dr = image.Rectangle{
 		Min: image.Point{
-			X: minX,
-			Y: minY,
+			X: x,
+			Y: y - f.Ascent,
 		},
 		Max: image.Point{
-			X: minX + f.Width,
-			Y: minY + f.Height,
+			X: x + f.Width,
+			Y: y + f.Descent,
 		},
 	}
 
@@ -114,7 +118,7 @@
 }
 
 func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
-	return fixed.R(0, -f.Ascent, f.Width, -f.Ascent+f.Height), fixed.I(f.Advance), true
+	return fixed.R(0, -f.Ascent, f.Width, +f.Descent), fixed.I(f.Advance), true
 }
 
 func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {