WordPress.org

Make WordPress Core

Ticket #13556: 13556.off-by-one-pixel.002.diff

File 13556.off-by-one-pixel.002.diff, 3.1 KB (added by markjaquith, 8 years ago)
  • wp-includes/media.php

     
    278278
    279279        $width_ratio = $height_ratio = 1.0;
    280280
    281         if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width )
     281        if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
    282282                $width_ratio = $max_width / $current_width;
     283                $did_width = true;
     284        }
    283285
    284         if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height )
     286        if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
    285287                $height_ratio = $max_height / $current_height;
     288                $did_height = true;
     289        }
    286290
    287         // the smaller ratio is the one we need to fit it to the constraining box
    288         $ratio = min( $width_ratio, $height_ratio );
     291        // Calculate the larger/smaller ratios
     292        $smaller_ratio = min( $width_ratio, $height_ratio );
     293        $larger_ratio  = max( $width_ratio, $height_ratio );
    289294
    290         return array( intval($current_width * $ratio), intval($current_height * $ratio) );
     295        if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
     296                // The larger ratio is too big. It would result in an overflow.
     297                $ratio = $smaller_ratio;
     298        else
     299                // The larger ratio fits, and is likely to be a more "snug" fit.
     300                $ratio = $larger_ratio;
     301
     302        $w = intval( $current_width  * $ratio );
     303        $h = intval( $current_height * $ratio );
     304
     305        // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
     306        // We also have issues with recursive calls resulting in an ever-changing result. Contraining to the result of a constraint should yield the original result.
     307        // Thus we look for dimensions that are one pixel shy of the max value and bump them up
     308        if ( isset( $did_width ) && $did_width && $w == $max_width - 1 )
     309                $w = $max_width; // Round it up
     310        if ( isset( $did_height ) && $did_height && $h == $max_height - 1 )
     311                $h = $max_height; // Round it up
     312
     313        return array( $w, $h );
    291314}
    292315
    293316/**
     
    521544                                        // Skip images with unexpectedly divergent aspect ratios (crops)
    522545                                        // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
    523546                                        $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false );
    524                                         // If the size doesn't match exactly, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size
    525                                         if ( 'thumbnail' != $_size && ( !$maybe_cropped || $maybe_cropped[4] != $data['width'] || $maybe_cropped[5] != $data['height'] ) )
     547                                        // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size
     548                                        if ( 'thumbnail' != $_size && ( !$maybe_cropped || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) ) )
    526549                                                continue;
    527550                                        // If we're still here, then we're going to use this size
    528551                                        $file = $data['file'];