freetype: add script to create more hinting tests.
R=bsiegert, r CC=golang-dev https://codereview.appspot.com/14414044
This commit is contained in:
parent
b968fb0953
commit
b76427be47
4 changed files with 146 additions and 52 deletions
|
@ -1,27 +1,47 @@
|
|||
/*
|
||||
gcc main.c -I/usr/include/freetype2 -lfreetype && ./a.out
|
||||
gcc main.c -I/usr/include/freetype2 -lfreetype && ./a.out 12 ../../testdata/luxisr.ttf with_hinting
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
static int font_size = 12;
|
||||
static int no_hinting = 0;
|
||||
void usage(char** argv) {
|
||||
printf("usage: %s font_size font_file [with_hinting|sans_hinting]\n", argv[0]);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
FT_Error error;
|
||||
FT_Library library;
|
||||
FT_Face face;
|
||||
FT_Outline* o;
|
||||
int i, j;
|
||||
int i, j, font_size, no_hinting;
|
||||
|
||||
if (argc != 4) {
|
||||
usage(argv);
|
||||
return 1;
|
||||
}
|
||||
font_size = atoi(argv[1]);
|
||||
if (font_size <= 0) {
|
||||
printf("invalid font_size\n");
|
||||
usage(argv);
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[3], "with_hinting")) {
|
||||
no_hinting = 0;
|
||||
} else if (!strcmp(argv[3], "sans_hinting")) {
|
||||
no_hinting = 1;
|
||||
} else {
|
||||
printf("neither \"with_hinting\" nor \"sans_hinting\"\n");
|
||||
usage(argv);
|
||||
return 1;
|
||||
};
|
||||
error = FT_Init_FreeType(&library);
|
||||
if (error) {
|
||||
printf("FT_Init_FreeType: error #%d\n", error);
|
||||
return 1;
|
||||
}
|
||||
error = FT_New_Face(library, "../../testdata/luxisr.ttf", 0, &face);
|
||||
error = FT_New_Face(library, argv[2], 0, &face);
|
||||
if (error) {
|
||||
printf("FT_New_Face: error #%d\n", error);
|
||||
return 1;
|
||||
|
@ -50,4 +70,5 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -74,63 +74,106 @@ func TestParse(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func testScaling(t *testing.T, filename string, hinter *Hinter) {
|
||||
b, err := ioutil.ReadFile("../../testdata/luxisr.ttf")
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile: %v", err)
|
||||
}
|
||||
font, err := Parse(b)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse: %v", err)
|
||||
}
|
||||
f, err := os.Open("../../testdata/" + filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
var scalingTestCases = []struct {
|
||||
name string
|
||||
size int32
|
||||
// hintingBrokenAt, if non-negative, is the glyph index n for which
|
||||
// only the first n glyphs are known to be correctly hinted.
|
||||
// TODO: remove this field, when hinting is completely implemented.
|
||||
hintingBrokenAt int
|
||||
}{
|
||||
{"luxisr", 12, -1},
|
||||
// TODO: uncomment the fonts below, once they get past Parse and
|
||||
// GlyphBuf.Load, and the unhinted values match C Freetype.
|
||||
//{"x-arial-bold", 11, 0},
|
||||
//{"x-deja-vu-sans-oblique", 17, 0},
|
||||
//{"x-droid-sans-japanese", 9, 0},
|
||||
//{"x-inconsolata", 10, 0},
|
||||
//{"x-times-new-roman", 13, 0},
|
||||
}
|
||||
|
||||
wants := [][]Point{}
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
text := scanner.Text()
|
||||
if text == "" {
|
||||
wants = append(wants, []Point{})
|
||||
continue
|
||||
}
|
||||
ss := strings.Split(text, ",")
|
||||
points := make([]Point, len(ss))
|
||||
for i, s := range ss {
|
||||
p := &points[i]
|
||||
if _, err := fmt.Sscanf(s, "%d %d %d", &p.X, &p.Y, &p.Flags); err != nil {
|
||||
t.Fatalf("Sscanf: %v", err)
|
||||
func testScaling(t *testing.T, hinter *Hinter) {
|
||||
loop:
|
||||
for _, tc := range scalingTestCases {
|
||||
b, err := ioutil.ReadFile(fmt.Sprintf("../../testdata/%s.ttf", tc.name))
|
||||
if err != nil {
|
||||
// The "x-foo" fonts are optional tests, as they are not checked
|
||||
// in for copyright or file size reasons.
|
||||
if strings.HasPrefix(tc.name, "x-") {
|
||||
t.Logf("%s: ReadFile: %v", tc.name, err)
|
||||
} else {
|
||||
t.Errorf("%s: ReadFile: %v", tc.name, err)
|
||||
}
|
||||
continue loop
|
||||
}
|
||||
wants = append(wants, points)
|
||||
}
|
||||
if err := scanner.Err(); err != nil && err != io.EOF {
|
||||
t.Fatalf("Scanner: %v", err)
|
||||
}
|
||||
font, err := Parse(b)
|
||||
if err != nil {
|
||||
t.Errorf("%s: Parse: %v", tc.name, err)
|
||||
continue loop
|
||||
}
|
||||
hinting := "sans"
|
||||
if hinter != nil {
|
||||
hinting = "with"
|
||||
}
|
||||
f, err := os.Open(fmt.Sprintf(
|
||||
"../../testdata/%s-%dpt-%s-hinting.txt", tc.name, tc.size, hinting))
|
||||
if err != nil {
|
||||
t.Errorf("%s: Open: %v", tc.name, err)
|
||||
continue loop
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
const fontSize = 12
|
||||
glyphBuf := NewGlyphBuf()
|
||||
for i, want := range wants {
|
||||
if err = glyphBuf.Load(font, fontSize*64, Index(i), hinter); err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
wants := [][]Point{}
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
text := scanner.Text()
|
||||
if text == "" {
|
||||
wants = append(wants, []Point{})
|
||||
continue
|
||||
}
|
||||
ss := strings.Split(text, ",")
|
||||
points := make([]Point, len(ss))
|
||||
for i, s := range ss {
|
||||
p := &points[i]
|
||||
if _, err := fmt.Sscanf(s, "%d %d %d", &p.X, &p.Y, &p.Flags); err != nil {
|
||||
t.Errorf("%s: Sscanf: %v", tc.name, err)
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
wants = append(wants, points)
|
||||
}
|
||||
got := glyphBuf.Point
|
||||
for i := range got {
|
||||
got[i].Flags &= 0x01
|
||||
if err := scanner.Err(); err != nil && err != io.EOF {
|
||||
t.Errorf("%s: Scanner: %v", tc.name, err)
|
||||
continue loop
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("glyph #%d:\ngot %v\nwant %v\n", i, got, want)
|
||||
|
||||
glyphBuf := NewGlyphBuf()
|
||||
for i, want := range wants {
|
||||
// TODO: completely implement hinting. For now, only the first
|
||||
// tc.hintingBrokenAt glyphs of the test case's font are correctly hinted.
|
||||
if hinter != nil && i == tc.hintingBrokenAt {
|
||||
break
|
||||
}
|
||||
|
||||
if err = glyphBuf.Load(font, tc.size*64, Index(i), hinter); err != nil {
|
||||
t.Errorf("%s: glyph #%d: Load: %v", tc.name, i, err)
|
||||
continue loop
|
||||
}
|
||||
got := glyphBuf.Point
|
||||
for i := range got {
|
||||
got[i].Flags &= 0x01
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("%s: glyph #%d:\ngot %v\nwant %v\n", tc.name, i, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScalingSansHinting(t *testing.T) {
|
||||
testScaling(t, "luxisr-12pt-sans-hinting.txt", nil)
|
||||
testScaling(t, nil)
|
||||
}
|
||||
|
||||
func TestScalingWithHinting(t *testing.T) {
|
||||
testScaling(t, "luxisr-12pt-with-hinting.txt", &Hinter{})
|
||||
testScaling(t, &Hinter{})
|
||||
}
|
||||
|
|
4
testdata/README
vendored
4
testdata/README
vendored
|
@ -1,8 +1,8 @@
|
|||
The *.ttf and COPYING files in this directory were copied from the X.org
|
||||
The luxi*.ttf and COPYING files in this directory were copied from the X.org
|
||||
project, specifically
|
||||
http://xorg.freedesktop.org/releases/individual/font/font-bh-ttf-1.0.0.tar.bz2
|
||||
|
||||
There are three fonts: sans (s), serif (r) and monospaced (m). For example,
|
||||
There are three Luxi fonts: sans (s), serif (r) and monospaced (m). For example,
|
||||
luxisr.ttf is Luxi Sans. The 'r' here means regular, as opposed to bold.
|
||||
|
||||
The *.ttx files in this directory were generated from the *.ttf files
|
||||
|
|
30
testdata/make-other-hinting-txts.sh
vendored
Executable file
30
testdata/make-other-hinting-txts.sh
vendored
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script creates the optional x-*-hinting.txt files from fonts that are
|
||||
# not checked in for copyright or file size reasons.
|
||||
#
|
||||
# Run it from this directory (testdata).
|
||||
#
|
||||
# It has only been tested on an Ubuntu 12.04 system.
|
||||
|
||||
set -e
|
||||
|
||||
: ${FONTDIR:=/usr/share/fonts/truetype}
|
||||
|
||||
ln -sf $FONTDIR/droid/DroidSansJapanese.ttf x-droid-sans-japanese.ttf
|
||||
ln -sf $FONTDIR/msttcorefonts/Arial_Bold.ttf x-arial-bold.ttf
|
||||
ln -sf $FONTDIR/msttcorefonts/Times_New_Roman.ttf x-times-new-roman.ttf
|
||||
ln -sf $FONTDIR/ttf-dejavu/DejaVuSans-Oblique.ttf x-deja-vu-sans-oblique.ttf
|
||||
|
||||
${CC:=gcc} ../cmd/print-glyph-points/main.c $(pkg-config --cflags --libs freetype2) -o print-glyph-points
|
||||
|
||||
./print-glyph-points 9 x-droid-sans-japanese.ttf sans_hinting > x-droid-sans-japanese-9pt-sans-hinting.txt
|
||||
./print-glyph-points 9 x-droid-sans-japanese.ttf with_hinting > x-droid-sans-japanese-9pt-with-hinting.txt
|
||||
./print-glyph-points 11 x-arial-bold.ttf sans_hinting > x-arial-bold-11pt-sans-hinting.txt
|
||||
./print-glyph-points 11 x-arial-bold.ttf with_hinting > x-arial-bold-11pt-with-hinting.txt
|
||||
./print-glyph-points 13 x-times-new-roman.ttf sans_hinting > x-times-new-roman-13pt-sans-hinting.txt
|
||||
./print-glyph-points 13 x-times-new-roman.ttf with_hinting > x-times-new-roman-13pt-with-hinting.txt
|
||||
./print-glyph-points 17 x-deja-vu-sans-oblique.ttf sans_hinting > x-deja-vu-sans-oblique-17pt-sans-hinting.txt
|
||||
./print-glyph-points 17 x-deja-vu-sans-oblique.ttf with_hinting > x-deja-vu-sans-oblique-17pt-with-hinting.txt
|
||||
|
||||
rm print-glyph-points
|
Loading…
Reference in a new issue