From 2eb80c4ba1cd4becba0a2046438bdec74b89ce98 Mon Sep 17 00:00:00 2001 From: Dianne Skoll Date: Sun, 19 Oct 2025 18:16:27 -0400 Subject: [PATCH] Add new color command-line options to rem2pdf. Also make "SHADE" fill the entire rectangle. New color options are: --line-color=RRGGBB Set line color --title-color=RRGGBB Set title color --header-color=RRGGBB Set header color --daynum-color=RRGGBB Set day number color --smallcal-color=RRGGBB Set small calendar color --bg-color=RRGGBB Set background color --- rem2pdf/bin/rem2pdf.in | 36 +++++++++++++++++ rem2pdf/lib/Remind/PDF.pm | 68 ++++++++++++++++++++++++++++++++- rem2pdf/lib/Remind/PDF/Entry.pm | 7 +++- 3 files changed, 108 insertions(+), 3 deletions(-) diff --git a/rem2pdf/bin/rem2pdf.in b/rem2pdf/bin/rem2pdf.in index 64bdf9c2..66cc7dd8 100644 --- a/rem2pdf/bin/rem2pdf.in +++ b/rem2pdf/bin/rem2pdf.in @@ -65,6 +65,12 @@ my $settings = { eps => 0, verbose => 0, + line_color => '000000', + title_color => '000000', + header_color => '000000', + daynum_color => '000000', + smallcal_color => '000000', + bg_color => 'ffffff', weeks_per_page => 1, }; @@ -110,6 +116,12 @@ Options: --margin-bottom=S Specify bottom margin size in 1/72nds of an inch --margin-left=S Specify left margin size in 1/72nds of an inch --margin-right=S Specify right margin size in 1/72nds of an inch +--line-color=RRGGBB Set line color +--title-color=RRGGBB Set title color +--header-color=RRGGBB Set header color +--daynum-color=RRGGBB Set day number color +--smallcal-color=RRGGBB Set small calendar color +--bg-color=RRGGBB Set background color --verbose, -v Print progress messages --help Display this help EOF @@ -145,6 +157,12 @@ my $ret = GetOptions('landscape|l' => \$settings->{landscape}, 'margin-left=f' => \$settings->{margin_left}, 'margin-right=f' => \$settings->{margin_right}, 'verbose|v' => \$settings->{verbose}, + 'line-color=s' => \$settings->{line_color}, + 'bg-color=s' => \$settings->{bg_color}, + 'title-color=s' => \$settings->{title_color}, + 'header-color=s' => \$settings->{header_color}, + 'daynum-color=s' => \$settings->{daynum_color}, + 'smallcal-color=s' => \$settings->{smallcal_color}, 'help' => \$help ); if (!$ret) { @@ -157,6 +175,24 @@ if ($help) { exit(0); } +my $bad = 0; +foreach my $setting (qw(bg_color line_color title_color header_color daynum_color smallcal_color)) { + my $c = $settings->{$setting}; + my $color = Remind::PDF->get_rgb($c); + if (!defined($color)) { + my $s = $setting; + $s =~ s/_/-/g; + print STDERR "Invalid color value `$c' for option --$s\n"; + $bad = 1; + } else { + $settings->{$setting} = $color; + } +} + +if ($bad) { + exit(1); +} + if ($settings->{weeks_per_page} < 1) { $settings->{weeks_per_page} = 1;} elsif ($settings->{weeks_per_page} > 4) { diff --git a/rem2pdf/lib/Remind/PDF.pm b/rem2pdf/lib/Remind/PDF.pm index 7a4a1372..665a3a08 100644 --- a/rem2pdf/lib/Remind/PDF.pm +++ b/rem2pdf/lib/Remind/PDF.pm @@ -476,6 +476,14 @@ sub render return; } } + my ($r, $g, $b) = @{$settings->{bg_color}}; + if ($r != 255 || $g != 255 || $b != 255) { + $cr->save; + $self->set_cr_color($cr, $settings->{bg_color}); + $cr->rectangle(0, 0, $settings->{width}, $settings->{height}); + $cr->fill(); + $cr->restore; + } $self->setup_daymap($settings); $self->{horiz_lines} = []; $cr->set_line_cap('square'); @@ -521,6 +529,10 @@ sub render print STDERR "WARNING: overfull calendar box\n"; } # The vertical lines + + # Set the color + $cr->save; + $self->set_cr_color($cr, $settings->{line_color}); my $cell = ($settings->{width} - $settings->{margin_left} - $settings->{margin_right}) / 7; for (my $i=0; $i<=7; $i++) { $cr->move_to($settings->{margin_left} + $i * $cell, $top_line); @@ -535,6 +547,7 @@ sub render $cr->stroke(); } + $cr->restore; if ($settings->{verbose}) { print STDERR "rem2pdf: Rendered " . $self->{monthname} . ' ' . $self->{year} . "\n"; } @@ -542,6 +555,13 @@ sub render $cr->show_page(); } +sub set_cr_color { + my ($self, $cr, $color_array) = @_; + $cr->set_source_rgb($color_array->[0] / 255, + $color_array->[1] / 255, + $color_array->[2] / 255); +} + =head2 draw_row($cr, $settings, $so_far, $row, $start_day, $start_col) Draw a single row in the calendar. C<$cr> is a Cairo drawing context @@ -638,7 +658,7 @@ sub draw_day $cr->set_source_rgb($shade->{r} / 255, $shade->{g} / 255, $shade->{b} / 255); - $cr->rectangle($x1, $y1, $x2 - $x1, $y2 - $y1); + $cr->rectangle($x1, $y1, $x2 - $x1, $y2 - $y1 + $settings->{border_size}); $cr->fill(); $cr->restore; } @@ -655,6 +675,7 @@ sub draw_day # Don't actually draw if we're just previewing to get the cell height if ($height) { $cr->save; + $self->set_cr_color($cr, $settings->{daynum_color}); if ($settings->{numbers_on_left}) { $cr->move_to($x1 + $settings->{border_size}, $so_far + $settings->{border_size}); } else { @@ -740,6 +761,7 @@ sub draw_daynames my ($wid, $h) = $layout->get_pixel_size(); $cr->save; + $self->set_cr_color($cr, $settings->{header_color}); $cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid/2, $so_far); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -775,12 +797,38 @@ sub draw_title my ($w, $h) = $layout->get_pixel_size(); $cr->save(); + $self->set_cr_color($cr, $settings->{title_color}); $cr->move_to($settings->{width}/2 - $w/2, $settings->{margin_top}); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); return $h + $settings->{margin_top} + $settings->{border_size}; } +=head2 get_rgb($color) + +Parses a 3- or 6-hex-digit color value and returs [red, green, blue]. If +color could not be parsed, returns undef + +=cut +sub get_rgb +{ + my ($self, $color) = @_; + my ($r, $g, $b); + if ($color =~ /^([0-9a-f])([0-9a-f])([0-9a-f])$/i) { + $r = hex($1); + $g = hex($2); + $b = hex($3); + $r = $r * 16 + $r; + $g = $g * 16 + $g; + $b = $b * 16 + $b; + return [$r, $g, $b]; + } elsif ($color =~ /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i) { + return [hex($1), hex($2), hex($3)]; + } + return undef; +} + + =head2 draw_small_calendar($cr, $x, $y, $width, $height, $settings, $month, $days, $start_wkday) Draw a small calendar on the Cairo context C<$cr>. The top left-hand @@ -828,6 +876,7 @@ sub draw_small_calendar $layout->set_text(Encode::decode('UTF-8', $month)); my ($mw, $mh) = $layout->get_pixel_size(); $cr->save(); + $self->set_cr_color($cr, $settings->{smallcal_color}); $cr->move_to($x + $width/2 - $mw/2, $y); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -849,6 +898,7 @@ sub draw_small_calendar $layout->set_font_description($desc); $layout->set_text($l); $cr->save(); + $self->set_cr_color($cr, $settings->{smallcal_color}); $cr->move_to($x + $col*$wid, $y); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -866,6 +916,7 @@ sub draw_small_calendar } $layout->set_text($dt); $cr->save(); + $self->set_cr_color($cr, $settings->{smallcal_color}); $cr->move_to($x + $col*$wid, $y); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -1055,6 +1106,16 @@ sub render return; } } + if ((($index-1) % $settings->{weeks_per_page}) == 0) { + my ($r, $g, $b) = @{$settings->{bg_color}}; + if ($r != 255 || $g != 255 || $b != 255) { + $cr->save; + $self->set_cr_color($cr, $settings->{bg_color}); + $cr->rectangle(0, 0, $settings->{width}, $settings->{height}); + $cr->fill(); + $cr->restore; + } + } $settings->{numbers_on_left} = 1; # Set up bounding box @@ -1117,6 +1178,7 @@ sub draw_headings my ($wid, $h) = $layout->get_pixel_size(); $cr->save; + $self->set_cr_color($cr, $settings->{header_color}); $cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid/2, $self->{bounding_box}[1]); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -1132,6 +1194,7 @@ sub draw_headings my ($wid2, $h2) = $layout->get_pixel_size(); $cr->save; + $self->set_cr_color($cr, $settings->{header_color}); $cr->move_to($settings->{margin_left} + $i * $cell + $cell/2 - $wid2/2, $self->{bounding_box}[1] + $h); Pango::Cairo::show_layout($cr, $layout); $cr->restore(); @@ -1232,6 +1295,8 @@ sub draw_lines { my ($self, $cr, $settings) = @_; + $cr->save; + $self->set_cr_color($cr, $settings->{line_color}); # Top horizonal line $cr->move_to($self->{bounding_box}[0], $self->{bounding_box}[1]); $cr->line_to($self->{bounding_box}[2], $self->{bounding_box}[1]); @@ -1255,6 +1320,7 @@ sub draw_lines $cr->line_to($x, $self->{bounding_box}[3]); $cr->stroke(); } + $cr->restore; } sub create_from_hash diff --git a/rem2pdf/lib/Remind/PDF/Entry.pm b/rem2pdf/lib/Remind/PDF/Entry.pm index 01697777..fbf34dee 100644 --- a/rem2pdf/lib/Remind/PDF/Entry.pm +++ b/rem2pdf/lib/Remind/PDF/Entry.pm @@ -151,6 +151,7 @@ sub render my ($wid, $h) = $layout->get_pixel_size(); $cr->save(); + Remind::PDF->set_cr_color($cr, $settings->{daynum_color}); $cr->move_to($x2 - $settings->{border_size}/4 - $wid, $y2 - $settings->{border_size}/4 - $h); my $url; if ($self->{info} && $self->{info}->{url}) { @@ -234,12 +235,13 @@ sub render if ($url) { $cr->tag_begin(Cairo::TAG_LINK, "uri='$url'"); } - $self->draw_moon($xc, $yc, $cr); + $self->draw_moon($xc, $yc, $cr, $settings); if ($url) { $cr->tag_end(Cairo::TAG_LINK); } if ($layout) { $cr->save(); + Remind::PDF->set_cr_color($cr, $settings->{daynum_color}); $cr->move_to ($xc + ($self->{size}/2) + $settings->{border_size}, $yc + ($self->{size}/2) - $self->{fontsize} ); if ($url) { @@ -255,8 +257,9 @@ sub render sub draw_moon { - my ($self, $xc, $yc, $cr) = @_; + my ($self, $xc, $yc, $cr, $settings) = @_; $cr->save(); + Remind::PDF->set_cr_color($cr, $settings->{daynum_color}); $cr->new_path(); $cr->arc($xc, $yc, $self->{size}/2, 0, 2*3.1415926535); if ($self->{phase} == 0) {