1- // Smoke test — verify compat.freetype builds, links, and basic API works
1+ // Smoke test — verify compat.freetype builds, links, and basic API works,
2+ // including the base extensions every distribution builds (ftstroke.c,
3+ // ftgasp.c, fttype1.c, ftbdf.c, ftcid.c, ftpfr.c, ftwinfnt.c, ftfstype.c,
4+ // ftpatent.c, ftgxval.c, ftotval.c, ftbzip2.c): each is called once.
25#include < ft2build.h>
36#include FT_FREETYPE_H
7+ #include FT_STROKER_H
8+ #include FT_GASP_H
9+ #include FT_TYPE1_TABLES_H
10+ #include FT_BDF_H
11+ #include FT_CID_H
12+ #include FT_PFR_H
13+ #include FT_WINFONTS_H
14+ #include FT_GX_VALIDATE_H
15+ #include FT_OPENTYPE_VALIDATE_H
16+ #include FT_BZIP2_H
417import std;
518
619int main () {
@@ -10,7 +23,60 @@ int main() {
1023 std::println (" FT_Init_FreeType failed: {}" , error);
1124 return 1 ;
1225 }
13- std::println (" compat.freetype smoke test: ok" );
26+ int failures = 0 ;
27+ auto expect = [&](bool ok, std::string_view what) {
28+ if (!ok) {
29+ std::println (" FAIL: {}" , what);
30+ ++failures;
31+ }
32+ };
33+
34+ // ftstroke.c: a stroker strokes a two-point path into a closed border.
35+ FT_Stroker stroker{};
36+ expect (FT_Stroker_New (library, &stroker) == FT_Err_Ok, " FT_Stroker_New" );
37+ FT_Stroker_Set (stroker, 64 , FT_STROKER_LINECAP_ROUND , FT_STROKER_LINEJOIN_ROUND , 0 );
38+ FT_Vector from{0 , 0 }, to{640 , 0 };
39+ expect (FT_Stroker_BeginSubPath (stroker, &from, 0 ) == FT_Err_Ok, " FT_Stroker_BeginSubPath" );
40+ expect (FT_Stroker_LineTo (stroker, &to) == FT_Err_Ok, " FT_Stroker_LineTo" );
41+ expect (FT_Stroker_EndSubPath (stroker) == FT_Err_Ok, " FT_Stroker_EndSubPath" );
42+ FT_UInt points = 0 , contours = 0 ;
43+ expect (FT_Stroker_GetCounts (stroker, &points, &contours) == FT_Err_Ok && points > 0 && contours > 0 ,
44+ " FT_Stroker_GetCounts" );
45+ FT_Stroker_Done (stroker);
46+
47+ // The face-level extensions reject a null face rather than failing to link.
48+ FT_Face none = nullptr ;
49+ expect (FT_Get_Gasp (none, 12 ) == FT_GASP_NO_TABLE , " FT_Get_Gasp" );
50+ expect (FT_Get_FSType_Flags (none) == 0 , " FT_Get_FSType_Flags" );
51+ expect (FT_Has_PS_Glyph_Names (none) == 0 , " FT_Has_PS_Glyph_Names" );
52+ PS_FontInfoRec info{};
53+ expect (FT_Get_PS_Font_Info (none, &info) == FT_Err_Invalid_Face_Handle, " FT_Get_PS_Font_Info" );
54+ const char *encoding = nullptr , *registry = nullptr ;
55+ expect (FT_Get_BDF_Charset_ID (none, &encoding, ®istry) == FT_Err_Invalid_Face_Handle, " FT_Get_BDF_Charset_ID" );
56+ FT_Bool cid_keyed = 0 ;
57+ expect (FT_Get_CID_Is_Internally_CID_Keyed (none, &cid_keyed) == FT_Err_Invalid_Argument,
58+ " FT_Get_CID_Is_Internally_CID_Keyed" );
59+ FT_UInt outline_resolution = 0 , metrics_resolution = 0 ;
60+ expect (FT_Get_PFR_Metrics (none, &outline_resolution, &metrics_resolution, nullptr , nullptr ) ==
61+ FT_Err_Invalid_Face_Handle,
62+ " FT_Get_PFR_Metrics" );
63+ FT_WinFNT_HeaderRec header{};
64+ expect (FT_Get_WinFNT_Header (none, &header) == FT_Err_Invalid_Face_Handle, " FT_Get_WinFNT_Header" );
65+ expect (FT_Face_CheckTrueTypePatents (none) == 0 , " FT_Face_CheckTrueTypePatents" );
66+ FT_Bytes tables[FT_VALIDATE_GX_LENGTH ]{};
67+ expect (FT_TrueTypeGX_Validate (none, FT_VALIDATE_GX , tables, FT_VALIDATE_GX_LENGTH ) != FT_Err_Ok,
68+ " FT_TrueTypeGX_Validate" );
69+ FT_Bytes base{}, gdef{}, gpos{}, gsub{}, jstf{};
70+ expect (FT_OpenType_Validate (none, FT_VALIDATE_OT , &base, &gdef, &gpos, &gsub, &jstf) != FT_Err_Ok,
71+ " FT_OpenType_Validate" );
72+
73+ // ftbzip2.c without libbz2: the entry point exists and says so.
74+ FT_StreamRec stream{}, source{};
75+ expect (FT_Stream_OpenBzip2 (&stream, &source) == FT_Err_Unimplemented_Feature, " FT_Stream_OpenBzip2" );
76+
1477 FT_Done_FreeType (library);
78+ if (failures)
79+ return 1 ;
80+ std::println (" compat.freetype smoke test: ok" );
1581 return 0 ;
1682}
0 commit comments