Skip to content

Commit 8f992e5

Browse files
committed
Test parsing METADATA.pb files
1 parent 4b5830f commit 8f992e5

File tree

5 files changed

+205
-1
lines changed

5 files changed

+205
-1
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ resolver = "2"
44
members = [
55
"fontspector-cli",
66
"fontspector-checkapi",
7-
"profile-universal", "profile-testplugin",
7+
"profile-universal", "profile-testplugin", "profile-googlefonts",
88
]

profile-googlefonts/Cargo.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "profile-googlefonts"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type=["dylib"]
8+
9+
[dependencies]
10+
fontspector-checkapi = { path = "../fontspector-checkapi" }
11+
protobuf = "3.5.0"
12+
pluginator = "1.0.1"
13+
[build-dependencies]
14+
protobuf-codegen = "3.5.0"

profile-googlefonts/build.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
fn main() {
2+
println!("Building protos");
3+
protobuf_codegen::Codegen::new()
4+
// Use `protoc` parser, optional.
5+
.protoc()
6+
// All inputs and imports from the inputs must reside in `includes` directories.
7+
.includes(&["src/protos"])
8+
.input("src/protos/fonts_public.proto")
9+
// Specify output directory relative to Cargo output directory.
10+
.cargo_out_dir("protos")
11+
.run_from_script();
12+
println!("cargo::rerun-if-changed=build.rs");
13+
}

