From c98344b5b36488668c350314e2631609135f2151 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Tue, 7 Feb 2017 09:15:32 -0500 Subject: [PATCH] Mw_parse: Add more support for thumbs --- 400_xowa/src/gplx/xowa/mws/Xomw_linker.java | 9 +- .../gplx/xowa/mws/filerepo/Xomw_FileRepo.java | 45 +- .../xowa/mws/filerepo/file/Xomw_File.java | 373 ++++++------ .../mws/filerepo/file/Xomw_LocalFile.java | 18 +- .../xowa/mws/media/Xomw_ImageHandler.java | 33 +- .../xowa/mws/media/Xomw_MediaHandler.java | 74 +-- .../mws/media/Xomw_MediaHandlerFactory.java | 2 +- .../mws/media/Xomw_MediaTransformOutput.java | 6 +- .../xowa/mws/media/Xomw_ThumbnailImage.java | 6 +- .../Xomw_TransformationalImageHandler.java | 548 +++++++++--------- .../xowa/mws/parsers/Xomw_parser_env.java | 1 + .../xowa/mws/parsers/lnkis/Xomw_lnki_wkr.java | 4 +- .../lnkis/Xomw_lnki_wkr__file__tst.java | 2 +- .../parsers/lnkis/Xomw_params_handler.java | 3 + 14 files changed, 574 insertions(+), 550 deletions(-) diff --git a/400_xowa/src/gplx/xowa/mws/Xomw_linker.java b/400_xowa/src/gplx/xowa/mws/Xomw_linker.java index e23fc4af7..a163c4ac2 100644 --- a/400_xowa/src/gplx/xowa/mws/Xomw_linker.java +++ b/400_xowa/src/gplx/xowa/mws/Xomw_linker.java @@ -154,7 +154,7 @@ public class Xomw_linker { // For caching health: If width scaled down due to upright // parameter, round to full __0 pixel to avoid the creation of a // lot of odd thumbs. - int pref_width = 0; + int pref_width = parser.Env().User__default__thumbsize; // pref_width = isset(frame_params['upright']) ? // round($wgThumbLimits[width_option] * frame_params['upright'], -1) : // $wgThumbLimits[width_option]; @@ -200,7 +200,7 @@ public class Xomw_linker { // Create a resized image, without the additional thumbnail features // $thumb = $file->transform(handler_params); // file.getPath() - thumb = new Xomw_MediaTransformOutput(file, file.getUrl(), null, file.getWidth(), file.getHeight()); + thumb = new Xomw_MediaTransformOutput(file, file.getUrl(), file.getUrl(), file.getWidth(), file.getHeight()); } else { thumb = null; @@ -320,7 +320,7 @@ public class Xomw_linker { else if (frame_params.framed != null) { // Use image dimensions, don't scale // thumb = $file->getUnscaledThumb(handler_params); - thumb = new Xomw_MediaTransformOutput(file, file.getUrl(), null, file.getWidth(), file.getHeight()); + thumb = new Xomw_MediaTransformOutput(file, file.getUrl(), file.getUrl(), file.getWidth(), file.getHeight()); no_scale = true; } else { @@ -331,7 +331,8 @@ public class Xomw_linker { handler_params.width = src_width; } // thumb = $file->transform(handler_params); - thumb = new Xomw_MediaTransformOutput(file, file.getUrl(), null, file.getWidth(), file.getHeight()); + thumb = file.transform(handler_params, 0); +// new Xomw_MediaTransformOutput(file, file.getUrl(), file.getUrl(), file.getWidth(), file.getHeight()); } if (thumb != null) { diff --git a/400_xowa/src/gplx/xowa/mws/filerepo/Xomw_FileRepo.java b/400_xowa/src/gplx/xowa/mws/filerepo/Xomw_FileRepo.java index 759d8892a..14391882c 100644 --- a/400_xowa/src/gplx/xowa/mws/filerepo/Xomw_FileRepo.java +++ b/400_xowa/src/gplx/xowa/mws/filerepo/Xomw_FileRepo.java @@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.mws.filerepo; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; +import gplx.xowa.mws.filerepo.file.*; import gplx.langs.phps.utls.*; /* TODO.XO: * getZoneUrl @@ -345,14 +346,14 @@ public class Xomw_FileRepo { // // return [ this.zones[zone]['container'], this.zones[zone]['directory'] ]; // } -// -// /** -// * Get the storage path corresponding to one of the zones -// * -// * @param String zone -// * @return String|null Returns null if the zone is not defined -// */ -// public function getZonePath(zone) { + + /** + * Get the storage path corresponding to one of the zones + * + * @param String zone + * @return String|null Returns null if the zone is not defined + */ + public byte[] getZonePath(int zone) { // list(container, super) = this.getZoneLocation(zone); // if (container === null || super === null) { // return null; @@ -363,8 +364,9 @@ public class Xomw_FileRepo { // } // // return "mwstore://backendName/{container}{super}"; -// } -// + return Bry_.Empty; + } + // /** // * Create a new File Object from the local repository // * @@ -1337,19 +1339,20 @@ public class Xomw_FileRepo { // // return status; // } -// -// /** -// * Checks existence of a a file -// * -// * @param String file Virtual URL (or storage path) of file to check -// * @return boolean -// */ -// public function fileExists(file) { -// result = this.fileExistsBatch([ file ]); + + /** + * Checks existence of a a file + * + * @param String file Virtual URL (or storage path) of file to check + * @return boolean + */ + public boolean fileExists(Xomw_File file) { +// result = this.fileExistsBatch(file); // // return result[0]; -// } -// + return file.exists(); + } + // /** // * Checks existence of an array of files. // * diff --git a/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_File.java b/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_File.java index d7e664c1b..f3de25a47 100644 --- a/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_File.java +++ b/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_File.java @@ -18,12 +18,12 @@ along with this program. If not, see . package gplx.xowa.mws.filerepo.file; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepo.*; import gplx.xowa.mws.media.*; import gplx.langs.phps.utls.*; -import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.parsers.lnkis.*; +import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.parsers.lnkis.*; +public class Xomw_File { /* TODO.XO: * P8: normalizeExtension * P8: normalizeTitle */ -public class Xomw_File { private final Xomw_parser_env env; // // Bitfield values akin to the Revision deletion constants // static final DELETED_FILE = 1; @@ -98,8 +98,8 @@ public class Xomw_File { /** @var String The name of a file from its title Object */ private byte[] name; -// /** @var String The storage path corresponding to one of the zones */ -// protected path; + /** @var String The storage path corresponding to one of the zones */ + private byte[] path; /** @var String Relative path including trailing slash */ private byte[] hashPath; @@ -129,7 +129,8 @@ public class Xomw_File { // // /** @var array Cache of tmp filepaths pointing to generated bucket thumbnails, keyed by width */ // protected tmpBucketedThumbCache = []; -// + + private byte[] relPath; // /** // * Call this constructor from child classes. // * @@ -385,29 +386,29 @@ public class Xomw_File { // return this.getUrl(); // } // } -// -// /** -// * Return the storage path to the file. Note that this does -// * not mean that a file actually exists under that location. -// * -// * This path depends on whether directory hashing is active or not, -// * i.e. whether the files are all found in the same directory, -// * or in hashed paths like /images/3/3c. -// * -// * Most callers don't check the return value, but ForeignAPIFile::getPath -// * returns false. -// * -// * @return String|boolean ForeignAPIFile::getPath can return false -// */ -// public function getPath() { -// if (!isset(this.path)) { -// this.assertRepoDefined(); -// this.path = this.repo.getZonePath('public') . '/' . this.getRel(); -// } -// -// return this.path; -// } -// + + /** + * Return the storage path to the file. Note that this does + * not mean that a file actually exists under that location. + * + * This path depends on whether directory hashing is active or not, + * i.e. whether the files are all found in the same directory, + * or in hashed paths like /images/3/3c. + * + * Most callers don't check the return value, but ForeignAPIFile::getPath + * returns false. + * + * @return String|boolean ForeignAPIFile::getPath can return false + */ + public byte[] getPath() { + if (this.path == null) { + // this.assertRepoDefined(); + this.path = Bry_.Add(this.repo.getZonePath(Xomw_FileRepo.Zone__public), Byte_ascii.Slash_bry, this.getRel()); + } + + return this.path; + } + // /** // * Get an FS copy or original of this file and return the path. // * Returns false on failure. Callers must not alter the file. @@ -462,7 +463,7 @@ public class Xomw_File { * @return boolean|int False on failure */ // @dflt: page = 1 - public int getHeight(int page) { + @gplx.Virtual public int getHeight(int page) { return -1; } public int getHeight() {return this.getHeight(1);} @@ -724,7 +725,7 @@ public class Xomw_File { */ public boolean canRender() { if (this.canRenderObj == null) { - this.canRenderVar = this.getHandler(env).canRender(this) && this.exists(); + this.canRenderVar = this.getHandler().canRender(this) && this.exists(); this.canRenderObj = this; } @@ -869,7 +870,7 @@ public class Xomw_File { */ public boolean exists() { // return this.getPath() && this.repo.fileExists(this.path); - return false; + return true; } // /** @@ -919,53 +920,57 @@ public class Xomw_File { // // return this.transform(hp); // } -// -// /** -// * Return the file name of a thumbnail with the specified parameters. -// * Use File::THUMB_FULL_NAME to always get a name like "-". -// * Otherwise, the format may be "-" or "-thumbnail.". -// * -// * @param array params Handler-specific parameters -// * @param int flags Bitfield that supports THUMB_* constants -// * @return String|null -// */ -// public function thumbName(params, flags = 0) { + + /** + * Return the file name of a thumbnail with the specified parameters. + * Use File::THUMB_FULL_NAME to always get a name like "-". + * Otherwise, the format may be "-" or "-thumbnail.". + * + * @param array paramsVar Handler-specific parameters + * @param int flags Bitfield that supports THUMB_* constants + * @return String|null + */ + public byte[] thumbName(Xomw_params_handler handlerParams) {return thumbName(handlerParams, 0);} + public byte[] thumbName(Xomw_params_handler handlerParams, int flags) { // name = (this.repo && !(flags & self::THUMB_FULL_NAME)) // ? this.repo.nameForThumb(this.getName()) // : this.getName(); -// -// return this.generateThumbName(name, params); -// } -// -// /** -// * Generate a thumbnail file name from a name and specified parameters -// * -// * @param String name -// * @param array params Parameters which will be passed to MediaHandler::makeParamString -// * @return String|null -// */ -// public function generateThumbName(name, params) { -// if (!this.getHandler()) { -// return null; -// } -// extension = this.getExtension(); + byte[] name = this.getName(); + + return this.generateThumbName(name, handlerParams); + } + + /** + * Generate a thumbnail file name from a name and specified parameters + * + * @param String name + * @param array paramsVar Parameters which will be passed to MediaHandler::makeParamString + * @return String|null + */ + public byte[] generateThumbName(byte[] name, Xomw_params_handler handlerParams) { + Xomw_MediaHandler handler = this.getHandler(); + if (handler == null) { + return null; + } + extension = this.getExtension(); // list(thumbExt,) = this.getHandler().getThumbType( -// extension, this.getMimeType(), params); -// thumbName = this.getHandler().makeParamString(params); -// +// extension, this.getMimeType(), paramsVar); + byte[] thumbName = handler.makeParamString(handlerParams); + // if (this.repo.supportsSha1URLs()) { // thumbName .= '-' . this.getSha1() . '.' . thumbExt; -// } else { -// thumbName .= '-' . name; -// +// } +// else { + thumbName = Bry_.Add(thumbName, Byte_ascii.Dash_bry, name); + // if (thumbExt != extension) { // thumbName .= ".thumbExt"; // } // } -// -// return thumbName; -// } -// + + return thumbName; + } + // /** // * Create a thumbnail of the image having the specified width/height. // * The thumbnail will not be created if the width is larger than the @@ -984,11 +989,11 @@ public class Xomw_File { // * @return String // */ // public function createThumb(width, height = -1) { -// params = [ 'width' => width ]; +// paramsVar = [ 'width' => width ]; // if (height != -1) { -// params['height'] = height; +// paramsVar['height'] = height; // } -// thumb = this.transform(params); +// thumb = this.transform(paramsVar); // if (!thumb || thumb.isError()) { // return ''; // } @@ -1001,41 +1006,40 @@ public class Xomw_File { // * // * @param String thumbPath Thumbnail storage path // * @param String thumbUrl Thumbnail URL -// * @param array params +// * @param array paramsVar // * @param int flags // * @return MediaTransformOutput // */ -// protected function transformErrorOutput(thumbPath, thumbUrl, params, flags) { +// protected function transformErrorOutput(thumbPath, thumbUrl, paramsVar, flags) { // global wgIgnoreImageErrors; // // handler = this.getHandler(); // if (handler && wgIgnoreImageErrors && !(flags & self::RENDER_NOW)) { -// return handler.getTransform(this, thumbPath, thumbUrl, params); +// return handler.getTransform(this, thumbPath, thumbUrl, paramsVar); // } else { // return new MediaTransformError('thumbnail_error', -// params['width'], 0, wfMessage('thumbnail-dest-create')); +// paramsVar['width'], 0, wfMessage('thumbnail-dest-create')); // } // } /** * Transform a media file * - * @param array An associative array of handler-specific parameters. + * @param array paramsVar An associative array of handler-specific parameters. * Typical keys are width, height and page. * @param int flags A bitfield, may contain self::RENDER_NOW to force rendering * @return ThumbnailImage|MediaTransformOutput|boolean False on failure */ // XO.MW.DFLT:flags=0; - public Object transform(Xomw_param_map paramsMap, int flags) { + public Xomw_MediaTransformOutput transform(Xomw_params_handler handlerParams, int flags) { // global wgThumbnailEpoch; - Object thumb = null; + Xomw_MediaTransformOutput thumb = null; do { if (!this.canRender()) { - thumb = this.iconThumb(); +// thumb = this.iconThumb(); break; // not a bitmap or renderable image, don't try } - // Get the descriptionUrl to embed it as comment into the thumbnail. Bug 19791. // descriptionUrl = this.getDescriptionUrl(); // if (descriptionUrl) { @@ -1051,13 +1055,13 @@ public class Xomw_File { // break; // } // } -// -// normalisedParams = paramsMap; + + Xomw_params_handler normalisedParams = handlerParams; // handler.normaliseParams(this, normalisedParams); -// -// thumbName = this.thumbName(normalisedParams); -// thumbUrl = this.getThumbUrl(thumbName); -// thumbPath = this.getThumbPath(thumbName); // final thumb path + + byte[] thumbName = this.thumbName(normalisedParams); + byte[] thumbUrl = this.getThumbUrl(thumbName); + byte[] thumbPath = this.getThumbPath(thumbName); // final thumb path if (this.repo != null) { // // Defer rendering if a 404 handler is set up... @@ -1077,11 +1081,11 @@ public class Xomw_File { // // XXX: Pass in the storage path even though we are not rendering anything // // and the path is supposed to be an FS path. This is due to getScalerType() // // getting called on the path and clobbering thumb.getUrl() if it's false. -// thumb = handler.getTransform(this, thumbPath, thumbUrl, paramsMap); + thumb = handler.getTransform(this, thumbPath, thumbUrl, handlerParams); // thumb.setStoragePath(thumbPath); -// break; + break; // } -// } + } // elseif (flags & self::RENDER_FORCE) { // wfDebug(__METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n"); // } @@ -1092,14 +1096,14 @@ public class Xomw_File { // thumb = this.transformErrorOutput(thumbPath, thumbUrl, paramsMap, flags); // break; // } - } - Object tmpFile = null; +// } +// Object tmpFile = null; // tmpFile = this.makeTransformTmpFile(thumbPath); // // if (!tmpFile) { // thumb = this.transformErrorOutput(thumbPath, thumbUrl, paramsMap, flags); // } else { - thumb = this.generateAndSaveThumb(tmpFile, paramsMap, flags); +// thumb = this.generateAndSaveThumb(tmpFile, paramsMap, flags); // } } while (thumb != null); @@ -1143,7 +1147,7 @@ public class Xomw_File { // statTiming = microtime(true) - starttime; // stats.timing('media.thumbnail.generate.transform', 1000 * statTiming); // -// if (!thumb) { // bad params? +// if (!thumb) { // bad paramsVar? // thumb = false; // } elseif (thumb.isError()) { // transform error // /** @var thumb MediaTransformError */ @@ -1177,21 +1181,21 @@ public class Xomw_File { // // /** // * Generates chained bucketed thumbnails if needed -// * @param array params +// * @param array paramsVar // * @param int flags // * @return boolean Whether at least one bucket was generated // */ -// protected function generateBucketsIfNeeded(params, flags = 0) { +// protected function generateBucketsIfNeeded(paramsVar, flags = 0) { // if (!this.repo -// || !isset(params['physicalWidth']) -// || !isset(params['physicalHeight']) +// || !isset(paramsVar['physicalWidth']) +// || !isset(paramsVar['physicalHeight']) // ) { // return false; // } // -// bucket = this.getThumbnailBucket(params['physicalWidth']); +// bucket = this.getThumbnailBucket(paramsVar['physicalWidth']); // -// if (!bucket || bucket == params['physicalWidth']) { +// if (!bucket || bucket == paramsVar['physicalWidth']) { // return false; // } // @@ -1203,10 +1207,10 @@ public class Xomw_File { // // starttime = microtime(true); // -// params['physicalWidth'] = bucket; -// params['width'] = bucket; +// paramsVar['physicalWidth'] = bucket; +// paramsVar['width'] = bucket; // -// params = this.getHandler().sanitizeParamsForBucketing(params); +// paramsVar = this.getHandler().sanitizeParamsForBucketing(paramsVar); // // tmpFile = this.makeTransformTmpFile(bucketPath); // @@ -1214,7 +1218,7 @@ public class Xomw_File { // return false; // } // -// thumb = this.generateAndSaveThumb(tmpFile, params, flags); +// thumb = this.generateAndSaveThumb(tmpFile, paramsVar, flags); // // buckettime = microtime(true) - starttime; // @@ -1235,14 +1239,14 @@ public class Xomw_File { // // /** // * Returns the most appropriate source image for the thumbnail, given a target thumbnail size -// * @param array params +// * @param array paramsVar // * @return array Source path and width/height of the source // */ -// public function getThumbnailSource(params) { +// public function getThumbnailSource(paramsVar) { // if (this.repo // && this.getHandler().supportsBucketing() -// && isset(params['physicalWidth']) -// && bucket = this.getThumbnailBucket(params['physicalWidth']) +// && isset(paramsVar['physicalWidth']) +// && bucket = this.getThumbnailBucket(paramsVar['physicalWidth']) // ) { // if (this.getWidth() != 0) { // bucketHeight = round(this.getHeight() * (bucket / this.getWidth())); @@ -1361,7 +1365,7 @@ public class Xomw_File { * @return MediaHandler|boolean Registered MediaHandler for file's MIME type * or false if none found */ - public Xomw_MediaHandler getHandler(Xomw_parser_env env) { + public Xomw_MediaHandler getHandler() { if (this.handler == null) { this.handler = env.MediaHandlerFactory().getHandler(this.getMimeType()); } @@ -1374,7 +1378,7 @@ public class Xomw_File { * * @return ThumbnailImage */ - private Object iconThumb() { +// private Object iconThumb() { // global wgResourceBasePath, IP; // assetsPath = "wgResourceBasePath/resources/assets/file-type-icons/"; // assetsDirectory = "IP/resources/assets/file-type-icons/"; @@ -1382,14 +1386,14 @@ public class Xomw_File { // try = [ 'fileicon-' . this.getExtension() . '.png', 'fileicon.png' ]; // foreach (try as icon) { // if (file_exists(assetsDirectory . icon)) { // always FS -// params = [ 'width' => 120, 'height' => 120 ]; +// paramsVar = [ 'width' => 120, 'height' => 120 ]; // -// return new ThumbnailImage(this, assetsPath . icon, false, params); +// return new ThumbnailImage(this, assetsPath . icon, false, paramsVar); // } // } - - return null; - } +// +// return null; +// } // /** // * Get last thumbnailing error. @@ -1407,7 +1411,7 @@ public class Xomw_File { // * @return array // */ // function getThumbnails() { -// return ...; +// return []; // } // // /** @@ -1502,16 +1506,19 @@ public class Xomw_File { return this.hashPath; } -// /** -// * Get the path of the file relative to the public zone root. -// * This function is overridden in OldLocalFile to be like getArchiveRel(). -// * -// * @return String -// */ -// function getRel() { -// return this.getHashPath() . this.getName(); -// } -// + /** + * Get the path of the file relative to the public zone root. + * This function is overridden in OldLocalFile to be like getArchiveRel(). + * + * @return String + */ + private byte[] getRel() { + if (relPath == null) { + this.relPath = Bry_.Add(this.getHashPath(), this.getName()); + } + return relPath; + } + // /** // * Get the path of an archived file relative to the public zone root // * @@ -1529,22 +1536,22 @@ public class Xomw_File { // // return path; // } -// -// /** -// * Get the path, relative to the thumbnail zone root, of the -// * thumbnail directory or a particular file if suffix is specified -// * -// * @param boolean|String suffix If not false, the name of a thumbnail file -// * @return String -// */ -// function getThumbRel(suffix = false) { -// path = this.getRel(); -// if (suffix !== false) { -// path .= '/' . suffix; -// } -// -// return path; -// } + + /** + * Get the path, relative to the thumbnail zone root, of the + * thumbnail directory or a particular file if suffix is specified + * + * @param boolean|String suffix If not false, the name of a thumbnail file + * @return String + */ + private byte[] getThumbRel(byte[] suffix) { + path = this.getRel(); + if (suffix != null) { + path = Bry_.Add(path, Byte_ascii.Slash_bry, suffix); + } + + return path; + } /** * Get urlencoded path of the file relative to the public zone root. @@ -1600,19 +1607,19 @@ public class Xomw_File { // return this.repo.getZonePath('thumb') . '/' . // this.getArchiveThumbRel(archiveName, suffix); // } -// -// /** -// * Get the path of the thumbnail directory, or a particular file if suffix is specified -// * -// * @param boolean|String suffix If not false, the name of a thumbnail file -// * @return String -// */ -// function getThumbPath(suffix = false) { -// this.assertRepoDefined(); -// -// return this.repo.getZonePath('thumb') . '/' . this.getThumbRel(suffix); -// } -// + + /** + * Get the path of the thumbnail directory, or a particular file if suffix is specified + * + * @param boolean|String suffix If not false, the name of a thumbnail file + * @return String + */ + public byte[] getThumbPath(byte[] suffix) { + // this.assertRepoDefined(); + + return Bry_.Add(this.repo.getZonePath(Xomw_FileRepo.Zone__thumb), Byte_ascii.Slash_bry, this.getThumbRel(suffix)); + } + // /** // * Get the path of the transcoded directory, or a particular file if suffix is specified // * @@ -1664,35 +1671,35 @@ public class Xomw_File { // // return path; // } -// -// /** -// * Get the URL of the zone directory, or a particular file if suffix is specified -// * -// * @param String zone Name of requested zone -// * @param boolean|String suffix If not false, the name of a file in zone -// * @return String Path -// */ -// function getZoneUrl(zone, suffix = false) { -// this.assertRepoDefined(); -// ext = this.getExtension(); -// path = this.repo.getZoneUrl(zone, ext) . '/' . this.getUrlRel(); -// if (suffix !== false) { -// path .= '/' . rawurlencode(suffix); -// } -// -// return path; -// } -// -// /** -// * Get the URL of the thumbnail directory, or a particular file if suffix is specified -// * -// * @param boolean|String suffix If not false, the name of a thumbnail file -// * @return String Path -// */ -// function getThumbUrl(suffix = false) { -// return this.getZoneUrl('thumb', suffix); -// } -// + + /** + * Get the URL of the zone directory, or a particular file if suffix is specified + * + * @param String zone Name of requested zone + * @param boolean|String suffix If not false, the name of a file in zone + * @return String Path + */ + private byte[] getZoneUrl(int zone, byte[] suffix) { + // this.assertRepoDefined(); + byte[] ext = this.getExtension(); + byte[] path = Bry_.Add(this.repo.getZoneUrl(zone, ext), Byte_ascii.Slash_bry, this.getUrlRel()); + if (suffix != null) { + path = Bry_.Add(path, Byte_ascii.Slash_bry, gplx.langs.htmls.encoders.Gfo_url_encoder_.Php_rawurlencode.Encode(suffix)); + } + + return path; + } + + /** + * Get the URL of the thumbnail directory, or a particular file if suffix is specified + * + * @param boolean|String suffix If not false, the name of a thumbnail file + * @return String Path + */ + private byte[] getThumbUrl(byte[] suffix) { + return this.getZoneUrl(Xomw_FileRepo.Zone__thumb, suffix); + } + // /** // * Get the URL of the transcoded directory, or a particular file if suffix is specified // * diff --git a/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_LocalFile.java b/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_LocalFile.java index 47726889c..c37d306f1 100644 --- a/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_LocalFile.java +++ b/400_xowa/src/gplx/xowa/mws/filerepo/file/Xomw_LocalFile.java @@ -706,13 +706,13 @@ public class Xomw_LocalFile extends Xomw_File {// static final VERSION = 10; // // } } -// /** -// * Return the height of the image -// * -// * @param int page -// * @return int -// */ -// public function getHeight( page = 1 ) { + /** + * Return the height of the image + * + * @param int page + * @return int + */ + @Override public int getHeight(int page) { // this.load(); // // if ( this.isMultipage() ) { @@ -729,9 +729,9 @@ public class Xomw_LocalFile extends Xomw_File {// static final VERSION = 10; // // return 0; // } // } else { -// return this.height; + return this.height; // } -// } + } // // /** // * Returns ID or name of user who uploaded the file diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_ImageHandler.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_ImageHandler.java index 576875562..541ddb39b 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_ImageHandler.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_ImageHandler.java @@ -18,7 +18,7 @@ along with this program. If not, see . package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.filerepo.file.*; import gplx.xowa.mws.parsers.lnkis.*; // MEMORY:only one instance per wiki -public class Xomw_ImageHandler extends Xomw_MediaHandler { private final Xomw_param_map paramMap = new Xomw_param_map(); +public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private final Xomw_param_map paramMap = new Xomw_param_map(); public Xomw_ImageHandler(byte[] key) {super(key); paramMap.Add(Xomw_param_itm.Mw__img_width, Xomw_param_map.Type__handler, Xomw_param_itm.Name_bry__width); } @@ -48,20 +48,23 @@ public class Xomw_ImageHandler extends Xomw_MediaHandler { private final Xomw } } -// public function makeParamString(params) { -// if (isset(params['physicalWidth'])) { -// width = params['physicalWidth']; -// } elseif (isset(params['width'])) { -// width = params['width']; -// } else { -// throw new MediaTransformInvalidParametersException('No width specified to ' . __METHOD__); -// } -// -// # Removed for ProofreadPage -// # width = intval(width); -// return "{width}px"; -// } -// + @Override public byte[] makeParamString(Xomw_params_handler handlerParams) { + int width = 0; + if (handlerParams.physicalWidth != -1) { + width = handlerParams.physicalWidth; + } + else if (handlerParams.width != -1) { + width = handlerParams.width; + } + else { + throw Err_.new_wo_type("No width specified to makeParamString"); + } + + // Removed for ProofreadPage + // width = intval(width); + return Bry_.Add(Int_.To_bry(width), Xomw_lnki_wkr.Bry__px); + } + // public function parseParamString(str) { // m = false; // if (preg_match('/^(\d+)px/', str, m)) { diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandler.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandler.java index 3ada77ecf..18fafe887 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandler.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandler.java @@ -24,7 +24,7 @@ public abstract class Xomw_MediaHandler { this.key = key; } -// static final TRANSFORM_LATER = 1; + private static final int TRANSFORM_LATER = 1; // static final METADATA_GOOD = true; // static final METADATA_BAD = false; // static final METADATA_COMPATIBLE = 2; // for old but backwards compatible. @@ -60,14 +60,14 @@ public abstract class Xomw_MediaHandler { */ public abstract boolean validateParam(int name_uid, byte[] val_bry, int val_int); -// /** -// * Merge a parameter array into a String appropriate for inclusion in filenames -// * -// * @param array $params Array of parameters that have been through normaliseParams. -// * @return String -// */ -// abstract public function makeParamString($params); -// + /** + * Merge a parameter array into a String appropriate for inclusion in filenames + * + * @param array paramsVar Array of parameters that have been through normaliseParams. + * @return String + */ + public abstract byte[] makeParamString(Xomw_params_handler handlerParams); + // /** // * Parse a param String made with makeParamString back into an array // * @@ -81,9 +81,9 @@ public abstract class Xomw_MediaHandler { // * Should be idempotent. // * Returns false if the parameters are unacceptable and the transform should fail // * @param File $image -// * @param array $params +// * @param array $paramsVar // */ -// abstract function normaliseParams($image, &$params); +// abstract function normaliseParams($image, &$paramsVar); // // /** // * Get an image size array like that returned by getimagesize(), or false if it @@ -241,26 +241,26 @@ public abstract class Xomw_MediaHandler { // * Return false to fall back to the regular getTransform(). // * @param File $image // * @param String $script -// * @param array $params +// * @param array $paramsVar // * @return boolean|ThumbnailImage // */ -// function getScriptedTransform($image, $script, $params) { +// function getScriptedTransform($image, $script, $paramsVar) { // return false; // } -// -// /** -// * Get a MediaTransformOutput Object representing the transformed output. Does not -// * actually do the transform. -// * -// * @param File $image The image Object -// * @param String $dstPath Filesystem destination path -// * @param String $dstUrl Destination URL to use in output HTML -// * @param array $params Arbitrary set of parameters validated by $this->validateParam() -// * @return MediaTransformOutput -// */ -// final function getTransform($image, $dstPath, $dstUrl, $params) { -// return $this->doTransform($image, $dstPath, $dstUrl, $params, self::TRANSFORM_LATER); -// } + + /** + * Get a MediaTransformOutput Object representing the transformed output. Does not + * actually do the transform. + * + * @param File $image The image Object + * @param String $dstPath Filesystem destination path + * @param String $dstUrl Destination URL to use in output HTML + * @param array $paramsVar Arbitrary set of parameters validated by $this->validateParam() + * @return MediaTransformOutput + */ + public Xomw_MediaTransformOutput getTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams) { + return this.doTransform(image, dstPath, dstUrl, handlerParams, TRANSFORM_LATER); + } /** * Get a MediaTransformOutput Object representing the transformed output. Does the @@ -269,23 +269,23 @@ public abstract class Xomw_MediaHandler { * @param File $image The image Object * @param String $dstPath Filesystem destination path * @param String $dstUrl Destination URL to use in output HTML - * @param array $Arbitrary set of parameters validated by $this->validateParam() + * @param array $paramsVar Arbitrary set of parameters validated by $this->validateParam() * Note: These parameters have *not* gone through $this->normaliseParams() * @param int $flags A bitfield, may contain self::TRANSFORM_LATER * @return MediaTransformOutput */ // XO.MW:flags=0 -// public abstract Object doTransform(Object image, Object dstPath, Object dstUrl, Xomw_param_map paramsMap, int flags); + public abstract Xomw_MediaTransformOutput doTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams, int flags); // /** // * Get the thumbnail extension and MIME type for a given source MIME type // * // * @param String $ext Extension of original file // * @param String $mime MIME type of original file -// * @param array $params Handler specific rendering parameters +// * @param array $paramsVar Handler specific rendering parameters // * @return array Thumbnail extension and MIME type // */ -// function getThumbType($ext, $mime, $params = null) { +// function getThumbType($ext, $mime, $paramsVar = null) { // $magic = MimeMagic::singleton(); // if (!$ext || $magic->isMatchingExtension($ext, $mime) === false) { // // The extension is not valid for this MIME type and we do @@ -308,7 +308,7 @@ public abstract class Xomw_MediaHandler { // * @return array // */ // public function getStreamHeaders($metadata) { -// return ...; +// return []; // } /** @@ -614,7 +614,7 @@ public abstract class Xomw_MediaHandler { // */ // static function getGeneralLongDesc($file) { // return wfMessage('file-info')->sizeParams($file->getSize()) -// ->params('' . $file->getMimeType() . '')->parse(); +// ->paramsVar('' . $file->getMimeType() . '')->parse(); // } // // /** @@ -828,13 +828,13 @@ public abstract class Xomw_MediaHandler { // } // // /** -// * Returns a normalised params array for which parameters have been cleaned up for bucketing +// * Returns a normalised paramsVar array for which parameters have been cleaned up for bucketing // * purposes -// * @param array $params +// * @param array $paramsVar // * @return array // */ -// public function sanitizeParamsForBucketing($params) { -// return $params; +// public function sanitizeParamsForBucketing($paramsVar) { +// return $paramsVar; // } // // /** diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandlerFactory.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandlerFactory.java index bbb565978..738a19db1 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandlerFactory.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaHandlerFactory.java @@ -25,7 +25,7 @@ public class Xomw_MediaHandlerFactory { public Xomw_MediaHandlerFactory() { // Default, MediaWiki core media handlers // 'image/jpeg' => JpegHandler::class, - handlers.Add(Mime__image__png, new Xomw_ImageHandler(Mime__image__png)); // PngHandler + handlers.Add(Mime__image__png, new Xomw_TransformationalImageHandler(Mime__image__png)); // PngHandler // 'image/gif' => GIFHandler::class, // 'image/tiff' => TiffHandler::class, // 'image/webp' => WebPHandler::class, diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaTransformOutput.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaTransformOutput.java index 2ba99461f..06a8259e4 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaTransformOutput.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_MediaTransformOutput.java @@ -20,10 +20,12 @@ import gplx.langs.htmls.*; import gplx.langs.phps.utls.*; import gplx.xowa.mws.filerepo.file.*; public class Xomw_MediaTransformOutput { - private int width = -1, height = -1; - public byte[] url; +// private final Xomw_File file; + private final byte[] url; + private final int width, height; private final List_adp attribs = List_adp_.New(), link_attribs = List_adp_.New(); public Xomw_MediaTransformOutput(Xomw_File file, byte[] url, byte[] path, int width, int height) { +// this.file = file; this.url = url; this.width = width; this.height = height; diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_ThumbnailImage.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_ThumbnailImage.java index 64bd86bf8..0d0d1211f 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_ThumbnailImage.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_ThumbnailImage.java @@ -19,9 +19,7 @@ package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa import gplx.xowa.mws.parsers.lnkis.*; import gplx.xowa.mws.filerepo.file.*; // Media transform output for images -// extends MediaTransformOutput { -public class Xomw_ThumbnailImage { - /** +public class Xomw_ThumbnailImage extends Xomw_MediaTransformOutput { /** * Get a thumbnail Object from a file and parameters. * If path is set to null, the output file is treated as a source copy. * If path is set to false, no output file will be created. @@ -33,7 +31,7 @@ public class Xomw_ThumbnailImage { * @param String|boolean path Filesystem path to the thumb * @param array parameters Associative array of parameters */ - public Xomw_ThumbnailImage(Xomw_File file, byte[] url, byte[] path, Xomw_param_map parameters) { + public Xomw_ThumbnailImage(Xomw_File file, byte[] url, byte[] path, Xomw_params_handler parameters) {super(file, url, path, parameters.width, parameters.height); // defaults = [ // 'page' => false, // 'lang' => false diff --git a/400_xowa/src/gplx/xowa/mws/media/Xomw_TransformationalImageHandler.java b/400_xowa/src/gplx/xowa/mws/media/Xomw_TransformationalImageHandler.java index a797b022a..dfafb0423 100644 --- a/400_xowa/src/gplx/xowa/mws/media/Xomw_TransformationalImageHandler.java +++ b/400_xowa/src/gplx/xowa/mws/media/Xomw_TransformationalImageHandler.java @@ -16,31 +16,35 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; -public class Xomw_TransformationalImageHandler { +import gplx.xowa.mws.filerepo.file.*; +import gplx.xowa.mws.parsers.lnkis.*; +public class Xomw_TransformationalImageHandler extends Xomw_ImageHandler { public Xomw_TransformationalImageHandler(byte[] key) {super(key); + } + // /** -// * @param File $image -// * @param array $params Transform parameters. Entries with the keys 'width' +// * @param File image +// * @param array paramsVar Transform parameters. Entries with the keys 'width' // * and 'height' are the respective screen width and height, while the keys // * 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions. // * @return boolean // */ -// function normaliseParams( $image, &$params ) { -// if ( !parent::normaliseParams( $image, $params ) ) { +// function normaliseParams(image, ¶msVar) { +// if (!parent::normaliseParams(image, paramsVar)) { // return false; // } // -// # Obtain the source, pre-rotation dimensions -// $srcWidth = $image->getWidth( $params['page'] ); -// $srcHeight = $image->getHeight( $params['page'] ); +// // Obtain the source, pre-rotation dimensions +// srcWidth = image.getWidth(paramsVar['page']); +// srcHeight = image.getHeight(paramsVar['page']); // -// # Don't make an image bigger than the source -// if ( $params['physicalWidth'] >= $srcWidth ) { -// $params['physicalWidth'] = $srcWidth; -// $params['physicalHeight'] = $srcHeight; +// // Don't make an image bigger than the source +// if (paramsVar['physicalWidth'] >= srcWidth) { +// paramsVar['physicalWidth'] = srcWidth; +// paramsVar['physicalHeight'] = srcHeight; // -// # Skip scaling limit checks if no scaling is required -// # due to requested size being bigger than source. -// if ( !$image->mustRender() ) { +// // Skip scaling limit checks if no scaling is required +// // due to requested size being bigger than source. +// if (!image.mustRender()) { // return true; // } // } @@ -56,228 +60,230 @@ public class Xomw_TransformationalImageHandler { // * stored as raw landscape with 90-degress rotation, the resulting size // * will be wider than it is tall. // * -// * @param array $params Parameters as returned by normaliseParams -// * @param int $rotation The rotation angle that will be applied -// * @return array ($width, $height) array +// * @param array paramsVar Parameters as returned by normaliseParams +// * @param int rotation The rotation angle that will be applied +// * @return array (width, height) array // */ -// public function extractPreRotationDimensions( $params, $rotation ) { -// if ( $rotation == 90 || $rotation == 270 ) { -// # We'll resize before rotation, so swap the dimensions again -// $width = $params['physicalHeight']; -// $height = $params['physicalWidth']; +// public function extractPreRotationDimensions(paramsVar, rotation) { +// if (rotation == 90 || rotation == 270) { +// // We'll resize before rotation, so swap the dimensions again +// width = paramsVar['physicalHeight']; +// height = paramsVar['physicalWidth']; // } else { -// $width = $params['physicalWidth']; -// $height = $params['physicalHeight']; +// width = paramsVar['physicalWidth']; +// height = paramsVar['physicalHeight']; // } // -// return [ $width, $height ]; +// return [ width, height ]; // } // -// /** -// * Create a thumbnail. -// * -// * This sets up various parameters, and then calls a helper method -// * based on $this->getScalerType in order to scale the image. -// * -// * @param File $image -// * @param String $dstPath -// * @param String $dstUrl -// * @param array $params -// * @param int $flags -// * @return MediaTransformError|ThumbnailImage|TransformParameterError -// */ -// function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) { -// if ( !$this->normaliseParams( $image, $params ) ) { -// return new TransformParameterError( $params ); + /** + * Create a thumbnail. + * + * This sets up various parameters, and then calls a helper method + * based on this.getScalerType in order to scale the image. + * + * @param File image + * @param String dstPath + * @param String dstUrl + * @param array paramsVar + * @param int flags + * @return MediaTransformError|ThumbnailImage|TransformParameterError + */ + @Override public Xomw_MediaTransformOutput doTransform(Xomw_File image, byte[] dstPath, byte[] dstUrl, Xomw_params_handler handlerParams, int flags) { +// if (!this.normaliseParams(image, paramsVar)) { +// return new TransformParameterError(paramsVar); // } // -// # Create a parameter array to pass to the scaler -// $scalerParams = [ -// # The size to which the image will be resized -// 'physicalWidth' => $params['physicalWidth'], -// 'physicalHeight' => $params['physicalHeight'], -// 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", -// # The size of the image on the page -// 'clientWidth' => $params['width'], -// 'clientHeight' => $params['height'], -// # Comment as will be added to the Exif of the thumbnail -// 'comment' => isset( $params['descriptionUrl'] ) -// ? "File source: {$params['descriptionUrl']}" +// // Create a parameter array to pass to the scaler +// scalerParams = [ +// // The size to which the image will be resized +// 'physicalWidth' => paramsVar['physicalWidth'], +// 'physicalHeight' => paramsVar['physicalHeight'], +// 'physicalDimensions' => "{paramsVar['physicalWidth']}x{paramsVar['physicalHeight']}", +// // The size of the image on the page +// 'clientWidth' => paramsVar['width'], +// 'clientHeight' => paramsVar['height'], +// // Comment as will be added to the Exif of the thumbnail +// 'comment' => isset(paramsVar['descriptionUrl']) +// ? "File source: {paramsVar['descriptionUrl']}" // : '', -// # Properties of the original image -// 'srcWidth' => $image->getWidth(), -// 'srcHeight' => $image->getHeight(), -// 'mimeType' => $image->getMimeType(), -// 'dstPath' => $dstPath, -// 'dstUrl' => $dstUrl, -// 'interlace' => isset( $params['interlace'] ) ? $params['interlace'] : false, +// // Properties of the original image +// 'srcWidth' => image.getWidth(), +// 'srcHeight' => image.getHeight(), +// 'mimeType' => image.getMimeType(), +// 'dstPath' => dstPath, +// 'dstUrl' => dstUrl, +// 'interlace' => isset(paramsVar['interlace']) ? paramsVar['interlace'] : false, // ]; // -// if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) { -// $scalerParams['quality'] = 30; +// if (isset(paramsVar['quality']) && paramsVar['quality'] === 'low') { +// scalerParams['quality'] = 30; // } // // // For subclasses that might be paged. -// if ( $image->isMultipage() && isset( $params['page'] ) ) { -// $scalerParams['page'] = intval( $params['page'] ); +// if (image.isMultipage() && isset(paramsVar['page'])) { +// scalerParams['page'] = intval(paramsVar['page']); // } // -// # Determine scaler type -// $scaler = $this->getScalerType( $dstPath ); +// // Determine scaler type +// scaler = this.getScalerType(dstPath); // -// if ( is_array( $scaler ) ) { -// $scalerName = get_class( $scaler[0] ); +// if (is_array(scaler)) { +// scalerName = get_class(scaler[0]); // } else { -// $scalerName = $scaler; +// scalerName = scaler; // } // -// wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} " . -// "thumbnail at $dstPath using scaler $scalerName\n" ); +// wfDebug(__METHOD__ . ": creating {scalerParams['physicalDimensions']} " . +// "thumbnail at dstPath using scaler scalerName\n"); // -// if ( !$image->mustRender() && -// $scalerParams['physicalWidth'] == $scalerParams['srcWidth'] -// && $scalerParams['physicalHeight'] == $scalerParams['srcHeight'] -// && !isset( $scalerParams['quality'] ) +// if (!image.mustRender() && +// scalerParams['physicalWidth'] == scalerParams['srcWidth'] +// && scalerParams['physicalHeight'] == scalerParams['srcHeight'] +// && !isset(scalerParams['quality']) // ) { // -// # normaliseParams (or the user) wants us to return the unscaled image -// wfDebug( __METHOD__ . ": returning unscaled image\n" ); +// // normaliseParams (or the user) wants us to return the unscaled image +// wfDebug(__METHOD__ . ": returning unscaled image\n"); // -// return $this->getClientScalingThumbnailImage( $image, $scalerParams ); +// return this.getClientScalingThumbnailImage(image, scalerParams); // } // -// if ( $scaler == 'client' ) { -// # Client-side image scaling, use the source URL -// # Using the destination URL in a TRANSFORM_LATER request would be incorrect -// return $this->getClientScalingThumbnailImage( $image, $scalerParams ); +// if (scaler == 'client') { +// // Client-side image scaling, use the source URL +// // Using the destination URL in a TRANSFORM_LATER request would be incorrect +// return this.getClientScalingThumbnailImage(image, scalerParams); // } // -// if ( $image->isTransformedLocally() && !$this->isImageAreaOkForThumbnaling( $image, $params ) ) { -// global $wgMaxImageArea; -// return new TransformTooBigImageAreaError( $params, $wgMaxImageArea ); +// if (image.isTransformedLocally() && !this.isImageAreaOkForThumbnaling(image, paramsVar)) { +// global wgMaxImageArea; +// return new TransformTooBigImageAreaError(paramsVar, wgMaxImageArea); // } // -// if ( $flags & self::TRANSFORM_LATER ) { -// wfDebug( __METHOD__ . ": Transforming later per flags.\n" ); -// $newParams = [ -// 'width' => $scalerParams['clientWidth'], -// 'height' => $scalerParams['clientHeight'] +// if (flags & self::TRANSFORM_LATER) { +// wfDebug(__METHOD__ . ": Transforming later per flags.\n"); +// newParams = [ +// 'width' => scalerParams['clientWidth'], +// 'height' => scalerParams['clientHeight'] // ]; -// if ( isset( $params['quality'] ) ) { -// $newParams['quality'] = $params['quality']; +// if (isset(paramsVar['quality'])) { +// newParams['quality'] = paramsVar['quality']; // } -// if ( isset( $params['page'] ) && $params['page'] ) { -// $newParams['page'] = $params['page']; +// if (isset(paramsVar['page']) && paramsVar['page']) { +// newParams['page'] = paramsVar['page']; // } -// return new Xomw_ThumbnailImage( $image, $dstUrl, false, $newParams ); +// return new Xomw_ThumbnailImage(image, dstUrl, null, newParams); + return new Xomw_ThumbnailImage(image, dstUrl, null, handlerParams); // } // -// # Try to make a target path for the thumbnail -// if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) { -// wfDebug( __METHOD__ . ": Unable to create thumbnail destination " . -// "directory, falling back to client scaling\n" ); +// // Try to make a target path for the thumbnail +// if (!wfMkdirParents(dirname(dstPath), null, __METHOD__)) { +// wfDebug(__METHOD__ . ": Unable to create thumbnail destination " . +// "directory, falling back to client scaling\n"); // -// return $this->getClientScalingThumbnailImage( $image, $scalerParams ); +// return this.getClientScalingThumbnailImage(image, scalerParams); // } // -// # Transform functions and binaries need a FS source file -// $thumbnailSource = $this->getThumbnailSource( $image, $params ); +// // Transform functions and binaries need a FS source file +// thumbnailSource = this.getThumbnailSource(image, paramsVar); // // // If the source isn't the original, disable EXIF rotation because it's already been applied -// if ( $scalerParams['srcWidth'] != $thumbnailSource['width'] -// || $scalerParams['srcHeight'] != $thumbnailSource['height'] ) { -// $scalerParams['disableRotation'] = true; +// if (scalerParams['srcWidth'] != thumbnailSource['width'] +// || scalerParams['srcHeight'] != thumbnailSource['height']) { +// scalerParams['disableRotation'] = true; // } // -// $scalerParams['srcPath'] = $thumbnailSource['path']; -// $scalerParams['srcWidth'] = $thumbnailSource['width']; -// $scalerParams['srcHeight'] = $thumbnailSource['height']; +// scalerParams['srcPath'] = thumbnailSource['path']; +// scalerParams['srcWidth'] = thumbnailSource['width']; +// scalerParams['srcHeight'] = thumbnailSource['height']; // -// if ( $scalerParams['srcPath'] === false ) { // Failed to get local copy -// wfDebugLog( 'thumbnail', -// sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"', -// wfHostname(), $image->getName() ) ); +// if (scalerParams['srcPath'] === false) { // Failed to get local copy +// wfDebugLog('thumbnail', +// sprintf('Thumbnail failed on %s: could not get local copy of "%s"', +// wfHostname(), image.getName())); // -// return new MediaTransformError( 'thumbnail_error', -// $scalerParams['clientWidth'], $scalerParams['clientHeight'], -// wfMessage( 'filemissing' ) +// return new MediaTransformError('thumbnail_error', +// scalerParams['clientWidth'], scalerParams['clientHeight'], +// wfMessage('filemissing') // ); // } // -// # Try a hook. Called "Bitmap" for historical reasons. -// /** @var $mto MediaTransformOutput */ -// $mto = null; -// Hooks::run( 'BitmapHandlerTransform', [ $this, $image, &$scalerParams, &$mto ] ); -// if ( !is_null( $mto ) ) { -// wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" ); -// $scaler = 'hookaborted'; +// // Try a hook. Called "Bitmap" for historical reasons. +// /** @var mto MediaTransformOutput */ +// mto = null; +// Hooks::run('BitmapHandlerTransform', [ this, image, &scalerParams, &mto ]); +// if (!is_null(mto)) { +// wfDebug(__METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n"); +// scaler = 'hookaborted'; // } // -// // $scaler will return a MediaTransformError on failure, or false on success. +// // scaler will return a MediaTransformError on failure, or false on success. // // If the scaler is succesful, it will have created a thumbnail at the destination // // path. -// if ( is_array( $scaler ) && is_callable( $scaler ) ) { +// if (is_array(scaler) && is_callable(scaler)) { // // Allow subclasses to specify their own rendering methods. -// $err = call_user_func( $scaler, $image, $scalerParams ); +// err = call_user_func(scaler, image, scalerParams); // } else { -// switch ( $scaler ) { +// switch (scaler) { // case 'hookaborted': -// # Handled by the hook above -// $err = $mto->isError() ? $mto : false; +// // Handled by the hook above +// err = mto.isError() ? mto : false; // break; // case 'im': -// $err = $this->transformImageMagick( $image, $scalerParams ); +// err = this.transformImageMagick(image, scalerParams); // break; // case 'custom': -// $err = $this->transformCustom( $image, $scalerParams ); +// err = this.transformCustom(image, scalerParams); // break; // case 'imext': -// $err = $this->transformImageMagickExt( $image, $scalerParams ); +// err = this.transformImageMagickExt(image, scalerParams); // break; // case 'gd': // default: -// $err = $this->transformGd( $image, $scalerParams ); +// err = this.transformGd(image, scalerParams); // break; // } // } // -// # Remove the file if a zero-byte thumbnail was created, or if there was an error -// $removed = $this->removeBadFile( $dstPath, (boolean)$err ); -// if ( $err ) { -// # transform returned MediaTransforError -// return $err; -// } elseif ( $removed ) { -// # Thumbnail was zero-byte and had to be removed -// return new MediaTransformError( 'thumbnail_error', -// $scalerParams['clientWidth'], $scalerParams['clientHeight'], -// wfMessage( 'unknown-error' ) +// // Remove the file if a zero-byte thumbnail was created, or if there was an error +// removed = this.removeBadFile(dstPath, (boolean)err); +// if (err) { +// // transform returned MediaTransforError +// return err; +// } elseif (removed) { +// // Thumbnail was zero-byte and had to be removed +// return new MediaTransformError('thumbnail_error', +// scalerParams['clientWidth'], scalerParams['clientHeight'], +// wfMessage('unknown-error') // ); -// } elseif ( $mto ) { -// return $mto; +// } elseif (mto) { +// return mto; // } else { -// $newParams = [ -// 'width' => $scalerParams['clientWidth'], -// 'height' => $scalerParams['clientHeight'] +// newParams = [ +// 'width' => scalerParams['clientWidth'], +// 'height' => scalerParams['clientHeight'] // ]; -// if ( isset( $params['quality'] ) ) { -// $newParams['quality'] = $params['quality']; +// if (isset(paramsVar['quality'])) { +// newParams['quality'] = paramsVar['quality']; // } -// if ( isset( $params['page'] ) && $params['page'] ) { -// $newParams['page'] = $params['page']; +// if (isset(paramsVar['page']) && paramsVar['page']) { +// newParams['page'] = paramsVar['page']; // } -// return new ThumbnailImage( $image, $dstUrl, $dstPath, $newParams ); +// return new ThumbnailImage(image, dstUrl, dstPath, newParams); // } -// } -// +// return null; + } + // /** // * Get the source file for the transform // * -// * @param File $file -// * @param array $params +// * @param File file +// * @param array paramsVar // * @return array Array with keys width, height and path. // */ -// protected function getThumbnailSource( $file, $params ) { -// return $file->getThumbnailSource( $params ); +// protected function getThumbnailSource(file, paramsVar) { +// return file.getThumbnailSource(paramsVar); // } // // /** @@ -288,38 +294,38 @@ public class Xomw_TransformationalImageHandler { // * // * If specifying a custom scaler command with [ Obj, method ], // * the method in question should take 2 parameters, a File Object, -// * and a $scalerParams array with various options (See doTransform -// * for what is in $scalerParams). On error it should return a +// * and a scalerParams array with various options (See doTransform +// * for what is in scalerParams). On error it should return a // * MediaTransformError Object. On success it should return false, // * and simply make sure the thumbnail file is located at -// * $scalerParams['dstPath']. +// * scalerParams['dstPath']. // * // * If there is a problem with the output path, it returns "client" // * to do client side scaling. // * -// * @param String $dstPath -// * @param boolean $checkDstPath Check that $dstPath is valid +// * @param String dstPath +// * @param boolean checkDstPath Check that dstPath is valid // * @return String|Callable One of client, im, custom, gd, imext, or a Callable array. // */ -// abstract protected function getScalerType( $dstPath, $checkDstPath = true ); +// abstract protected function getScalerType(dstPath, checkDstPath = true); // // /** // * Get a ThumbnailImage that respresents an image that will be scaled // * client side // * -// * @param File $image File associated with this thumbnail -// * @param array $scalerParams Array with scaler params +// * @param File image File associated with this thumbnail +// * @param array scalerParams Array with scaler paramsVar // * @return ThumbnailImage // * // * @todo FIXME: No rotation support // */ -// protected function getClientScalingThumbnailImage( $image, $scalerParams ) { -// $params = [ -// 'width' => $scalerParams['clientWidth'], -// 'height' => $scalerParams['clientHeight'] +// protected function getClientScalingThumbnailImage(image, scalerParams) { +// paramsVar = [ +// 'width' => scalerParams['clientWidth'], +// 'height' => scalerParams['clientHeight'] // ]; // -// return new ThumbnailImage( $image, $image->getUrl(), null, $params ); +// return new ThumbnailImage(image, image.getUrl(), null, paramsVar); // } // // /** @@ -327,13 +333,13 @@ public class Xomw_TransformationalImageHandler { // * // * This is a stub method. The real method is in BitmapHander. // * -// * @param File $image File associated with this thumbnail -// * @param array $params Array with scaler params +// * @param File image File associated with this thumbnail +// * @param array paramsVar Array with scaler paramsVar // * // * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise // */ -// protected function transformImageMagick( $image, $params ) { -// return $this->getMediaTransformError( $params, "Unimplemented" ); +// protected function transformImageMagick(image, paramsVar) { +// return this.getMediaTransformError(paramsVar, "Unimplemented"); // } // // /** @@ -341,13 +347,13 @@ public class Xomw_TransformationalImageHandler { // * // * This is a stub method. The real method is in BitmapHander. // * -// * @param File $image File associated with this thumbnail -// * @param array $params Array with scaler params +// * @param File image File associated with this thumbnail +// * @param array paramsVar Array with scaler paramsVar // * // * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise // */ -// protected function transformImageMagickExt( $image, $params ) { -// return $this->getMediaTransformError( $params, "Unimplemented" ); +// protected function transformImageMagickExt(image, paramsVar) { +// return this.getMediaTransformError(paramsVar, "Unimplemented"); // } // // /** @@ -355,25 +361,25 @@ public class Xomw_TransformationalImageHandler { // * // * This is a stub method. The real method is in BitmapHander. // * -// * @param File $image File associated with this thumbnail -// * @param array $params Array with scaler params +// * @param File image File associated with this thumbnail +// * @param array paramsVar Array with scaler paramsVar // * // * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise // */ -// protected function transformCustom( $image, $params ) { -// return $this->getMediaTransformError( $params, "Unimplemented" ); +// protected function transformCustom(image, paramsVar) { +// return this.getMediaTransformError(paramsVar, "Unimplemented"); // } // // /** // * Get a MediaTransformError with error 'thumbnail_error' // * -// * @param array $params Parameter array as passed to the transform* functions -// * @param String $errMsg Error message +// * @param array paramsVar Parameter array as passed to the transform* functions +// * @param String errMsg Error message // * @return MediaTransformError // */ -// public function getMediaTransformError( $params, $errMsg ) { -// return new MediaTransformError( 'thumbnail_error', $params['clientWidth'], -// $params['clientHeight'], $errMsg ); +// public function getMediaTransformError(paramsVar, errMsg) { +// return new MediaTransformError('thumbnail_error', paramsVar['clientWidth'], +// paramsVar['clientHeight'], errMsg); // } // // /** @@ -381,32 +387,32 @@ public class Xomw_TransformationalImageHandler { // * // * This is a stub method. The real method is in BitmapHander. // * -// * @param File $image File associated with this thumbnail -// * @param array $params Array with scaler params +// * @param File image File associated with this thumbnail +// * @param array paramsVar Array with scaler paramsVar // * // * @return MediaTransformError Error Object if error occurred, false (=no error) otherwise // */ -// protected function transformGd( $image, $params ) { -// return $this->getMediaTransformError( $params, "Unimplemented" ); +// protected function transformGd(image, paramsVar) { +// return this.getMediaTransformError(paramsVar, "Unimplemented"); // } // // /** // * Escape a String for ImageMagick's property input (e.g. -set -comment) // * See InterpretImageProperties() in magick/property.c -// * @param String $s +// * @param String s // * @return String // */ -// function escapeMagickProperty( $s ) { +// function escapeMagickProperty(s) { // // Double the backslashes -// $s = str_replace( '\\', '\\\\', $s ); +// s = str_replace('\\', '\\\\', s); // // Double the percents -// $s = str_replace( '%', '%%', $s ); +// s = str_replace('%', '%%', s); // // Escape initial - or @ -// if ( strlen( $s ) > 0 && ( $s[0] === '-' || $s[0] === '@' ) ) { -// $s = '\\' . $s; +// if (strlen(s) > 0 && (s[0] === '-' || s[0] === '@')) { +// s = '\\' . s; // } // -// return $s; +// return s; // } // // /** @@ -421,69 +427,69 @@ public class Xomw_TransformationalImageHandler { // * in a directory, so we're better off escaping and waiting for the bugfix // * to filter down to users. // * -// * @param String $path The file path -// * @param boolean|String $scene The scene specification, or false if there is none +// * @param String path The file path +// * @param boolean|String scene The scene specification, or false if there is none // * @throws MWException // * @return String // */ -// function escapeMagickInput( $path, $scene = false ) { -// # Die on initial metacharacters (caller should prepend path) -// $firstChar = substr( $path, 0, 1 ); -// if ( $firstChar === '~' || $firstChar === '@' ) { -// throw new MWException( __METHOD__ . ': cannot escape this path name' ); +// function escapeMagickInput(path, scene = false) { +// // Die on initial metacharacters (caller should prepend path) +// firstChar = substr(path, 0, 1); +// if (firstChar === '~' || firstChar === '@') { +// throw new MWException(__METHOD__ . ': cannot escape this path name'); // } // -// # Escape glob chars -// $path = preg_replace( '/[*?\[\]{}]/', '\\\\\0', $path ); +// // Escape glob chars +// path = preg_replace('/[*?\[\]{}]/', '\\\\\0', path); // -// return $this->escapeMagickPath( $path, $scene ); +// return this.escapeMagickPath(path, scene); // } // // /** // * Escape a String for ImageMagick's output filename. See // * InterpretImageFilename() in magick/image.c. -// * @param String $path The file path -// * @param boolean|String $scene The scene specification, or false if there is none +// * @param String path The file path +// * @param boolean|String scene The scene specification, or false if there is none // * @return String // */ -// function escapeMagickOutput( $path, $scene = false ) { -// $path = str_replace( '%', '%%', $path ); +// function escapeMagickOutput(path, scene = false) { +// path = str_replace('%', '%%', path); // -// return $this->escapeMagickPath( $path, $scene ); +// return this.escapeMagickPath(path, scene); // } // // /** // * Armour a String against ImageMagick's GetPathComponent(). This is a // * helper function for escapeMagickInput() and escapeMagickOutput(). // * -// * @param String $path The file path -// * @param boolean|String $scene The scene specification, or false if there is none +// * @param String path The file path +// * @param boolean|String scene The scene specification, or false if there is none // * @throws MWException // * @return String // */ -// protected function escapeMagickPath( $path, $scene = false ) { -// # Die on format specifiers (other than drive letters). The regex is -// # meant to match all the formats you get from "convert -list format" -// if ( preg_match( '/^([a-zA-Z0-9-]+):/', $path, $m ) ) { -// if ( wfIsWindows() && is_dir( $m[0] ) ) { +// protected function escapeMagickPath(path, scene = false) { +// // Die on format specifiers (other than drive letters). The regex is +// // meant to match all the formats you get from "convert -list format" +// if (preg_match('/^([a-zA-Z0-9-]+):/', path, m)) { +// if (wfIsWindows() && is_dir(m[0])) { // // OK, it's a drive letter // // ImageMagick has a similar exception, see IsMagickConflict() // } else { -// throw new MWException( __METHOD__ . ': unexpected colon character in path name' ); +// throw new MWException(__METHOD__ . ': unexpected colon character in path name'); // } // } // -// # If there are square brackets, add a do-nothing scene specification -// # to force a literal interpretation -// if ( $scene === false ) { -// if ( strpos( $path, '[' ) !== false ) { -// $path .= '[0--1]'; +// // If there are square brackets, add a do-nothing scene specification +// // to force a literal interpretation +// if (scene === false) { +// if (strpos(path, '[') !== false) { +// path .= '[0--1]'; // } // } else { -// $path .= "[$scene]"; +// path .= "[scene]"; // } // -// return $path; +// return path; // } // // /** @@ -493,27 +499,27 @@ public class Xomw_TransformationalImageHandler { // * @return String|boolean Representing the IM version; false on error // */ // protected function getMagickVersion() { -// $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache(); -// $method = __METHOD__; -// return $cache->getWithSetCallback( +// cache = MediaWikiServices::getInstance().getLocalServerObjectCache(); +// method = __METHOD__; +// return cache.getWithSetCallback( // 'imagemagick-version', -// $cache::TTL_HOUR, -// function () use ( $method ) { -// global $wgImageMagickConvertCommand; -// -// $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version'; -// wfDebug( $method . ": Running convert -version\n" ); -// $retval = ''; -// $return = wfShellExec( $cmd, $retval ); -// $x = preg_match( -// '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches +// cache::TTL_HOUR, +// function () use (method) { +// global wgImageMagickConvertCommand; +// +// cmd = wfEscapeShellArg(wgImageMagickConvertCommand) . ' -version'; +// wfDebug(method . ": Running convert -version\n"); +// retval = ''; +// return = wfShellExec(cmd, retval); +// x = preg_match( +// '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', return, matches // ); -// if ( $x != 1 ) { -// wfDebug( $method . ": ImageMagick version check failed\n" ); +// if (x != 1) { +// wfDebug(method . ": ImageMagick version check failed\n"); // return false; // } // -// return $matches[1]; +// return matches[1]; // } // ); // } @@ -532,7 +538,7 @@ public class Xomw_TransformationalImageHandler { // * Should we automatically rotate an image based on exif // * // * @since 1.24 No longer static -// * @see $wgEnableAutoRotation +// * @see wgEnableAutoRotation // * @return boolean Whether auto rotation is enabled // */ // public function autoRotateEnabled() { @@ -544,26 +550,26 @@ public class Xomw_TransformationalImageHandler { // * // * This is a stub. See BitmapHandler::rotate. // * -// * @param File $file -// * @param array $params Rotate parameters. +// * @param File file +// * @param array paramsVar Rotate parameters. // * 'rotation' clockwise rotation in degrees, allowed are multiples of 90 // * @since 1.24 Is non-static. From 1.21 it was static // * @return boolean|MediaTransformError // */ -// public function rotate( $file, $params ) { -// return new MediaTransformError( 'thumbnail_error', 0, 0, -// get_class( $this ) . ' rotation not implemented' ); +// public function rotate(file, paramsVar) { +// return new MediaTransformError('thumbnail_error', 0, 0, +// get_class(this) . ' rotation not implemented'); // } // // /** // * Returns whether the file needs to be rendered. Returns true if the // * file requires rotation and we are able to rotate it. // * -// * @param File $file +// * @param File file // * @return boolean // */ -// public function mustRender( $file ) { -// return $this->canRotate() && $this->getRotation( $file ) != 0; +// public function mustRender(file) { +// return this.canRotate() && this.getRotation(file) != 0; // } // // /** @@ -571,35 +577,35 @@ public class Xomw_TransformationalImageHandler { // * // * Runs the 'BitmapHandlerCheckImageArea' hook. // * -// * @param File $file -// * @param array $params +// * @param File file +// * @param array paramsVar // * @return boolean // * @since 1.25 // */ -// public function isImageAreaOkForThumbnaling( $file, &$params ) { -// global $wgMaxImageArea; +// public function isImageAreaOkForThumbnaling(file, ¶msVar) { +// global wgMaxImageArea; // -// # For historical reasons, hook starts with BitmapHandler -// $checkImageAreaHookResult = null; +// // For historical reasons, hook starts with BitmapHandler +// checkImageAreaHookResult = null; // Hooks::run( // 'BitmapHandlerCheckImageArea', -// [ $file, &$params, &$checkImageAreaHookResult ] +// [ file, ¶msVar, &checkImageAreaHookResult ] // ); // -// if ( !is_null( $checkImageAreaHookResult ) ) { +// if (!is_null(checkImageAreaHookResult)) { // // was set by hook, so return that value -// return (boolean)$checkImageAreaHookResult; +// return (boolean)checkImageAreaHookResult; // } // -// $srcWidth = $file->getWidth( $params['page'] ); -// $srcHeight = $file->getHeight( $params['page'] ); +// srcWidth = file.getWidth(paramsVar['page']); +// srcHeight = file.getHeight(paramsVar['page']); // -// if ( $srcWidth * $srcHeight > $wgMaxImageArea -// && !( $file->getMimeType() == 'image/jpeg' -// && $this->getScalerType( false, false ) == 'im' ) +// if (srcWidth * srcHeight > wgMaxImageArea +// && !(file.getMimeType() == 'image/jpeg' +// && this.getScalerType(false, false) == 'im') // ) { -// # Only ImageMagick can efficiently downsize jpg images without loading -// # the entire file in memory +// // Only ImageMagick can efficiently downsize jpg images without loading +// // the entire file in memory // return false; // } // return true; diff --git a/400_xowa/src/gplx/xowa/mws/parsers/Xomw_parser_env.java b/400_xowa/src/gplx/xowa/mws/parsers/Xomw_parser_env.java index 498a3fd74..167f41cb3 100644 --- a/400_xowa/src/gplx/xowa/mws/parsers/Xomw_parser_env.java +++ b/400_xowa/src/gplx/xowa/mws/parsers/Xomw_parser_env.java @@ -19,6 +19,7 @@ package gplx.xowa.mws.parsers; import gplx.*; import gplx.xowa.*; import gplx.xo import gplx.xowa.mws.filerepo.file.*; import gplx.xowa.mws.media.*; public class Xomw_parser_env { public byte[] Lang__align_end = Bry_.new_a7("right"); + public int User__default__thumbsize = 220; public Xomw_MagicWordMgr Magic_word_mgr() {return magic_word_mgr;} private final Xomw_MagicWordMgr magic_word_mgr = new Xomw_MagicWordMgr(); public Xomw_message_mgr Message_mgr() {return message_mgr;} private final Xomw_message_mgr message_mgr = new Xomw_message_mgr(); public Xomw_file_finder File_finder() {return file_finder;} private Xomw_file_finder file_finder = new Xomw_file_finder__noop(); diff --git a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr.java b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr.java index 7bdd4e1ce..8fb230371 100644 --- a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr.java +++ b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr.java @@ -483,7 +483,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls Xomw_File file = fetchFileAndTitle(title, null); // Get parameter map - Xomw_MediaHandler handler = file == null ? null : file.getHandler(env); + Xomw_MediaHandler handler = file == null ? null : file.getHandler(); Xomw_image_params tmp_img_params = pctx.Lnki_wkr__make_image__img_params; this.getImageParams(tmp_img_params, handler); @@ -768,7 +768,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls img_size[0] = Bry_.To_int_or(src, w_bgn, w_end, 0); img_size[1] = Bry_.To_int_or(src, h_bgn, h_end, 0); } - private static final byte[] Bry__px = Bry_.new_a7("px"); + public static final byte[] Bry__px = Bry_.new_a7("px"); /** * Fetch a file and its title and register a reference to it. diff --git a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr__file__tst.java b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr__file__tst.java index 167419aaa..a4b2e861d 100644 --- a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr__file__tst.java +++ b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_lnki_wkr__file__tst.java @@ -27,7 +27,7 @@ public class Xomw_lnki_wkr__file__tst { fxt.Test__to_html("[[File:A.png]]", "A.png"); } @Test public void Thumb() { - fxt.Test__to_html("[[File:A.png|thumb]]", "
A.png
"); + fxt.Test__to_html("[[File:A.png|thumb]]", "
A.png
"); } @Test public void Size() { fxt.Test__to_html("[[File:A.png|123x456px]]", "A.png"); diff --git a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_params_handler.java b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_params_handler.java index f91d868f9..93cf15ed9 100644 --- a/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_params_handler.java +++ b/400_xowa/src/gplx/xowa/mws/parsers/lnkis/Xomw_params_handler.java @@ -20,14 +20,17 @@ public class Xomw_params_handler { public int width = -1; public int height = -1; public int page = -1; + public int physicalWidth = -1; public Xomw_params_handler Clear() { width = height = page = -1; + physicalWidth = -1; return this; } public void Copy_to(Xomw_params_handler src) { this.width = src.width; this.height = src.height; this.page = src.page; + this.physicalWidth = -1; } public void Set(int uid, byte[] val_bry, int val_int) { switch (uid) {