Esempio n. 1
0
func (f *Face) Glyph(dot fixed.Point26_6, r rune) (
	dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {

loop:
	for _, rr := range [2]rune{r, '\ufffd'} {
		for _, rng := range f.Ranges {
			if rr < rng.Low || rng.High <= rr {
				continue
			}
			maskp.Y = (int(rr-rng.Low) + rng.Offset) * f.Height
			ok = true
			break loop
		}
	}
	if !ok {
		return image.Rectangle{}, nil, image.Point{}, 0, false
	}

	minX := int(dot.X+32) >> 6
	minY := int(dot.Y+32)>>6 - f.Ascent
	dr = image.Rectangle{
		Min: image.Point{
			X: minX,
			Y: minY,
		},
		Max: image.Point{
			X: minX + f.Width,
			Y: minY + f.Height,
		},
	}

	return dr, f.Mask, maskp, fixed.I(f.Advance), true
}
Esempio n. 2
0
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
}
Esempio n. 3
0
func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
	return fixed.I(f.Advance), true
}
Esempio n. 4
0
func testScaling(t *testing.T, h font.Hinting) {
	for _, tc := range scalingTestCases {
		f, testdataIsOptional, err := parseTestdataFont(tc.name)
		if err != nil {
			if testdataIsOptional {
				t.Log(err)
			} else {
				t.Error(err)
			}
			continue
		}
		hintingStr := "sans"
		if h != font.HintingNone {
			hintingStr = "with"
		}
		testFile, err := os.Open(fmt.Sprintf(
			"../testdata/%s-%dpt-%s-hinting.txt", tc.name, tc.size, hintingStr))
		if err != nil {
			t.Errorf("%s: Open: %v", tc.name, err)
			continue
		}
		defer testFile.Close()

		wants := []scalingTestData{}
		scanner := bufio.NewScanner(testFile)
		if scanner.Scan() {
			major, minor, patch := 0, 0, 0
			_, err := fmt.Sscanf(scanner.Text(), "freetype version %d.%d.%d", &major, &minor, &patch)
			if err != nil {
				t.Errorf("%s: version information: %v", tc.name, err)
			}
			if (major < 2) || (major == 2 && minor < 5) || (major == 2 && minor == 5 && patch < 1) {
				t.Errorf("%s: need freetype version >= 2.5.1.\n"+
					"Try setting LD_LIBRARY_PATH=/path/to/freetype_built_from_src/objs/.libs/\n"+
					"and re-running testdata/make-other-hinting-txts.sh",
					tc.name)
				continue
			}
		} else {
			t.Errorf("%s: no version information", tc.name)
			continue
		}
		for scanner.Scan() {
			wants = append(wants, scalingTestParse(scanner.Text()))
		}
		if err := scanner.Err(); err != nil && err != io.EOF {
			t.Errorf("%s: Scanner: %v", tc.name, err)
			continue
		}

		glyphBuf := &GlyphBuf{}
		for i, want := range wants {
			if err = glyphBuf.Load(f, fixed.I(tc.size), Index(i), h); err != nil {
				t.Errorf("%s: glyph #%d: Load: %v", tc.name, i, err)
				continue
			}
			got := scalingTestData{
				advanceWidth: glyphBuf.AdvanceWidth,
				bounds:       glyphBuf.Bounds,
				points:       glyphBuf.Points,
			}

			if got.advanceWidth != want.advanceWidth {
				t.Errorf("%s: glyph #%d advance width:\ngot  %v\nwant %v",
					tc.name, i, got.advanceWidth, want.advanceWidth)
				continue
			}

			if got.bounds != want.bounds {
				t.Errorf("%s: glyph #%d bounds:\ngot  %v\nwant %v",
					tc.name, i, got.bounds, want.bounds)
				continue
			}

			for i := range got.points {
				got.points[i].Flags &= 0x01
			}
			if len(got.points) != len(want.points) {
				t.Errorf("%s: glyph #%d:\ngot  %v\nwant %v\ndifferent slice lengths: %d versus %d",
					tc.name, i, got.points, want.points, len(got.points), len(want.points))
				continue
			}
			if j, equals := scalingTestEquals(got.points, want.points); !equals {
				t.Errorf("%s: glyph #%d:\ngot  %v\nwant %v\nat index %d: %v versus %v",
					tc.name, i, got.points, want.points, j, got.points[j], want.points[j])
				continue
			}
		}
	}
}