From: Steinar H. Gunderson Date: Tue, 20 Oct 2015 19:39:47 +0000 (+0200) Subject: Much better high-dpi support; makes images and text much clearer on such displays. X-Git-Url: https://git.sesse.net/?p=pr0n;a=commitdiff_plain;h=acc5b53241d0e971595d6017c60f54a6bc057c41 Much better high-dpi support; makes images and text much clearer on such displays. --- diff --git a/files/pr0n-fullscreen.js b/files/pr0n-fullscreen.js index fe31090..79c174b 100644 --- a/files/pr0n-fullscreen.js +++ b/files/pr0n-fullscreen.js @@ -29,7 +29,8 @@ function find_width() { if (typeof(window.innerWidth) == 'number') { // non-IE - return [window.innerWidth, window.innerHeight]; + var dpr = find_dpr(); + return [window.innerWidth * dpr, window.innerHeight * dpr]; } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { // IE 6+ in 'standards compliant mode' return [document.documentElement.clientWidth, document.documentElement.clientHeight]; @@ -40,6 +41,11 @@ function find_width() return [null,null]; } +function find_dpr() +{ + return window.devicePixelRatio || 1; +} + /* * pr0n can resize to any size we'd like, but we're much more likely * to have this set of fixed-resolution screens cached, so to increase @@ -148,6 +154,7 @@ function display_image(width, height, evt, filename, element_id) var url = "http://" + global_vhost + "/" + evt + "/" + width + "x" + height + "/nobox/" + filename; var main = document.getElementById("iehack"); var preload = document.getElementById("preload"); + var dpr = find_dpr(); var img; // See if we have a preload going on that we can reuse. if (element_id == "image" && preload !== null && preload.src == url) { @@ -159,14 +166,23 @@ function display_image(width, height, evt, filename, element_id) img.style.position = "absolute"; img.style.left = "0px"; img.style.top = "0px"; + img.style.transformOrigin = "top left"; + img.style.transform = "scale(" + (1.0 / dpr) + ")"; if (global_infobox != 'nobox/') { - var url = "http://" + global_vhost + "/" + evt + "/" + width + "x" + height + "/box/" + filename; + var url; + if (dpr == 1) { + url = "http://" + global_vhost + "/" + evt + "/" + width + "x" + height + "/box/" + filename; + } else { + url = "http://" + global_vhost + "/" + evt + "/" + width + "x" + height + "@" + dpr + "/box/" + filename; + } var boximg = replace_image_element(url, element_id + "_box", main); boximg.style.position = "absolute"; boximg.style.left = "0px"; boximg.style.bottom = "-1px"; + boximg.style.transformOrigin = "bottom left"; + boximg.style.transform = "scale(" + (1.0 / dpr) + ")"; } return img; @@ -267,6 +283,7 @@ function set_opacity(id, amount) function center_image(num) { var screen_size = find_width(); + var dpr = find_dpr(); var width, height; if (global_image_list[num][2] == -1) { @@ -284,11 +301,11 @@ function center_image(num) // center the image on-screen var main = document.getElementById("main"); main.style.position = "absolute"; - main.style.left = (screen_size[0] - width) / 2 + "px"; - main.style.top = (screen_size[1] - height) / 2 + "px"; - main.style.width = width + "px"; - main.style.height = height + "px"; - main.style.lineHeight = height + "px"; + main.style.left = (((screen_size[0] - width) / 2) / dpr) + "px"; + main.style.top = (((screen_size[1] - height) / 2) / dpr) + "px"; + main.style.width = (width / dpr) + "px"; + main.style.height = (height / dpr) + "px"; + main.style.lineHeight = (height / dpr) + "px"; } function relayout() diff --git a/perl/Sesse/pr0n/Common.pm b/perl/Sesse/pr0n/Common.pm index 8ea7fca..77cf431 100644 --- a/perl/Sesse/pr0n/Common.pm +++ b/perl/Sesse/pr0n/Common.pm @@ -220,7 +220,7 @@ sub get_disk_location { } sub get_cache_location { - my ($r, $id, $width, $height, $infobox) = @_; + my ($r, $id, $width, $height, $infobox, $dpr) = @_; my $dir = POSIX::floor($id / 256); if ($infobox eq 'both') { @@ -228,7 +228,11 @@ sub get_cache_location { } elsif ($infobox eq 'nobox') { return get_base($r) . "cache/$dir/$id-$width-$height-nobox.jpg"; } else { - return get_base($r) . "cache/$dir/$id-$width-$height-box.png"; + if ($dpr == 1) { + return get_base($r) . "cache/$dir/$id-$width-$height-box.png"; + } else { + return get_base($r) . "cache/$dir/$id-$width-$height-box\@$dpr.png"; + } } } @@ -756,7 +760,7 @@ sub read_original_image { } sub ensure_cached { - my ($r, $filename, $id, $dbwidth, $dbheight, $infobox, $xres, $yres, @otherres) = @_; + my ($r, $filename, $id, $dbwidth, $dbheight, $infobox, $dpr, $xres, $yres, @otherres) = @_; my ($new_dbwidth, $new_dbheight); @@ -767,7 +771,7 @@ sub ensure_cached { } } - my $cachename = get_cache_location($r, $id, $xres, $yres, $infobox); + my $cachename = get_cache_location($r, $id, $xres, $yres, $infobox, $dpr); my $err; if (! -r $cachename or (-M $cachename > -M $fname)) { # If we are in overload mode (aka Slashdot mode), refuse to generate @@ -800,12 +804,12 @@ sub ensure_cached { if (defined($xres) && defined($yres)) { ($width, $height) = scale_aspect($width, $height, $xres, $yres); } - $height = 24; + $height = 24 * $dpr; $img->Set(size=>($width . "x" . $height)); $img->Read('xc:white'); my $info = Image::ExifTool::ImageInfo($fname); - if (make_infobox($img, $info, $r)) { + if (make_infobox($img, $info, $r, $dpr)) { $img->Quantize(colors=>16, dither=>'False'); # Since the image is grayscale, ImageMagick overrides us and writes this @@ -838,7 +842,7 @@ sub ensure_cached { while (defined($xres) && defined($yres)) { my ($nxres, $nyres) = (shift @otherres, shift @otherres); - my $cachename = get_cache_location($r, $id, $xres, $yres, $infobox); + my $cachename = get_cache_location($r, $id, $xres, $yres, $infobox, $dpr); my $cimg; if (defined($nxres) && defined($nyres)) { @@ -863,7 +867,7 @@ sub ensure_cached { if (($nwidth >= 800 || $nheight >= 600 || $xres == -1) && $infobox ne 'nobox') { my $info = Image::ExifTool::ImageInfo($fname); - make_infobox($cimg, $info, $r); + make_infobox($cimg, $info, $r, 1); } # Strip EXIF tags etc. @@ -919,7 +923,7 @@ sub get_mimetype_from_filename { } sub make_infobox { - my ($img, $info, $r) = @_; + my ($img, $info, $r, $dpr) = @_; # The infobox is of the form # "Time - date - focal length, shutter time, aperture, sensitivity, exposure bias - flash", @@ -1048,7 +1052,7 @@ sub make_infobox { $font = '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf'; } - my (undef, undef, $h, undef, $w) = ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12)); + my (undef, undef, $h, undef, $w) = ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12*$dpr)); $tw += $w; $th = $h if ($h > $th); @@ -1057,7 +1061,7 @@ sub make_infobox { return 0 if ($tw > $img->Get('columns')); my $x = 0; - my $y = $img->Get('rows') - 24; + my $y = $img->Get('rows') - 24*$dpr; # Hit exact DCT blocks $y -= ($y % 8); @@ -1065,13 +1069,13 @@ sub make_infobox { my $points = sprintf "%u,%u %u,%u", $x, $y, ($img->Get('columns') - 1), ($img->Get('rows') - 1); my $lpoints = sprintf "%u,%u %u,%u", $x, $y, ($img->Get('columns') - 1), $y; $img->Draw(primitive=>'rectangle', stroke=>'white', fill=>'white', points=>$points); - $img->Draw(primitive=>'line', stroke=>'black', points=>$lpoints); + $img->Draw(primitive=>'line', stroke=>'black', strokewidth=>$dpr, points=>$lpoints); # Start writing out the text $x = ($img->Get('columns') - $tw) / 2; - my $room = ($img->Get('rows') - 1 - $y - $th); - $y = ($img->Get('rows') - 1) - $room/2; + my $room = ($img->Get('rows') - $dpr - $y - $th); + $y = ($img->Get('rows') - $dpr) - $room/2; for my $part (@parts) { my $font; @@ -1080,8 +1084,8 @@ sub make_infobox { } else { $font = '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf'; } - $img->Annotate(text=>$part->[0], font=>$font, pointsize=>12, x=>int($x), y=>int($y)); - $x += ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12))[4]; + $img->Annotate(text=>$part->[0], font=>$font, pointsize=>12*$dpr, x=>int($x), y=>int($y)); + $x += ($img->QueryFontMetrics(text=>$part->[0], font=>$font, pointsize=>12*$dpr))[4]; } return 1; diff --git a/perl/Sesse/pr0n/Image.pm b/perl/Sesse/pr0n/Image.pm index da45cfb..f4262e3 100644 --- a/perl/Sesse/pr0n/Image.pm +++ b/perl/Sesse/pr0n/Image.pm @@ -14,20 +14,21 @@ sub handler { # } # Find the event and file name - my ($event,$filename,$xres,$yres); + my ($event,$filename,$xres,$yres,$dpr); my $infobox = 'both'; if ($r->uri =~ m#^/([a-zA-Z0-9-]+)/original/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) { $event = $1; $filename = $3; $infobox = 'nobox' if (defined($2) && $2 eq 'nobox/'); $infobox = 'box' if (defined($2) && $2 eq 'box/'); - } elsif ($r->uri =~ m#^/([a-zA-Z0-9-]+)/(\d+)x(\d+)/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) { + } elsif ($r->uri =~ m#^/([a-zA-Z0-9-]+)/(\d+)x(\d+)(?:\@(\d+))?/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) { $event = $1; - $filename = $5; + $filename = $6; $xres = $2; $yres = $3; - $infobox = 'nobox' if (defined($4) && $4 eq 'nobox/'); - $infobox = 'box' if (defined($4) && $4 eq 'box/'); + $dpr = $4; + $infobox = 'nobox' if (defined($5) && $5 eq 'nobox/'); + $infobox = 'box' if (defined($5) && $5 eq 'box/'); } elsif ($r->uri =~ m#^/([a-zA-Z0-9-]+)/((?:no)?box/)?([a-zA-Z0-9._()-]+)$#) { $event = $1; $filename = $3; @@ -36,6 +37,7 @@ sub handler { $infobox = 'nobox' if (defined($2) && $2 eq 'nobox/'); $infobox = 'box' if (defined($2) && $2 eq 'box/'); } + $dpr //= 1; my ($id, $dbwidth, $dbheight); #if ($event eq 'single' && $filename =~ /^(\d+)\.jpeg$/) { @@ -52,7 +54,7 @@ sub handler { $dbheight = $ref->{'height'}; # Scale if we need to do so - my ($fname, $mime_type) = Sesse::pr0n::Common::ensure_cached($r, $filename, $id, $dbwidth, $dbheight, $infobox, $xres, $yres); + my ($fname, $mime_type) = Sesse::pr0n::Common::ensure_cached($r, $filename, $id, $dbwidth, $dbheight, $infobox, $dpr, $xres, $yres); # Output the image to the user if (!defined($mime_type)) { diff --git a/perl/Sesse/pr0n/WebDAV.pm b/perl/Sesse/pr0n/WebDAV.pm index 71cd8ba..21573c6 100644 --- a/perl/Sesse/pr0n/WebDAV.pm +++ b/perl/Sesse/pr0n/WebDAV.pm @@ -500,7 +500,7 @@ EOF if ($filename !~ /^\.(_|DS_Store)/) { # FIXME: Ideally we'd want to ensure cache of -1x-1 here as well (for NEFs), but that would # preclude mipmapping in its current form. - Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, undef, undef, "nobox", 80, 64, 320, 256); + Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, undef, undef, "nobox", 1, 80, 64, 320, 256); } # OK, we got this far, commit @@ -629,7 +629,7 @@ EOF or die "/usr/bin/exifautotran: $!"; # Make cache while we're at it. - Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, undef, undef, 1, 80, 64, 320, 256, -1, -1); + Sesse::pr0n::Common::ensure_cached($r, $filename, $newid, undef, undef, 1, 1, 80, 64, 320, 256, -1, -1); # OK, we got this far, commit $dbh->commit; diff --git a/perl/Sesse/pr0n/pr0n.pm b/perl/Sesse/pr0n/pr0n.pm index 0372c46..74d34f3 100644 --- a/perl/Sesse/pr0n/pr0n.pm +++ b/perl/Sesse/pr0n/pr0n.pm @@ -66,7 +66,7 @@ sub handler { $uri =~ /^\/\+all\/?$/ || $uri =~ /^\/\+tags\/[a-zA-Z0-9-]+\/?$/) { return Sesse::pr0n::Index::handler($r); - } elsif ($uri =~ m#^/[a-zA-Z0-9-]+/(\d+x\d+/|original/)?((?:no)?box/)?[a-zA-Z0-9._()-]+$#) { + } elsif ($uri =~ m#^/[a-zA-Z0-9-]+/(\d+x\d+(\@\d+)?/|original/)((?:no)?box/)?[a-zA-Z0-9._()-]+$#) { return Sesse::pr0n::Image::handler($r); } diff --git a/perl/update-image-cache.pl b/perl/update-image-cache.pl index a159e37..8a19841 100755 --- a/perl/update-image-cache.pl +++ b/perl/update-image-cache.pl @@ -121,13 +121,13 @@ while (my $ref = $q->fetchrow_hashref) { next unless $any_old; unlink (@files); if (scalar @bothres > 0) { - Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'both', sort_res(@bothres)); + Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'both', 1, sort_res(@bothres)); } if (scalar @noboxres > 0) { - Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'nobox', sort_res(@noboxres)); + Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'nobox', 1, sort_res(@noboxres)); } if (scalar @boxres > 0) { - Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'box', sort_res(@boxres)); + Sesse::pr0n::Common::ensure_cached($r, $ref->{'filename'}, $id, $ref->{'width'}, $ref->{'height'}, 'box', 1, sort_res(@boxres)); } my @newfiles = glob("../cache/$dir/$id-*.jpg");