summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/gen-mplus-patch.pl205
1 files changed, 189 insertions, 16 deletions
diff --git a/scripts/gen-mplus-patch.pl b/scripts/gen-mplus-patch.pl
index b294ec1..ffdd263 100755
--- a/scripts/gen-mplus-patch.pl
+++ b/scripts/gen-mplus-patch.pl
@@ -5,30 +5,59 @@ use warnings;
no indirect;
no autovivification;
use English qw(-no_match_vars);
-
+use Font::FreeType;
+use List::Util qw(max);
use Text::Diff;
my @FONTS = (
# face weight w h
+ [qw(1m regular 10 14)],
+ [qw(1m regular 12 17)],
[qw(1m regular 16 22)],
- [qw(1m bold 16 22)],
- [qw(1mn regular 16 22)],
- [qw(1mn bold 16 22)],
+ [qw(1m regular 24 34)],
+ [qw(1m regular 32 44)],
+ [qw(1m regular 8 12)],
);
+my $PATCH = 'patches/01_add-mplus-fonts.patch';
-sub slurp
+sub header
{
- my ($fname) = @_;
- my $fh;
- my $data;
+ my ($mplus_dir) = @_;
+ my $ft;
+ my $face;
+ my $version;
+ my $header;
+
+ $ft = Font::FreeType->new();
+ $face = $ft->face("$mplus_dir/mplus-1m-regular.ttf");
+ foreach my $entry (@{$face->namedinfos()}) {
+ if ($entry->platform_id() != 1 or $entry->encoding_id() != 0) {
+ next;
+ }
+ if ($entry->name_id() != 5) {
+ next;
+ }
+ $version = $entry->string();
+ $version =~ s{\AVersion\s1[.]}{}msx;
+ }
+
+ ($header = <<" EOF") =~ s{^\t\t}{}msxg;
+ Author: Patrick McDermott <patrick.mcdermott\@libiquity.com>
+ Subject: Add M+ fonts
+
+ Generated from M+ version $version by $PROGRAM_NAME
+
+ EOF
+
+ return $header;
+}
- $fname = "tmp/src/$fname";
- open($fh, '<', $fname) or die("Error opening $fname: $OS_ERROR");
- local $INPUT_RECORD_SEPARATOR = undef;
- $data = <$fh>;
- close($fh) or die("Error closing $fname: $OS_ERROR");
+sub extract
+{
+ my ($fname) = @_;
- return $data;
+ return `tar --wildcards --no-wildcards-match-slash -xJOf \\
+ linux-libre-*.orig.tar.xz 'linux-*/$fname'`;
}
sub make_patch
@@ -50,7 +79,7 @@ sub patch_font_h
my $width;
my $height;
- $new = $old = slurp('include/linux/font.h');
+ $new = $old = extract('include/linux/font.h');
# Inject "#define"s.
($i) = $old =~ m{.*^[#]\s*define\s+[A-Za-x0-9_]+_IDX\s+(\d+)\s*$}msx;
@@ -75,19 +104,163 @@ sub patch_font_h
sub patch_kconfig
{
+ my $old;
+ my $new;
+ my $inject;
+ my $face;
+ my $weight;
+ my $width;
+ my $height;
+
+ $new = $old = extract('lib/fonts/Kconfig');
+
+ $inject = '';
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $inject .= sprintf("config FONT_MPLUS_%s_%s_%dx%d\n",
+ uc($face), uc($weight), $width, $height);
+ $inject .= sprintf("\tbool \"M+ %s %s %dx%d font " .
+ "(not supported by all drivers)\" if FONTS\n",
+ $face, $weight, $width, $height);
+ $inject .= "\tdepends on FRAMEBUFFER_CONSOLE\n\thelp\n";
+ $inject .= "\t This is a sans-serif font with a " .
+ "sophisticated and relaxed design that\n\t balances " .
+ "natural letterform and high legibility.\n";
+ }
+ $new =~ s{^(\s*config\s+FONT_AUTOSELECT\s*)$}{$inject$1}msx;
+
+ $inject = '';
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $inject .= sprintf("\tdepends on !FONT_MPLUS_%s_%s_%dx%d\n",
+ uc($face), uc($weight), $width, $height);
+ }
+ $new =~ s{ ^ ( \s* select \s+ FONT_[A-Za-z0-9_]+ \s* ) $ }
+ {$inject$1}msx;
+
+ return make_patch('lib/fonts/Kconfig', $old, $new);
}
sub patch_makefile
{
+ my $old;
+ my $new;
+ my $max_var_len;
+ my $face;
+ my $weight;
+ my $width;
+ my $height;
+ my $len;
+ my $inject;
+
+ $new = $old = extract('lib/fonts/Makefile');
+
+ $max_var_len = 0;
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $len = length(
+ sprintf('font-objs-$(CONFIG_FONT_MPLUS_%s_%s_%dx%d)',
+ $face, $weight, $width, $height));
+ $max_var_len = max($max_var_len, $len);
+ }
+ $inject = '';
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $len = length(
+ sprintf('font-objs-$(CONFIG_FONT_MPLUS_%s_%s_%dx%d)',
+ $face, $weight, $width, $height));
+ $len = $max_var_len - $len;
+ $inject .= sprintf('font-objs-$(CONFIG_FONT_MPLUS_%s_%s_%dx%d)'
+ . "%${len}s += font_mplus_%s_%s_%dx%d.o\n",
+ uc($face), uc($weight), $width, $height,
+ '', $face, $weight, $width, $height);
+ }
+ $new =~ s{ \A ( .* ^
+ font-objs-\$[(]CONFIG_FONT_[A-Za-z0-9_]+[)]
+ \s* [+]= \s*
+ font_[a-z0-9_]+[.]o \s*
+ $ ) }{$1$inject}msx;
+
+ return make_patch('lib/fonts/Makefile', $old, $new);
}
sub patch_fonts_c
{
+ my $old;
+ my $new;
+ my $inject;
+ my $face;
+ my $weight;
+ my $width;
+ my $height;
+
+ $new = $old = extract('lib/fonts/fonts.c');
+
+ $inject = '';
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $inject .= sprintf("#ifdef CONFIG_FONT_MPLUS_%s_%s_%dx%d\n" .
+ "#undef NO_FONTS\n &font_mplus_%s_%s_%dx%d,\n" .
+ "#endif\n",
+ uc($face), uc($weight), $width, $height,
+ $face, $weight, $width, $height);
+ }
+ $new =~ s<
+ ( \s* static \s* const \s* struct \s* font_desc \s*
+ [*] \s* fonts\[\] \s* = \s* { [^}]+ ) }
+ ><$1$inject}>msx;
+
+ return make_patch('lib/fonts/fonts.c', $old, $new);
+}
+
+sub conv_fonts
+{
+ my ($mplus_dir, $bdf2fbcon) = @_;
+ my $patch;
+ my $face;
+ my $weight;
+ my $width;
+ my $height;
+ my $new;
+
+ $patch = '';
+ foreach my $font (@FONTS) { ($face, $weight, $width, $height) = @$font;
+ $font = "mplus-$face-$weight";
+ $new = `otf2bdf -p $width -r 72 $mplus_dir/$font.ttf | \\
+ $bdf2fbcon -o - -n $font -p 2 -`;
+ $patch .= make_patch("lib/fonts/font_mplus_${face}_${weight}_" .
+ "${width}x${height}.c", '', $new);
+ }
+
+ return $patch;
}
sub main
{
- print(patch_font_h());
+ my $mplus_dir;
+ my $bdf2fbcon;
+ my $patch;
+ my $fh;
+
+ if (scalar(@ARGV) != 2) {
+ STDERR->printf("Usage: %s <mplus-dir> <bdf2fbcon>\n",
+ $PROGRAM_NAME);
+ return 1;
+ }
+ ($mplus_dir, $bdf2fbcon) = @ARGV;
+
+ $patch = patch_font_h();
+ $patch .= patch_kconfig();
+ $patch .= patch_makefile();
+ $patch .= conv_fonts($mplus_dir, $bdf2fbcon);
+ $patch .= patch_fonts_c();
+ open($fh, '>', "$PATCH~~") or die("Error opening $PATCH~~: $OS_ERROR");
+ $fh->print($patch);
+ close($fh) or die("Error closing $PATCH~~: $OS_ERROR");
+
+ open($fh, '>', "$PATCH~") or die("Error opening $PATCH~: $OS_ERROR");
+ $fh->print(header($mplus_dir) . "---\n" . `diffstat $PATCH~~` . "\n" .
+ $patch);
+ close($fh) or die("Error closing $PATCH~: $OS_ERROR");
+ unlink("$PATCH~~") or die("Error unlinking $PATCH~~");
+ rename("$PATCH~", "$PATCH") or die("Error renaming $PATCH~: $OS_ERROR");
+
+ return 0;
}
exit(main());