From 463f2161cdb4d27e1788810294409b9aef6e9cee Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Fri, 11 Oct 2024 23:17:50 +0200 Subject: [PATCH] Fixing emoji positions. --- lib/Exd/DeviceToImage.pm | 1 - lib/Exd/Printer.pm | 77 +++++++++++++++++++++++++++------------- scripts/demo.pl | 6 ++-- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/lib/Exd/DeviceToImage.pm b/lib/Exd/DeviceToImage.pm index c1be2ae..1e43e7f 100644 --- a/lib/Exd/DeviceToImage.pm +++ b/lib/Exd/DeviceToImage.pm @@ -30,7 +30,6 @@ sub image( $self, $image ) { $new_current->copy( $current_image, 0, 0, 0, 0, $current_image->width, $current_image->height); - say $current_image->height; $new_current->copy( $image, 0, $current_image->height, 0, 0, $image->width, $image->height ); $self->current_image($new_current); diff --git a/lib/Exd/Printer.pm b/lib/Exd/Printer.pm index 2e1e652..17457fc 100644 --- a/lib/Exd/Printer.pm +++ b/lib/Exd/Printer.pm @@ -16,6 +16,13 @@ has device => ( required => 1, ); +has font => ( + is => 'rw', + default => sub { + return 'Noto Sans CJK JP'; + }, +); + sub qr( $self, $url ) { my $tmpdir = Path::Tiny->tempdir; my $image_file = $tmpdir->child('image.png'); @@ -60,7 +67,7 @@ sub image( $self, $file ) { } } -sub split_text_lines( $self, $text, $max_width, $font, $font_size ) { +sub _split_text_lines( $self, $text, $max_width, $font, $font_size ) { my @return; my @lines; if ( !ref $text ) { @@ -84,50 +91,50 @@ sub split_text_lines( $self, $text, $max_width, $font, $font_size ) { my $layout = Pango::Cairo::create_layout($cr); $layout->set_font_description($font); while (@lines) { - my $current_line = $self->get_next_line( \@lines ); + my $current_line = $self->_get_next_line( \@lines ); my ( $w, $h ) = $self->_get_size_text( $cr, $layout, $font, $font_size, $current_line ); my $final_line = []; my $remainder = []; if ( $w > $max_width ) { LOOP_SPLIT: while (1) { - my $word = $self->get_word($current_line); + my $word = $self->_get_word($current_line); if ( !defined $word ) { die 'wtf?'; } my ( $w, $h ) = $self->_get_size_text( $cr, $layout, $font, $font_size, - $self->join_line_with_word( $final_line, $word ) ); + $self->_join_line_with_word( $final_line, $word ) ); if ( $w > $max_width ) { my ( $w_cutted_word, $h_cutted_word ) = $self->_get_size_text( $cr, $layout, $font, $font_size, [$word] ); if ( $w_cutted_word > $max_width ) { my $i = 0; - $final_line = $self->join_line_with_word( $final_line, $word ); + $final_line = $self->_join_line_with_word( $final_line, $word ); while (1) { my $possible_cut = - $self->substr_line( $final_line, 0, $i ); + $self->_substr_line( $final_line, 0, $i ); my ( $w_cutted_word, $h_cutted_word ) = $self->_get_size_text( $cr, $layout, $font, $font_size, $possible_cut ); if ( $w_cutted_word > $max_width ) { $remainder = - $self->substr_line( [ @$final_line, @$current_line ], + $self->_substr_line( [ @$final_line, @$current_line ], $i - 1 ); $final_line = - $self->substr_line( $final_line, 0, $i - 1 ); + $self->_substr_line( $final_line, 0, $i - 1 ); $current_line = $final_line; last LOOP_SPLIT; } $i++; } } - $remainder = $self->unshift_line_with_word( $word, $current_line ); + $remainder = $self->_unshift_line_with_word( $word, $current_line ); $current_line = $final_line; last; } - $final_line = $self->join_line_with_word( $final_line, $word ); + $final_line = $self->_join_line_with_word( $final_line, $word ); } } $remainder->[0] =~ s/^\s+// @@ -138,7 +145,7 @@ sub split_text_lines( $self, $text, $max_width, $font, $font_size ) { return @return; } -sub substr_line( $self, $text, $offset, $how_much = undef ) { +sub _substr_line( $self, $text, $offset, $how_much = undef ) { my $result = []; my $cur_offset = 0; my $element = 0; @@ -174,7 +181,7 @@ sub substr_line( $self, $text, $offset, $how_much = undef ) { if ( defined $how_much && $gotten + $substr_length > $how_much ) { $substr_length = $how_much - $gotten; } - $result = $self->join_line_with_word( $result, substr $text->[$element], + $result = $self->_join_line_with_word( $result, substr $text->[$element], $needed_offset, $substr_length ); $needed_offset = 0; $gotten += $substr_length; @@ -184,7 +191,7 @@ sub substr_line( $self, $text, $offset, $how_much = undef ) { return $result; } -sub unshift_line_with_word( $self, $word, $line ) { +sub _unshift_line_with_word( $self, $word, $line ) { my $result = [@$line]; if ( defined $result->[0] && !ref $result->[0] ) { $result->[0] = $word . $result->[0]; @@ -196,7 +203,7 @@ sub unshift_line_with_word( $self, $word, $line ) { } -sub join_line_with_word( $self, $line, $word ) { +sub _join_line_with_word( $self, $line, $word ) { my $result = [@$line]; if ( scalar @$result == 0 || scalar @$result == 0 @@ -212,7 +219,7 @@ sub join_line_with_word( $self, $line, $word ) { } -sub get_word($self, $line) { +sub _get_word($self, $line) { if ( ref $line->[0] ) { return shift @$line; } @@ -227,7 +234,7 @@ sub get_word($self, $line) { return $1; } -sub get_next_line($self, $lines) { +sub _get_next_line($self, $lines) { my @result; my $last_is_image = 0; my $first = 1; @@ -272,25 +279,33 @@ sub print_text( $self, $text, $font_size ) { my $tempdir = Path::Tiny->tempdir; my $file = $tempdir->child('result.png'); my $font = Pango::FontDescription->from_string( - 'Noto Sans CJK JP ' . ( $font_size - ( 2 * 50 / 30 ) ) ); - - my @lines = $self->split_text_lines( $text, 380, $font, $font_size ); + $self->font . ' ' . ( $font_size - ( 2 * 50 / 30 ) ) ); + my $height; + my $surface = Cairo::ImageSurface->create( 'argb32', 380, 500 ); + my $cr = Cairo::Context->create($surface); + my $layout = Pango::Cairo::create_layout($cr); + my $context = $layout->get_context; + my $metrics = $context->get_metrics($font, undef); + $height = ($metrics->get_ascent + $metrics->get_descent + $layout->get_spacing) / 1024; + my @lines = $self->_split_text_lines( $text, 380, $font, $font_size ); while (@lines) { my $current_line = shift @lines; - my $height = $font_size * 30 / 17; + my $surface = Cairo::ImageSurface->create( 'argb32', 380, $height ); my $cr = Cairo::Context->create($surface); $cr->set_source_rgb( 1, 1, 1 ); - $cr->rectangle( 0, 0, 380, $font_size * 30 / 17 ); + $cr->rectangle( 0, 0, 380, $height ); $cr->fill; $cr->set_source_rgb( 0, 0, 0 ); my $x = 0; - my $layout = Pango::Cairo::create_layout($cr); for my $part (@$current_line) { $cr->move_to( 0, 0 ); + my $layout = Pango::Cairo::create_layout($cr); + my $context = $layout->get_context; + my $metrics = $context->get_metrics($font, undef); if ( !ref $part ) { Pango::Cairo::update_layout( $cr, $layout ); $layout->set_text($part); @@ -309,14 +324,16 @@ sub print_text( $self, $text, $font_size ) { my $ori_width = $gd_image->width; my $ori_height = $gd_image->height; my $scale_w = $font_size / $ori_width; - my $total_height = $font_size * 30 / 17 / $scale_w; - my $scale_h = $scale_w; + my $total_height = ($height) / $scale_w; + + my $scale_h = $font_size / $ori_height; $cr->save; $cr->scale( $scale_w, $scale_h ); + say ((($metrics->get_ascent / 1024 ))); $cr->set_source_surface( $image, $x / $scale_w, - ( $total_height - $x * $scale_w ) / 4 + ((($metrics->get_ascent / 1024 - $metrics->get_descent / 1024 - $layout->get_baseline / 1024 )) / $scale_h), ); $cr->paint; $cr->restore; @@ -330,6 +347,16 @@ sub print_text( $self, $text, $font_size ) { } } +sub _font_to_weight ($self, $font) { + my $weight = $font->get_weight; + if ($weight eq 'normal') { + return 4; + } + if ($weight eq 'bold') { + return 7; + } +} + sub print($self) { $self->device->print; } diff --git a/scripts/demo.pl b/scripts/demo.pl index 1ee495c..0c64acd 100644 --- a/scripts/demo.pl +++ b/scripts/demo.pl @@ -12,13 +12,15 @@ use Exd::DeviceToBluetooth; use Exd::Utils; { - my $device = Exd::DeviceToBluetooth->new( address => '5A:4A:AE:8C:E9:D2', port => 1 ); +# my $device = Exd::DeviceToBluetooth->new( address => '5A:4A:AE:8C:E9:D2', port => 1 ); + my $device = Exd::DeviceToImage->new( output_file => 'a.png' ); my $printer = Exd::Printer->new( device => $device ); + $printer->font('Z003 Medium Italic'); my $hoz = Exd::Utils::get_gd_image('scripts/hoz.jpg'); $printer->print_text( - [ $hoz, ' The best software belongs to everybody ', $hoz ], 27 ); + [ $hoz, 'The best software belongs to everybody', $hoz ], 40 ); $printer->image('scripts/hoz.jpg'); $printer->print_n_lf(4);