Index: trunk/phase3/includes/media/Bitmap.php |
— | — | @@ -8,6 +8,54 @@ |
9 | 9 | * @ingroup Media |
10 | 10 | */ |
11 | 11 | class BitmapHandler extends ImageHandler { |
| 12 | + function getParamMap() { |
| 13 | + return array( |
| 14 | + 'img_width' => 'width', |
| 15 | + 'img_crop' => 'crop', |
| 16 | + ); |
| 17 | + } |
| 18 | + function validateParam( $name, $value ) { |
| 19 | + if ( $name == 'crop' ) { |
| 20 | + return $this->splitCropParam( $value ) !== false; |
| 21 | + } else { |
| 22 | + return parent::validateParam( $name, $value ); |
| 23 | + } |
| 24 | + } |
| 25 | + function splitCropParam( $value ) { |
| 26 | + $parts = explode( 'x', $value ); |
| 27 | + if ( count( $parts ) > 4 ) |
| 28 | + return false; |
| 29 | + foreach ( $parts as &$part ) { |
| 30 | + $intVal = intval( $part ); |
| 31 | + if ( $intVal === 0 && !( $part === '0' || $part === '' ) ) |
| 32 | + return false; |
| 33 | + if ( $intVal < 0 ) |
| 34 | + return false; |
| 35 | + |
| 36 | + $part = $intVal; |
| 37 | + } |
| 38 | + |
| 39 | + return $parts; |
| 40 | + } |
| 41 | + |
| 42 | + function parseParamString( $str ) { |
| 43 | + $res = parent::parseParamString( $str ); |
| 44 | + if ( $res === false ) { |
| 45 | + $m = false; |
| 46 | + if ( preg_match( '/^(\d+)px-([x0-9])crop$/', $str, $m ) ) { |
| 47 | + return array( 'width' => $m[1], 'crop' => $m[2] ); |
| 48 | + } else { |
| 49 | + return false; |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + function makeParamString( $params ) { |
| 54 | + $res = parent::makeParamString( $params ); |
| 55 | + if ( !empty( $params['crop'] ) ) |
| 56 | + $res .= '-'.implode( 'x', $params['crop'] ).'crop'; |
| 57 | + return $res; |
| 58 | + } |
| 59 | + |
12 | 60 | function normaliseParams( $image, &$params ) { |
13 | 61 | global $wgMaxImageArea; |
14 | 62 | if ( !parent::normaliseParams( $image, $params ) ) { |
— | — | @@ -36,6 +84,45 @@ |
37 | 85 | $params['physicalHeight'] = $srcHeight; |
38 | 86 | return true; |
39 | 87 | } |
| 88 | + |
| 89 | + # Validate crop params |
| 90 | + if ( isset( $params['crop'] ) ) { |
| 91 | + # $cropParams = array( x, y, width, height ); |
| 92 | + $cropParams = $this->splitCropParam( $params['crop'] ); |
| 93 | + # Fill up params |
| 94 | + switch ( count( $cropParams ) ) { |
| 95 | + # All fall through |
| 96 | + case 1: |
| 97 | + $cropParams[1] = 0; |
| 98 | + case 2: |
| 99 | + $cropParams[2] = $srcWidth - $cropParams[0]; |
| 100 | + case 3: |
| 101 | + $cropParams[3] = $srcHeight - $cropParams[1]; |
| 102 | + } |
| 103 | + $cx = $cropParams[0] + $cropParams[2]; |
| 104 | + $cy = $cropParams[1] + $cropParams[3]; |
| 105 | + $targetWidth = $cropParams[2]; |
| 106 | + $targetHeight = $cropParams[3]; |
| 107 | + # Can't go outside image |
| 108 | + if ( $cx > $srcWidth || $cy > $srcHeight ) { |
| 109 | + # TODO: Maybe should fail gracefully? |
| 110 | + return false; |
| 111 | + } |
| 112 | + if ( $targetWidth == $srcWidth && $targetHeight == $srcHeight ) |
| 113 | + { |
| 114 | + # No need to crop |
| 115 | + $params['crop'] = false; |
| 116 | + } |
| 117 | + else |
| 118 | + { |
| 119 | + header("X-Size: {$targetWidth}x{$targetHeight}"); |
| 120 | + $params['crop'] = $cropParams; |
| 121 | + $params['height'] = $params['physicalHeight'] = File::scaleHeight( |
| 122 | + $targetWidth, $targetHeight, $params['width'] ); |
| 123 | + } |
| 124 | + } else { |
| 125 | + $params['crop'] = false; |
| 126 | + } |
40 | 127 | |
41 | 128 | return true; |
42 | 129 | } |
— | — | @@ -136,6 +223,13 @@ |
137 | 224 | } else { |
138 | 225 | $tempEnv = ''; |
139 | 226 | } |
| 227 | + |
| 228 | + if ( $params['crop'] ) { |
| 229 | + $crop = $params['crop']; |
| 230 | + $cropCmd = "-crop {$crop[2]}x{$crop[3]}+{$crop[0]}+{$crop[1]}"; |
| 231 | + } |
| 232 | + else |
| 233 | + $cropCmd = ''; |
140 | 234 | |
141 | 235 | # Specify white background color, will be used for transparent images |
142 | 236 | # in Internet Explorer/Windows instead of default black. |
— | — | @@ -147,7 +241,7 @@ |
148 | 242 | $cmd = |
149 | 243 | $tempEnv . |
150 | 244 | wfEscapeShellArg($wgImageMagickConvertCommand) . |
151 | | - " {$quality} -background white -size {$physicalWidth} ". |
| 245 | + " {$cropCmd} {$quality} -background white -size {$physicalWidth} ". |
152 | 246 | wfEscapeShellArg($srcPath . $frame) . |
153 | 247 | $animation . |
154 | 248 | // For the -resize option a "!" is needed to force exact size, |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -288,6 +288,7 @@ |
289 | 289 | 'img_text_bottom' => array( 1, 'text-bottom' ), |
290 | 290 | 'img_link' => array( 1, 'link=$1' ), |
291 | 291 | 'img_alt' => array( 1, 'alt=$1' ), |
| 292 | + 'img_crop' => array( 1, 'crop=$1' ), |
292 | 293 | 'int' => array( 0, 'INT:' ), |
293 | 294 | 'sitename' => array( 1, 'SITENAME' ), |
294 | 295 | 'ns' => array( 0, 'NS:' ), |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -192,6 +192,7 @@ |
193 | 193 | numbers outside the permitted ranges), etc. |
194 | 194 | ** The summary attribute has been removed from tables of contents. summary is |
195 | 195 | obsolete in HTML 5 and wasn't useful here anyway. |
| 196 | +* Added crop for inline images. |
196 | 197 | |
197 | 198 | === Bug fixes in 1.16 === |
198 | 199 | |