1 /*
2  * Test ttf engine performance
3  *
4  * Copyright © 1997-1998 Herbert Duerr
5  * Copyright © 2008-2009, 2012, 2016, 2018-2019 Guillem Jover
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free Softaware
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 
23 #include "config.h"
24 
25 #define MAXFONTBUFSIZE (2048*2048)
26 
27 #include <sys/mman.h>
28 #include <sys/stat.h>
29 #include <sys/time.h>
30 
31 #include <dirent.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 
35 #include <cctype>
36 #include <cstring>
37 #include <cstdlib>
38 
39 #include "ttf.h"
40 #include "ttfn.h"
41 
42 #ifndef MAGNIFY
43 int MAGNIFY = 0;
44 #endif /* MAGNIFY */
45 
46 static int numGlyphs = 0;
47 
48 static int
ttPerfDir(Rasterizer * raster,int pt,FontExtent * fe,const char * ttdir)49 ttPerfDir(Rasterizer *raster, int pt, FontExtent *fe, const char *ttdir)
50 {
51 	int nfonts = 0;
52 	printf("xfstt: perftest in directory " FONTDIR "/%s\n", ttdir);
53 	DIR *dirp = opendir(".");
54 
55 	while (dirent *de = readdir(dirp)) {
56 		string filename(de->d_name);
57 		int namelen = filename.size();
58 
59 		if (namelen - 4 <= 0)
60 			continue;
61 
62 		string ext = string(filename, namelen - 4, namelen);
63 
64 		if (ext != ".ttf")
65 			continue;
66 
67 		struct stat statbuf;
68 		if (stat(de->d_name, &statbuf) < 0)
69 			continue;
70 		if (!S_ISREG(statbuf.st_mode))
71 			continue;
72 
73 		struct timeval t0, t1;
74 		gettimeofday(&t0, nullptr);
75 
76 		static int countFonts = 0;
77 		printf("opening \"%s\",\tno. %5d\n", de->d_name, countFonts++);
78 		fflush(stdout);
79 		if (!strcmp("DAVSDING.TTF", de->d_name))
80 			continue;
81 		if (!strcmp("FH0495.TTF", de->d_name))
82 			continue;
83 		if (!strcmp("GAELACH.TTF", de->d_name))
84 			continue;
85 
86 		TTFont ttFont(de->d_name);
87 		if (ttFont.badFont())
88 			continue;
89 
90 		FontInfo fi;
91 		ttFont.getFontInfo(&fi);
92 		if (fi.faceLength > 31)
93 			fi.faceLength = 31;
94 		fi.faceName[fi.faceLength] = 0;
95 		printf("TTF(\"%s\")", fi.faceName);
96 
97 		raster->useTTFont(&ttFont);
98 		raster->setPointSize(pt, 0, 0, pt, 96, 96);
99 
100 		numGlyphs += ttFont.maxpTable->getNumGlyphs();
101 		raster->getFontExtent(fe);
102 
103 		++nfonts;
104 
105 		gettimeofday(&t1, nullptr);
106 		double dt = (t1.tv_sec - t0.tv_sec) * 1.0e+3;
107 		dt += (t1.tv_usec - t0.tv_usec) * 1.0e-3;
108 
109 		string indent(fi.faceLength >> 3, '\t');
110 		printf("%s\t%7.3f ms\n", indent.c_str(), dt);
111 	}
112 
113 	closedir(dirp);
114 	return nfonts;
115 }
116 
117 int
main(int argc,char ** argv)118 main(int argc, char **argv)
119 {
120 	if (chdir(FONTDIR)) {
121 		fputs("xfstt: " FONTDIR " does not exist!\n", stderr);
122 		return -1;
123 	}
124 
125 	int ptsize = 0;
126 	if (argc > 1)
127 		ptsize = atoi(argv[1]);
128 	if (ptsize <= 0)
129 		ptsize = 12;
130 
131 	printf("perftest(ptsize = %d, resolution = 96)\n", ptsize);
132 
133 	FontExtent fe;
134 	fe.buflen = MAXFONTBUFSIZE;
135 	fe.buffer = (uint8_t *)allocMem(fe.buflen);
136 
137 	Rasterizer raster;
138 
139 	int nfonts = 0;
140 	nfonts += ttPerfDir(&raster, ptsize, &fe, ".");
141 	DIR *dirp = opendir(".");
142 	while (dirent *de = readdir(dirp)) {
143 		chdir(FONTDIR);
144 		if (de->d_name[0] != '.' && !chdir(de->d_name))
145 			nfonts += ttPerfDir(&raster, ptsize, &fe, de->d_name);
146 	}
147 	printf("\nTested %d fonts (%d glyphs)\n", nfonts, numGlyphs);
148 
149 	deallocMem(fe.buffer, fe.buflen);
150 	closedir(dirp);
151 	return 0;
152 }
153