resize-font (4527B)
1 # #!/usr/bin/env perl 2 # vim:ft=perl:fenc=utf-8:tw=80 3 # Copyright (c) 2009-, Simon Lundström <simmel@soy.se> 4 # Copyright (c) 2014 Maarten de Vries <maarten@de-vri.es> 5 # 6 # Permission to use, copy, modify, and/or distribute this software for any 7 # purpose with or without fee is hereby granted, provided that the above 8 # copyright notice and this permission notice appear in all copies. 9 # 10 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 18 19 my @fonts = ( 20 {'name' => 'font', 'code' => 710}, 21 {'name' => 'boldFont', 'code' => 711}, 22 {'name' => 'italicFont', 'code' => 712}, 23 {'name' => 'boldItalicFont', 'code' => 713}, 24 ); 25 26 my @fixed = qw(4x6 5x7 5x8 6x9 6x10 6x12 6x13 7x13 7x14 8x13 8x16 9x15 9x18 27 10x20 12x24); 28 my $step; 29 30 sub on_start { 31 my ($self) = @_; 32 33 foreach (@fonts) { 34 $_->{'default'} = $self->resource($_->{'name'}); 35 } 36 37 $step = $self->x_resource("%.step") || 2; 38 } 39 40 sub on_init { 41 my ($self) = @_; 42 my $commands = { 43 "smaller" => "C-minus", 44 "bigger" => "C-plus", 45 "reset" => "C-equal", 46 "show" => "C-question", 47 }; 48 bind_hotkeys($self, $commands); 49 50 () 51 } 52 53 sub bind_hotkeys { 54 my ($self, $commands) = @_; 55 56 for (keys %$commands) { 57 my $hotkey = $$commands{$_}; 58 my $hotkey_bound = $self->{'term'}->x_resource("keysym.$hotkey"); 59 if (!defined($hotkey_bound) ) { 60 # Support old-style key bindings 61 if ($self->x_resource("%.$_")) { 62 $hotkey = $self->x_resource("%.$_"); 63 } 64 65 # FIXME If we're bound to a keysym, don't bind the default. 66 $self->bind_action($hotkey, "%:$_") or 67 warn "unable to register '$hotkey' as hotkey for $_"; 68 } 69 else { 70 if ($hotkey_bound !~ /^resize-font:/) { 71 warn "Hotkey $$commands{$_} already bound to $hotkey_bound, not ". 72 "binding to resize-font:$_ by default."; 73 } 74 } 75 } 76 } 77 78 sub on_action { 79 my ($self, $string) = @_; 80 81 if ($string eq "bigger") { 82 foreach (@fonts) { 83 next if not defined($_->{'default'}); 84 update_font_size($self, $_, +$step); 85 } 86 } 87 elsif ($string eq "smaller") { 88 foreach (@fonts) { 89 next if not defined($_->{'default'}); 90 update_font_size($self, $_, -$step); 91 } 92 } 93 elsif ($string eq "reset") { 94 foreach (@fonts) { 95 next if not defined($_->{'default'}); 96 set_font($self, $_, $_->{'default'}); 97 } 98 } 99 elsif ($string eq "show") { 100 101 my $term = $self->{'term'}; 102 $term->{'resize-font'}{'overlay'} = { 103 ov => $term->overlay_simple(0, -1, format_font_info($self)), 104 to => urxvt::timer 105 ->new 106 ->start(urxvt::NOW + 1) 107 ->cb(sub { 108 delete $term->{'resize-font'}{'overlay'}; 109 }), 110 }; 111 } 112 113 () 114 } 115 116 sub get_font { 117 my ($self, $name) = @_; 118 return $self->resource($name); 119 } 120 121 sub set_font { 122 my ($self, $font, $new) = @_; 123 $self->cmd_parse(sprintf("\33]%d;%s\007", $font->{'code'}, $new)); 124 } 125 126 sub update_font_size { 127 my ($self, $font, $delta) = @_; 128 my $regex = qr"(?<=size=)(\d+)"; 129 my $current = get_font($self, $font->{'name'}); 130 131 my ($index) = grep { $fixed[$_] eq $current } 0..$#fixed; 132 if ($index or $index eq 0) { 133 my $inc = $delta / abs($delta); 134 $index += $inc; 135 if ($index < 0) { $index = 0; } 136 if ($index > $#fixed) { $index = $#fixed; } 137 $current = $fixed[$index]; 138 } 139 elsif ($current =~ /^-/) { 140 my @font = split(/-/, $current); 141 # https://en.wikipedia.org/wiki/X_logical_font_description 142 my $newsize = $font[7]+$delta; 143 $font[7] = $newsize if ($newsize > 0); 144 $current = join('-', @font); 145 } 146 else { 147 my $newsize = $1+$delta if ($current =~ /$regex/); 148 $current =~ s/$regex/$newsize/ge if ($newsize > 0); 149 } 150 set_font($self, $font, $current); 151 } 152 153 sub format_font_info { 154 my ($self) = @_; 155 156 my $width = 0; 157 foreach (@fonts) { 158 my $length = length($_->{'name'}); 159 $width = $length > $width ? $length : $width; 160 } 161 ++$width; 162 163 my $info = ''; 164 foreach (@fonts) { 165 $info .= sprintf("%-${width}s %s\n", $_->{'name'} . ':', 166 get_font($self, $_->{'name'})); 167 } 168 169 return $info; 170 }