2006-08-31 11:20:43 +00:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* Return a rounded pixel equivalent for a labeled CSS/SVG length.
|
|
|
|
|
* http://www.w3.org/TR/SVG11/coords.html#UnitIdentifiers
|
|
|
|
|
*
|
|
|
|
|
* @param $length String: CSS/SVG length.
|
2008-12-16 06:26:14 +00:00
|
|
|
* @param $viewportSize: Float optional scale for percentage units...
|
2008-12-16 05:45:28 +00:00
|
|
|
* @return float: length in pixels
|
2006-08-31 11:20:43 +00:00
|
|
|
*/
|
2008-12-16 05:39:11 +00:00
|
|
|
function wfScaleSVGUnit( $length, $viewportSize=512 ) {
|
2006-08-31 11:20:43 +00:00
|
|
|
static $unitLength = array(
|
|
|
|
|
'px' => 1.0,
|
|
|
|
|
'pt' => 1.25,
|
|
|
|
|
'pc' => 15.0,
|
|
|
|
|
'mm' => 3.543307,
|
|
|
|
|
'cm' => 35.43307,
|
|
|
|
|
'in' => 90.0,
|
2008-12-16 05:39:11 +00:00
|
|
|
'em' => 16.0, // fake it?
|
|
|
|
|
'ex' => 12.0, // fake it?
|
2006-08-31 11:20:43 +00:00
|
|
|
'' => 1.0, // "User units" pixels by default
|
|
|
|
|
);
|
2006-11-29 11:43:58 +00:00
|
|
|
$matches = array();
|
2008-12-09 00:26:09 +00:00
|
|
|
if( preg_match( '/^\s*(\d+(?:\.\d+)?)(em|ex|px|pt|pc|cm|mm|in|%|)\s*$/', $length, $matches ) ) {
|
2006-08-31 11:20:43 +00:00
|
|
|
$length = floatval( $matches[1] );
|
|
|
|
|
$unit = $matches[2];
|
2008-12-16 05:39:11 +00:00
|
|
|
if( $unit == '%' ) {
|
2008-12-16 05:45:28 +00:00
|
|
|
return $length * 0.01 * $viewportSize;
|
2008-12-16 05:39:11 +00:00
|
|
|
} else {
|
2008-12-16 05:45:28 +00:00
|
|
|
return $length * $unitLength[$unit];
|
2008-12-16 05:39:11 +00:00
|
|
|
}
|
2006-08-31 11:20:43 +00:00
|
|
|
} else {
|
|
|
|
|
// Assume pixels
|
2008-12-16 05:45:28 +00:00
|
|
|
return floatval( $length );
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-09 00:26:09 +00:00
|
|
|
class XmlSizeFilter {
|
2008-12-16 05:39:11 +00:00
|
|
|
const DEFAULT_WIDTH = 512;
|
|
|
|
|
const DEFAULT_HEIGHT = 512;
|
2008-12-09 00:26:09 +00:00
|
|
|
var $first = true;
|
2008-12-16 05:39:11 +00:00
|
|
|
var $width = self::DEFAULT_WIDTH;
|
|
|
|
|
var $height = self::DEFAULT_HEIGHT;
|
2008-12-09 00:26:09 +00:00
|
|
|
function filter( $name, $attribs ) {
|
|
|
|
|
if( $this->first ) {
|
2008-12-16 05:39:11 +00:00
|
|
|
$defaultWidth = self::DEFAULT_WIDTH;
|
|
|
|
|
$defaultHeight = self::DEFAULT_HEIGHT;
|
|
|
|
|
$aspect = 1.0;
|
|
|
|
|
$width = null;
|
|
|
|
|
$height = null;
|
|
|
|
|
|
|
|
|
|
if( isset( $attribs['viewBox'] ) ) {
|
|
|
|
|
// min-x min-y width height
|
|
|
|
|
$viewBox = preg_split( '/\s+/', trim( $attribs['viewBox'] ) );
|
|
|
|
|
if( count( $viewBox ) == 4 ) {
|
|
|
|
|
$viewWidth = wfScaleSVGUnit( $viewBox[2] );
|
|
|
|
|
$viewHeight = wfScaleSVGUnit( $viewBox[3] );
|
|
|
|
|
if( $viewWidth > 0 && $viewHeight > 0 ) {
|
|
|
|
|
$aspect = $viewWidth / $viewHeight;
|
|
|
|
|
$defaultHeight = $defaultWidth / $aspect;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-09 00:26:09 +00:00
|
|
|
if( isset( $attribs['width'] ) ) {
|
2008-12-16 05:39:11 +00:00
|
|
|
$width = wfScaleSVGUnit( $attribs['width'], $defaultWidth );
|
2008-12-09 00:26:09 +00:00
|
|
|
}
|
|
|
|
|
if( isset( $attribs['height'] ) ) {
|
2008-12-16 05:39:11 +00:00
|
|
|
$height = wfScaleSVGUnit( $attribs['height'], $defaultHeight );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !isset( $width ) && !isset( $height ) ) {
|
|
|
|
|
$width = $defaultWidth;
|
|
|
|
|
$height = $width / $aspect;
|
|
|
|
|
} elseif( isset( $width ) && !isset( $height ) ) {
|
|
|
|
|
$height = $width / $aspect;
|
|
|
|
|
} elseif( isset( $height ) && !isset( $width ) ) {
|
|
|
|
|
$width = $height * $aspect;
|
2008-12-09 00:26:09 +00:00
|
|
|
}
|
2008-12-16 05:39:11 +00:00
|
|
|
|
2008-12-16 05:45:28 +00:00
|
|
|
if( $width > 0 && $height > 0 ) {
|
|
|
|
|
$this->width = intval( round( $width ) );
|
|
|
|
|
$this->height = intval( round( $height ) );
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-09 00:26:09 +00:00
|
|
|
$this->first = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-31 11:20:43 +00:00
|
|
|
/**
|
|
|
|
|
* Compatible with PHP getimagesize()
|
|
|
|
|
* @todo support gzipped SVGZ
|
|
|
|
|
* @todo check XML more carefully
|
|
|
|
|
* @todo sensible defaults
|
|
|
|
|
*
|
|
|
|
|
* @param $filename String: full name of the file (passed to php fopen()).
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
function wfGetSVGsize( $filename ) {
|
2008-12-09 00:26:09 +00:00
|
|
|
$filter = new XmlSizeFilter();
|
|
|
|
|
$xml = new XmlTypeCheck( $filename, array( $filter, 'filter' ) );
|
|
|
|
|
if( $xml->wellFormed ) {
|
|
|
|
|
return array( $filter->width, $filter->height, 'SVG',
|
|
|
|
|
"width=\"$filter->width\" height=\"$filter->height\"" );
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
2008-12-09 00:26:09 +00:00
|
|
|
|
|
|
|
|
return false;
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determine if an image exists on the 'bad image list'.
|
|
|
|
|
*
|
2006-09-25 01:35:41 +00:00
|
|
|
* The format of MediaWiki:Bad_image_list is as follows:
|
|
|
|
|
* * Only list items (lines starting with "*") are considered
|
|
|
|
|
* * The first link on a line must be a link to a bad image
|
|
|
|
|
* * Any subsequent links on the same line are considered to be exceptions,
|
|
|
|
|
* i.e. articles where the image may occur inline.
|
|
|
|
|
*
|
WARNING: HUGE COMMIT
Doxygen documentation update:
* Changed alls @addtogroup to @ingroup. @addtogroup adds the comment to the group description, but doesn't add the file, class, function, ... to the group like @ingroup does. See for example http://svn.wikimedia.org/doc/group__SpecialPage.html where it's impossible to see related files, classes, ... that should belong to that group.
* Added @file to file description, it seems that it should be explicitely decalred for file descriptions, otherwise doxygen will think that the comment document the first class, variabled, function, ... that is in that file.
* Removed some empty comments
* Removed some ?>
Added following groups:
* ExternalStorage
* JobQueue
* MaintenanceLanguage
One more thing: there are still a lot of warnings when generating the doc.
2008-05-20 17:13:28 +00:00
|
|
|
* @param $name string the image name to check
|
|
|
|
|
* @param $contextTitle Title: the page on which the image occurs, if known
|
2006-08-31 11:20:43 +00:00
|
|
|
* @return bool
|
|
|
|
|
*/
|
2006-09-25 01:35:41 +00:00
|
|
|
function wfIsBadImage( $name, $contextTitle = false ) {
|
|
|
|
|
static $badImages = false;
|
2006-08-31 11:20:43 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2006-09-25 01:35:41 +00:00
|
|
|
|
2009-05-01 21:22:25 +00:00
|
|
|
# Handle redirects
|
|
|
|
|
$redirectTitle = RepoGroup::singleton()->checkRedirect( Title::makeTitle( NS_FILE, $name ) );
|
|
|
|
|
if( $redirectTitle ) {
|
|
|
|
|
$name = $redirectTitle->getDbKey();
|
|
|
|
|
}
|
|
|
|
|
|
2006-09-25 01:35:41 +00:00
|
|
|
# Run the extension hook
|
2006-08-31 11:20:43 +00:00
|
|
|
$bad = false;
|
2006-09-25 01:35:41 +00:00
|
|
|
if( !wfRunHooks( 'BadImage', array( $name, &$bad ) ) ) {
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $bad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !$badImages ) {
|
|
|
|
|
# Build the list now
|
|
|
|
|
$badImages = array();
|
2006-10-12 01:07:01 +00:00
|
|
|
$lines = explode( "\n", wfMsgForContentNoTrans( 'bad_image_list' ) );
|
2006-09-25 01:35:41 +00:00
|
|
|
foreach( $lines as $line ) {
|
|
|
|
|
# List items only
|
|
|
|
|
if ( substr( $line, 0, 1 ) !== '*' ) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Find all links
|
2006-11-29 11:43:58 +00:00
|
|
|
$m = array();
|
2006-09-25 01:35:41 +00:00
|
|
|
if ( !preg_match_all( '/\[\[:?(.*?)\]\]/', $line, $m ) ) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$exceptions = array();
|
|
|
|
|
$imageDBkey = false;
|
|
|
|
|
foreach ( $m[1] as $i => $titleText ) {
|
|
|
|
|
$title = Title::newFromText( $titleText );
|
|
|
|
|
if ( !is_null( $title ) ) {
|
|
|
|
|
if ( $i == 0 ) {
|
|
|
|
|
$imageDBkey = $title->getDBkey();
|
|
|
|
|
} else {
|
|
|
|
|
$exceptions[$title->getPrefixedDBkey()] = true;
|
|
|
|
|
}
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
2006-09-25 01:35:41 +00:00
|
|
|
|
|
|
|
|
if ( $imageDBkey !== false ) {
|
|
|
|
|
$badImages[$imageDBkey] = $exceptions;
|
|
|
|
|
}
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-04-14 07:45:50 +00:00
|
|
|
|
2006-09-25 01:35:41 +00:00
|
|
|
$contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() : false;
|
|
|
|
|
$bad = isset( $badImages[$name] ) && !isset( $badImages[$name][$contextKey] );
|
|
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
|
return $bad;
|
2006-08-31 11:20:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate the largest thumbnail width for a given original file size
|
|
|
|
|
* such that the thumbnail's height is at most $maxHeight.
|
|
|
|
|
* @param $boxWidth Integer Width of the thumbnail box.
|
|
|
|
|
* @param $boxHeight Integer Height of the thumbnail box.
|
|
|
|
|
* @param $maxHeight Integer Maximum height expected for the thumbnail.
|
|
|
|
|
* @return Integer.
|
|
|
|
|
*/
|
|
|
|
|
function wfFitBoxWidth( $boxWidth, $boxHeight, $maxHeight ) {
|
|
|
|
|
$idealWidth = $boxWidth * $maxHeight / $boxHeight;
|
|
|
|
|
$roundedUp = ceil( $idealWidth );
|
|
|
|
|
if( round( $roundedUp * $boxHeight / $boxWidth ) > $maxHeight )
|
|
|
|
|
return floor( $idealWidth );
|
|
|
|
|
else
|
|
|
|
|
return $roundedUp;
|
|
|
|
|
}
|