From 323a860325a9768737683ac7c594f8e95bb76e70 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Mon, 15 Jul 2019 00:11:19 -0400 Subject: scripts/gen-mplus-patch.pl: Finish --- 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 + 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 \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()); -- cgit v0.9.1