profile-googlefonts/src/lib.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
2+
3+
use fonts_public::FamilyProto;
4+
5+
use fontspector_checkapi::prelude::*;
6+
7+
fn validate_metadatapb(c: &Testable) -> StatusList {
8+
let mdpb = std::fs::read_to_string(&c.filename).expect("Couldn't open file");
9+
if let Err(error) = protobuf::text_format::parse_from_str::<FamilyProto>(&mdpb) {
10+
Status::just_one_fail(&format!("Invalid METADATA.pb: {}", error))
11+
} else {
12+
Status::just_one_pass()
13+
}
14+
}
15+
16+
pub const VALIDATE_METADATA_PB: Check = Check {
17+
id: "com.google.fonts/check/metadata/parses",
18+
title: "Check METADATA.pb parse correctly",
19+
rationale: None,
20+
proposal: None,
21+
check_all: None,
22+
check_one: Some(&validate_metadatapb),
23+
applies_to: "MDPB",
24+
hotfix: None,
25+
fix_source: None,
26+
};
27+
28+
struct GoogleFonts;
29+
impl fontspector_checkapi::Plugin for GoogleFonts {
30+
fn register(&self, cr: &mut Registry) {
31+
let mdpb = FileType::new("METADATA.pb");
32+
cr.register_filetype("MDPB", mdpb);
33+
34+
cr.register_simple_profile("googlefonts", vec![VALIDATE_METADATA_PB]);
35+
}
36+
}
37+
pluginator::plugin_implementation!(fontspector_checkapi::Plugin, GoogleFonts);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
syntax = "proto2";
2+
3+
/**
4+
* Open Source'd font metadata proto formats.
5+
*/
6+
package google.fonts_public;
7+
8+
option java_package = "com.google.fonts.proto";
9+
option java_outer_classname = "FontsPublic";
10+
11+
message FamilyProto {
12+
required string name = 1;
13+
required string designer = 2;
14+
required string license = 3;
15+
16+
// A mutually-exclusive category for each font. The categories are: Serif,
17+
// Sans Serif, Display, Handwriting and Monospace. Being mutually exclusive is
18+
// a significant deficiency as, for example, most Display fonts are typically
19+
// Serif or Sans Serif and that is not captured.
20+
//
21+
// For searching, this field is replaced by stroke and classifications (see
22+
// below), however, this field persists (it's required after all) and will
23+
// continue to be populated in the onboarding process.
24+
//
25+
// This is repeated field, yet Google Fonts only uses the last entry so
26+
// multiple entries should be avoided.
27+
repeated string category = 4; // Only the LAST value is used by Google Fonts
28+
required string date_added = 5;
29+
repeated FontProto fonts = 6;
30+
repeated string aliases = 7;
31+
repeated string subsets = 8;
32+
optional string ttf_autohint_args = 9;
33+
repeated AxisSegmentProto axes = 10;
34+
map<string, float> registry_default_overrides = 11;
35+
optional SourceProto source = 12;
36+
optional bool is_noto = 13;
37+
repeated string languages = 14;
38+
repeated FamilyFallbackProto fallbacks = 15;
39+
map<string, string> sample_glyphs = 16;
40+
optional SampleTextProto sample_text = 17;
41+
optional string display_name = 18;
42+
repeated GlyphGroupProto ordered_sample_glyphs = 19;
43+
// Optional url for more info about the font.
44+
optional string minisite_url = 20;
45+
// The script to use when picking sample text. See the Script spanner table.
46+
optional string primary_script = 21;
47+
48+
optional string primary_language = 22;
49+
50+
// Stroke of the letter forms: serif, sans serif, etc. Stroke is mutually
51+
// exclusive. The values are the string names from the Stroke enum or the
52+
// empty string.
53+
optional string stroke = 23;
54+
55+
// A family's broad classifications: display, handwriting, monospace, etc.
56+
// The values are the string names from the Classification enum.
57+
repeated string classifications = 25;
58+
// Next = 25
59+
}
60+
61+
message FontProto {
62+
required string name = 1;
63+
required string style = 2;
64+
required int32 weight = 3;
65+
required string filename = 4;
66+
required string post_script_name = 5;
67+
required string full_name = 6;
68+
optional string copyright = 7;
69+
}
70+
71+
message AxisSegmentProto {
72+
optional string tag = 1;
73+
optional float min_value = 2;
74+
reserved 3;
75+
reserved "default_value";
76+
optional float max_value = 4;
77+
// Next = 5
78+
}
79+
80+
message SourceProto {
81+
optional string repository_url = 1;
82+
optional string branch = 5;
83+
optional string commit = 2;
84+
optional string archive_url = 3;
85+
repeated SourceFileProto files = 4;
86+
// Next = 6
87+
}
88+
89+
// A file to take from source and where to put it in dest
90+
// Ex web/split/Roboto[wdth,wght].ttf => Roboto[wdth,wght].ttf
91+
message SourceFileProto {
92+
optional string source_file = 1;
93+
optional string dest_file = 2;
94+
}
95+
96+
enum TargetTypeProto {
97+
TARGET_UNSPECIFIED = 0;
98+
TARGET_OS_WINDOWS = 1;
99+
TARGET_OS_MAC = 2;
100+
TARGET_OS_LINUX = 3;
101+
TARGET_OS_ANDROID = 4;
102+
TARGET_OS_IOS = 5;
103+
}
104+
105+
// Message so we can add additional fields like value in future
106+
message TargetProto {
107+
optional TargetTypeProto target_type = 1; // e.g., OS
108+
}
109+
110+
message FamilyFallbackProto {
111+
repeated AxisSegmentProto axis_target = 1; // activate for this region
112+
repeated TargetProto target = 2; // activate for any of these
113+
optional float size_adjust_pct = 3; // e.g. 90%
114+
optional float ascent_override_pct = 5; // e.g. 110%
115+
repeated string local_src = 4; // e.g. Impact; the local family to use
116+
// Next = 6
117+
}
118+
119+
// Corresponds to SampleTextProto in
120+
// google3/java/com/google/fonts/backend/spanner/google_fonts_proto.proto
121+
message SampleTextProto {
122+
optional string masthead_full = 1;
123+
optional string masthead_partial = 2;
124+
optional string styles = 3;
125+
optional string tester = 4;
126+
optional string poster_sm = 5;
127+
optional string poster_md = 6;
128+
optional string poster_lg = 7;
129+
optional string specimen_48 = 8;
130+
optional string specimen_36 = 9;
131+
optional string specimen_32 = 10;
132+
optional string specimen_21 = 11;
133+
optional string specimen_16 = 12;
134+
optional string note = 13;
135+
}
136+
137+
message GlyphGroupProto {
138+
optional string name = 1;
139+
optional string glyphs = 2;
140+
}

0 commit comments

Comments
 (0)