Mw_parse: Add fixBoxWidth, scaleByHeight, etc.

pull/620/head
gnosygnu 8 years ago
parent ff7952447d
commit 26527a8800

@ -22,6 +22,7 @@ public class Math_ {
public static double E = java.lang.Math.E;
public static int Ceil_as_int(double v) {return (int)Ceil(v);}
public static double Ceil(double v) {return java.lang.Math.ceil(v);}
public static int Floor_as_int(double v) {return (int)Floor(v);}
public static double Floor(double v) {return java.lang.Math.floor(v);}
public static double Round(double v, int places) {
return java.math.BigDecimal.valueOf(v).setScale(places, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();

@ -37,8 +37,6 @@ public class Xomw_linker {
private final byte[][] split_trail_rv = new byte[2][];
private Btrie_slim_mgr split_trail_trie;
private final Xomw_atr_mgr tmp_attribs = new Xomw_atr_mgr();
private final Xomw_MediaTransformOutputParams params_list = new Xomw_MediaTransformOutputParams();
private final Xomw_MediaTransformOutputParams mto_params = new Xomw_MediaTransformOutputParams();
private static final byte[] Atr__class = Bry_.new_a7("class"), Atr__rel = Bry_.new_a7("rel"), Atr__href = Bry_.new_a7("href"), Rel__nofollow = Bry_.new_a7("nofollow");
public static final byte[]
@ -65,7 +63,7 @@ public class Xomw_linker {
// @param Parser $parser
// @param Title $title Title Object of the file (not the currently viewed page)
// @param File $file File Object, or false if it doesn't exist
// @param array frame_params Associative array of parameters external to the media handler.
// @param array frameParams Associative array of parameters external to the media handler.
// Boolean parameters are indicated by presence or absence, the value is arbitrary and
// will often be false.
// thumbnail If present, downscale and frame
@ -93,7 +91,7 @@ public class Xomw_linker {
// @param int|null width_option Used by the parser to remember the user preference thumbnailsize
// @since 1.20
// @return String HTML for an image, with links, wrappers, etc.
public void makeImageLink(Bry_bfr bfr, Xomw_parser parser, Xoa_ttl title, Xomw_File file, Xomw_params_frame frame_params, Xomw_params_handler handler_params, Object time, byte[] query, Object widthOption) {
public void makeImageLink(Bry_bfr bfr, Xomw_parser_ctx pctx, Xomw_parser parser, Xoa_ttl title, Xomw_File file, Xomw_params_frame frameParams, Xomw_params_handler handler_params, Object time, byte[] query, Object widthOption) {
// XO.MW.HOOK:ImageBeforeProduceHTML
if (file != null && !file.allowInlineDisplay()) {
@ -103,25 +101,25 @@ public class Xomw_linker {
// Clean up parameters
int page = handler_params.page;
if (frame_params.align == null) {
frame_params.align = Bry_.Empty;
if (frameParams.align == null) {
frameParams.align = Bry_.Empty;
}
if (frame_params.alt == null) {
frame_params.alt = Bry_.Empty;
if (frameParams.alt == null) {
frameParams.alt = Bry_.Empty;
}
if (frame_params.title == null) {
frame_params.title = Bry_.Empty;
if (frameParams.title == null) {
frameParams.title = Bry_.Empty;
}
if (frame_params.cls == null) {
frame_params.cls = Bry_.Empty;
if (frameParams.cls == null) {
frameParams.cls = Bry_.Empty;
}
byte[] prefix = Bry_.Empty; byte[] postfix = Bry_.Empty;
if (Bry_.Eq(Align__frame__center, frame_params.align)) {
if (Bry_.Eq(Align__frame__center, frameParams.align)) {
prefix = Prefix__center;
postfix = Gfh_tag_.Div_rhs;
frame_params.align = Align__frame__none;
frameParams.align = Align__frame__none;
}
if (file != null && handler_params.width == Php_utl_.Null_int) {
if (handler_params.height != Php_utl_.Null_int && file.isVectorized()) {
@ -134,10 +132,10 @@ public class Xomw_linker {
handler_params.width = file.getWidth(page);
}
if ( frame_params.thumbnail != null
|| frame_params.manual_thumb != null
|| frame_params.framed != null
|| frame_params.frameless != null
if ( frameParams.thumbnail != null
|| frameParams.manual_thumb != null
|| frameParams.framed != null
|| frameParams.frameless != null
|| handler_params.width == Php_utl_.Null_int
) {
// global $wgThumbLimits, $wgThumbUpright;
@ -147,16 +145,16 @@ public class Xomw_linker {
// }
// Reduce width for upright images when parameter 'upright' is used
if (frame_params.upright == 0) {
// frame_params.upright = $wgThumbUpright;
if (frameParams.upright == 0) {
// frameParams.upright = $wgThumbUpright;
}
// 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 = parser.Env().User__default__thumbsize;
// pref_width = isset(frame_params['upright']) ?
// round($wgThumbLimits[width_option] * frame_params['upright'], -1) :
// pref_width = isset(frameParams['upright']) ?
// round($wgThumbLimits[width_option] * frameParams['upright'], -1) :
// $wgThumbLimits[width_option];
// Use width which is smaller: real image width or user preference width
@ -168,24 +166,24 @@ public class Xomw_linker {
}
}
if (frame_params.thumbnail != null || frame_params.manual_thumb != null
|| frame_params.framed != null
if (frameParams.thumbnail != null || frameParams.manual_thumb != null
|| frameParams.framed != null
) {
// Create a thumbnail. Alignment depends on the writing direction of
// the page content language (right-aligned for LTR languages,
// left-aligned for RTL languages)
// If a thumbnail width has not been provided, it is set
// to the default user option as specified in Language*.php
if (frame_params.align == Bry_.Empty) {
frame_params.align = parser.Env().Lang__align_end;
if (frameParams.align == Bry_.Empty) {
frameParams.align = parser.Env().Lang__align_end;
}
bfr.Add(prefix);
this.Make_thumb_link2(bfr, title, file, frame_params, handler_params, time, query);
this.Make_thumb_link2(bfr, pctx, title, file, frameParams, handler_params, time, query);
bfr.Add(postfix);
return;
}
if (file != null && frame_params.frameless != null) {
if (file != null && frameParams.frameless != null) {
int src_width = file.getWidth(page);
// For "frameless" option: do not present an image bigger than the
// source (for bitmap-style images). This is the same behavior as the
@ -206,26 +204,26 @@ public class Xomw_linker {
byte[] s = null;
if (thumb == null) {
// $s = self::makeBrokenImageLinkObj($title, frame_params['title'], '', '', '', $time == true);
// $s = self::makeBrokenImageLinkObj($title, frameParams['title'], '', '', '', $time == true);
s = Bry_.Empty;
}
else {
// self::processResponsiveImages($file, $thumb, handler_params);
params_list.Clear();
params_list.alt = frame_params.alt;
params_list.title = frame_params.title;
params_list.valign = frame_params.valign;
params_list.img_cls = frame_params.cls;
if (frame_params.border != null) {
params_list.img_cls = Xomw_params_frame.Cls_add(params_list.img_cls, Img_class__thumbborder);
Xomw_params_mto prms = pctx.Linker__makeImageLink__prms.Clear();
prms.alt = frameParams.alt;
prms.title = frameParams.title;
prms.valign = frameParams.valign;
prms.img_cls = frameParams.cls;
if (frameParams.border != null) {
prms.img_cls = Xomw_params_frame.Cls_add(prms.img_cls, Img_class__thumbborder);
}
// $params = self::getImageLinkMTOParams(frame_params, $query, $parser) + $params;
getImageLinkMTOParams(prms, frameParams, query, parser);
thumb.toHtml(tmp, tmp_2, params_list);
thumb.toHtml(tmp, tmp_2, prms);
s = tmp.To_bry_and_clear();
}
if (frame_params.align != Bry_.Empty) {
tmp.Add_str_a7("<div class=\"float").Add(frame_params.align);
if (frameParams.align != Bry_.Empty) {
tmp.Add_str_a7("<div class=\"float").Add(frameParams.align);
tmp.Add(s);
tmp.Add_str_a7("\">");
tmp.Add_str_a7("</div>");
@ -246,24 +244,24 @@ public class Xomw_linker {
// @param Parser|null $parser
// @return array
// XO.MW:SYNC:1.29; DATE:2017-02-03
public void Get_image_link_mto_params(Xomw_MediaTransformOutputParams mto_params, Xomw_params_frame frame_params, byte[] query, Xomw_parser parser) {
if (Php_utl_.isset(frame_params.link_url) && frame_params.link_url != Bry_.Empty) {
mto_params.custom_url_link = frame_params.link_url;
if (Php_utl_.isset(frame_params.link_target)) {
mto_params.custom_target_link = frame_params.link_target;
private static void getImageLinkMTOParams(Xomw_params_mto mto_params, Xomw_params_frame frameParams, byte[] query, Xomw_parser parser) {
if (Php_utl_.isset(frameParams.link_url) && frameParams.link_url != Bry_.Empty) {
mto_params.custom_url_link = frameParams.link_url;
if (Php_utl_.isset(frameParams.link_target)) {
mto_params.custom_target_link = frameParams.link_target;
}
if (parser != null) {
// extLinkAttrs = parser->getExternalLinkAttribs(frame_params['link-url']);
// extLinkAttrs = parser->getExternalLinkAttribs(frameParams['link-url']);
// foreach (extLinkAttrs as name => val) {
// // Currently could include 'rel' and 'target'
// mto_params['parser-extlink-' . name] = val;
// }
}
}
else if (Php_utl_.isset(frame_params.link_title) && frame_params.link_title != Bry_.Empty) {
// mto_params.custom_title_link = Title::newFromLinkTarget(Normalize_speecial_page(frame_params.link_title));
else if (Php_utl_.isset(frameParams.link_title) && frameParams.link_title != Bry_.Empty) {
// mto_params.custom_title_link = Title::newFromLinkTarget(Normalize_speecial_page(frameParams.link_title));
}
else if (!Php_utl_.Empty(frame_params.no_link)) {
else if (!Php_utl_.Empty(frameParams.no_link)) {
// No link
}
else {
@ -272,26 +270,26 @@ public class Xomw_linker {
}
}
public void Make_thumb_link2(Bry_bfr bfr, Xoa_ttl title, Xomw_File file, Xomw_params_frame frame_params, Xomw_params_handler handler_params, Object time, byte[] query) {
public void Make_thumb_link2(Bry_bfr bfr, Xomw_parser_ctx pctx, Xoa_ttl title, Xomw_File file, Xomw_params_frame frameParams, Xomw_params_handler handler_params, Object time, byte[] query) {
boolean exists = true; // = $file && $file->exists();
int page = handler_params.page;
if (frame_params.align == null) {
frame_params.align = Align__frame__right;
if (frameParams.align == null) {
frameParams.align = Align__frame__right;
}
if (frame_params.alt == null) {
frame_params.alt = Bry_.Empty;
if (frameParams.alt == null) {
frameParams.alt = Bry_.Empty;
}
if (frame_params.title == null) {
frame_params.title = Bry_.Empty;
if (frameParams.title == null) {
frameParams.title = Bry_.Empty;
}
if (frame_params.caption == null) {
frame_params.caption = Bry_.Empty;
if (frameParams.caption == null) {
frameParams.caption = Bry_.Empty;
}
if (handler_params.width == Php_utl_.Null_int) {
// Reduce width for upright images when parameter 'upright' is used
handler_params.width = frame_params.upright != Php_utl_.Null_int ? 130 : 180;
handler_params.width = frameParams.upright != Php_utl_.Null_int ? 130 : 180;
}
boolean no_scale = false;
boolean manual_thumb = false;
@ -302,9 +300,9 @@ public class Xomw_linker {
outer_width = handler_params.width + 2;
}
else {
if (frame_params.manual_thumb != null) {
if (frameParams.manual_thumb != null) {
// Use manually specified thumbnail
// $manual_title = Title::makeTitleSafe(NS_FILE, frame_params['manual_thumb']);
// $manual_title = Title::makeTitleSafe(NS_FILE, frameParams['manual_thumb']);
// if ($manual_title) {
// $manual_img = wfFindFile($manual_title);
// if ($manual_img) {
@ -315,7 +313,7 @@ public class Xomw_linker {
// }
// }
}
else if (frame_params.framed != null) {
else if (frameParams.framed != null) {
// Use image dimensions, don't scale
// thumb = $file->getUnscaledThumb(handler_params);
thumb = new Xomw_ThumbnailImage(file, file.getUrl(), file.getUrl(), file.getWidth(), file.getHeight());
@ -349,19 +347,19 @@ public class Xomw_linker {
// $url = wfAppendQuery($url, [ 'page' => $page ]);
// }
if (manual_thumb
&& frame_params.link_title != null
&& frame_params.link_url != null
&& frame_params.no_link != null) {
frame_params.link_url = url;
&& frameParams.link_title != null
&& frameParams.link_url != null
&& frameParams.no_link != null) {
frameParams.link_url = url;
}
int rv_bgn = bfr.Len();
bfr.Add_str_a7("<div class=\"thumb t").Add(frame_params.align)
bfr.Add_str_a7("<div class=\"thumb t").Add(frameParams.align)
.Add_str_a7("\"><div class=\"thumbinner\" style=\"width:").Add_int_variable(outer_width).Add_str_a7("px;\">");
byte[] zoom_icon = Bry_.Empty;
if (!exists) {
// $s .= self::makeBrokenImageLinkObj($title, frame_params.title, '', '', '', $time == true);
// $s .= self::makeBrokenImageLinkObj($title, frameParams.title, '', '', '', $time == true);
zoom_icon = Bry_.Empty;
}
else if (thumb == null) {
@ -373,13 +371,14 @@ public class Xomw_linker {
if (!no_scale && !manual_thumb) {
// self::processResponsiveImages($file, thumb, handler_params);
}
mto_params.Clear();
mto_params.alt = frame_params.alt;
mto_params.title = frame_params.title;
mto_params.img_cls = Xomw_params_frame.Cls_add(frame_params.cls, Img_class__thumbimage);
Get_image_link_mto_params(mto_params, frame_params, query, null);
thumb.toHtml(bfr, tmp, mto_params);
if (frame_params.framed != null) {
Xomw_params_mto prms = pctx.Linker__makeImageLink__prms.Clear();
prms.alt = frameParams.alt;
prms.title = frameParams.title;
prms.img_cls = Xomw_params_frame.Cls_add(frameParams.cls, Img_class__thumbimage);
getImageLinkMTOParams(prms, frameParams, query, null);
thumb.toHtml(bfr, tmp, prms);
if (frameParams.framed != null) {
zoom_icon = Bry_.Empty;
}
else {
@ -395,7 +394,7 @@ public class Xomw_linker {
zoom_icon = tmp.To_bry_and_clear();
}
}
bfr.Add_str_a7(" <div class=\"thumbcaption\">").Add(zoom_icon).Add(frame_params.caption).Add_str_a7("</div></div></div>");
bfr.Add_str_a7(" <div class=\"thumbcaption\">").Add(zoom_icon).Add(frameParams.caption).Add_str_a7("</div></div></div>");
Bry_.Replace_all_direct(bfr.Bfr(), Byte_ascii.Nl, Byte_ascii.Space, rv_bgn, bfr.Len()); // str_replace("\n", ' ', $s);
}
@ -647,18 +646,18 @@ public class Xomw_linker {
// public static function makeThumbLinkObj(Title $title, $file, $label = '', $alt,
// $align = 'right', $params = [], $framed = false, $manual_thumb = ""
// ) {
// frame_params = [
// frameParams = [
// 'alt' => $alt,
// 'caption' => $label,
// 'align' => $align
// ];
// if ($framed) {
// frame_params['framed'] = true;
// frameParams['framed'] = true;
// }
// if ($manual_thumb) {
// frame_params['manual_thumb'] = $manual_thumb;
// frameParams['manual_thumb'] = $manual_thumb;
// }
// return self::makeThumbLink2($title, $file, frame_params, $params);
// return self::makeThumbLink2($title, $file, frameParams, $params);
// }
// // Make a "broken" link to an image

@ -1984,25 +1984,26 @@ public class Xomw_File {
//
// return this.pageCount;
// }
//
// /**
// * Calculate the height of a thumbnail using the source and destination width
// *
// * @param int srcWidth
// * @param int srcHeight
// * @param int dstWidth
// *
// * @return int
// */
// static function scaleHeight(srcWidth, srcHeight, dstWidth) {
// // Exact integer multiply followed by division
// if (srcWidth == 0) {
// return 0;
// } else {
// return (int)round(srcHeight * dstWidth / srcWidth);
// }
// }
//
/**
* Calculate the height of a thumbnail us_ing the source and destination width
*
* @param int srcWidth
* @param int srcHeight
* @param int dstWidth
*
* @return int
*/
public static int scaleHeight(int srcWidth, int srcHeight, int dstWidth) {
// Exact integer multiply followed by division
if (srcWidth == 0) {
return 0;
}
else {
return (int)Math_.Round(srcHeight * dstWidth / srcWidth, 0);
}
}
// /**
// * Get an image size array like that returned by getImageSize(), or false if it
// * can't be determined. Loads the image size directly from the file ignoring caches.

@ -21,6 +21,7 @@ public class Xomw_file_finder__mock implements Xomw_file_finder {
private final Xomw_parser_env env;
public Xomw_file_finder__mock(Xomw_parser_env env) {this.env = env;}
private final Hash_adp hash = Hash_adp_.New();
public void Clear() {hash.Clear();}
public Xomw_File Find_file(Xoa_ttl ttl) {
return (Xomw_File)hash.Get_by(ttl.Page_db_as_str());
}

@ -19,9 +19,6 @@ package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa
import gplx.xowa.mws.filerepo.file.*; import gplx.xowa.mws.parsers.lnkis.*;
import gplx.xowa.mws.utls.*;
/* XO.TODO:
* parseParamString
* fitBoxWidth
* scaleHeight
* validateThumbParams
*/
// MEMORY:only one instance per wiki
@ -73,13 +70,20 @@ public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private fina
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)) {
// return [ 'width' => m[1] ];
// } else {
// return false;
// public Xomw_param_map parseParamString(byte[] src) {
// int len = src.length;
// // XO.MW.REGEX: if (preg_match('/^(\d+)px/', str, m)) {
// if ( len > 0 // at least one char
// && Byte_ascii.Is_num(src[0])) // 1st char is numeric
// {
// pos = Bry_find_.Find_fwd_while_num(src, 1, len); // skip numeric
// if (Bry_.Match(src, pos, len, Xomw_lnki_wkr.Bry__px)) { // matches "px"
// Xomw_params_handler rv = new Xomw_params_handler();
// rv.width = Bry_.To_int_or(src, 0, pos, Php_utl_.Null_int);
// return rv;
// }
// }
// return null;
// }
// function getScriptParams(paramsVar) {
@ -92,7 +96,7 @@ public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private fina
* @return boolean
*/
@Override public boolean normaliseParams(Xomw_File image, Xomw_params_handler handlerParams) {
// mimeType = image.getMimeType();
byte[] mimeType = image.getMimeType();
if (!Php_utl_.isset(handlerParams.width)) {
return false;
@ -119,7 +123,7 @@ public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private fina
// Height & width were both set
if (handlerParams.width * srcHeight > handlerParams.height * srcWidth) {
// Height is the relative smaller dimension, so scale width accordingly
// handlerParams.width = self::fitBoxWidth(srcWidth, srcHeight, handlerParams.height);
handlerParams.width = fitBoxWidth(srcWidth, srcHeight, handlerParams.height);
if (handlerParams.width == 0) {
// Very small image, so we need to rely on client side scaling :(
@ -141,57 +145,60 @@ public abstract class Xomw_ImageHandler extends Xomw_MediaHandler { private fina
// Because thumbs are only referred to by width, the height always needs
// to be scaled by the width to keep the thumbnail sizes consistent,
// even if it was set inside the if block above
// handlerParams.physicalHeight = File::scaleHeight(srcWidth, srcHeight,
// handlerParams.physicalWidth);
handlerParams.physicalHeight = Xomw_File.scaleHeight(srcWidth, srcHeight,
handlerParams.physicalWidth);
// Set the height if it was not validated in the if block higher up
if (!Php_utl_.isset(handlerParams.height) || handlerParams.height == -1) {
handlerParams.height = handlerParams.physicalHeight;
}
// if (!this.validateThumbParams(handlerParams.physicalWidth,
// handlerParams.physicalHeight, srcWidth, srcHeight, mimeType)
// ) {
// return false;
// }
if (!this.validateThumbParams(handlerParams, srcWidth, srcHeight, mimeType)
) {
return false;
}
return true;
}
/**
* Validate thumbnail parameters and fill in the correct height
*
* @param int width Specified width (input/output)
* @param int height Height (output only)
* @param int srcWidth Width of the source image
* @param int srcHeight Height of the source image
* @param String mimeType Unused
* @return boolean False to indicate that an error should be returned to the user.
*/
// XO.MW.NOTE: MW passes w and h by ref, but only changes h; XO will pass handlerParams directly
private boolean validateThumbParams(Xomw_params_handler handlerParams, int srcWidth, int srcHeight, byte[] mimeType) {
int width = handlerParams.physicalWidth;
int height = handlerParams.physicalHeight;
// width = intval(width);
// Sanity check width
if (width <= 0) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "validateThumbParams: Invalid destination width: width");
return false;
}
if (srcWidth <= 0) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "validateThumbParams: Invalid source width: srcWidth");
return false;
}
height = Xomw_File.scaleHeight(srcWidth, srcHeight, width);
if (height == 0) {
// Force height to be at least 1 pixel
height = 1;
}
handlerParams.height = height;
return true;
}
// /**
// * Validate thumbnail parameters and fill in the correct height
// *
// * @param int width Specified width (input/output)
// * @param int height Height (output only)
// * @param int srcWidth Width of the source image
// * @param int srcHeight Height of the source image
// * @param String mimeType Unused
// * @return boolean False to indicate that an error should be returned to the user.
// */
// function validateThumbParams(&width, &height, srcWidth, srcHeight, mimeType) {
// width = intval(width);
//
// # Sanity check width
// if (width <= 0) {
// wfDebug(__METHOD__ . ": Invalid destination width: width\n");
//
// return false;
// }
// if (srcWidth <= 0) {
// wfDebug(__METHOD__ . ": Invalid source width: srcWidth\n");
//
// return false;
// }
//
// height = File::scaleHeight(srcWidth, srcHeight, width);
// if (height == 0) {
// # Force height to be at least 1 pixel
// height = 1;
// }
//
// return true;
// }
//
// /**
// * @param File image
// * @param String script

@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.xowa.mws.utls.*;
import gplx.xowa.mws.parsers.*; import gplx.xowa.mws.parsers.lnkis.*;
import gplx.xowa.mws.filerepo.*; import gplx.xowa.mws.filerepo.file.*;
public class Xomw_ImageHandler__tst {
private final Xomw_ImageHandler__fxt fxt = new Xomw_ImageHandler__fxt();
@Before public void init() {
fxt.Init__file("A.png", 400, 200);
}
@Test public void normaliseParams() {
// widthOnly; "Because thumbs are only referred to by width, the height always needs"
fxt.Test__normaliseParams(fxt.Make__handlerParams(200), fxt.Make__handlerParams(200, 100, 200, 100));
}
}
class Xomw_ImageHandler__fxt {
private final Xomw_ImageHandler handler;
private final Xomw_FileRepo repo = new Xomw_FileRepo(Bry_.new_a7("/orig"), Bry_.new_a7("/thumb"));
private final Xomw_parser_env env = new Xomw_parser_env();
private Xomw_File file;
public Xomw_ImageHandler__fxt() {
handler = new Xomw_TransformationalImageHandler(Bry_.new_a7("test_handler"));
}
public Xomw_params_handler Make__handlerParams(int w) {return Make__handlerParams(w, Php_utl_.Null_int, Php_utl_.Null_int, Php_utl_.Null_int);}
public Xomw_params_handler Make__handlerParams(int w, int h, int phys_w, int phys_h) {
Xomw_params_handler rv = new Xomw_params_handler();
rv.width = w;
rv.height = h;
rv.physicalWidth = phys_w;
rv.physicalHeight = phys_h;
return rv;
}
public void Init__file(String title, int w, int h) {
this.file = new Xomw_LocalFile(env, Bry_.new_u8(title), repo, w, h, Xomw_MediaHandlerFactory.Mime__image__png);
}
public void Test__normaliseParams(Xomw_params_handler prms, Xomw_params_handler expd) {
// exec
handler.normaliseParams(file, prms);
// test
Gftest.Eq__int(expd.width, prms.width);
Gftest.Eq__int(expd.height, prms.height);
Gftest.Eq__int(expd.physicalWidth, prms.physicalWidth);
Gftest.Eq__int(expd.physicalHeight, prms.physicalHeight);
}
}

@ -616,25 +616,25 @@ public abstract class Xomw_MediaHandler {
// return wfMessage('file-info')->sizeParams($file->getSize())
// ->paramsVar('<span class="mime-type">' . $file->getMimeType() . '</span>')->parse();
// }
//
// /**
// * Calculate the largest thumbnail width for a given original file size
// * such that the thumbnail's height is at most $maxHeight.
// * @param int $boxWidth Width of the thumbnail box.
// * @param int $boxHeight Height of the thumbnail box.
// * @param int $maxHeight Maximum height expected for the thumbnail.
// * @return int
// */
// public static function fitBoxWidth($boxWidth, $boxHeight, $maxHeight) {
// $idealWidth = $boxWidth * $maxHeight / $boxHeight;
// $roundedUp = ceil($idealWidth);
// if (round($roundedUp * $boxHeight / $boxWidth) > $maxHeight) {
// return floor($idealWidth);
// } else {
// return $roundedUp;
// }
// }
//
/**
* Calculate the largest thumbnail width for a given original file size
* such that the thumbnail's height is at most $maxHeight.
* @param int $boxWidth Width of the thumbnail box.
* @param int $boxHeight Height of the thumbnail box.
* @param int $maxHeight Maximum height expected for the thumbnail.
* @return int
*/
public static int fitBoxWidth(int boxWidth, int boxHeight, int maxHeight) {
double idealWidth = boxWidth * maxHeight / boxHeight;
int roundedUp = Math_.Ceil_as_int(idealWidth);
if (Math_.Round(roundedUp * boxHeight / boxWidth, 0) > maxHeight) {
return Math_.Floor_as_int(idealWidth);
} else {
return roundedUp;
}
}
// /**
// * Shown in file history box on image description page.
// *

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.langs.htmls.*;
import gplx.xowa.mws.utls.*;
import gplx.xowa.mws.parsers.lnkis.*;
import gplx.xowa.mws.filerepo.file.*;
public abstract class Xomw_MediaTransformOutput {
public Xomw_MediaTransformOutput(Xomw_File file, byte[] url, byte[] path, int width, int height) {
@ -131,7 +132,7 @@ public abstract class Xomw_MediaTransformOutput {
*
* @return String
*/
public abstract void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_MediaTransformOutputParams options);
public abstract void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_params_mto options);
// /**
// * This will be overridden to return true in error classes

@ -129,7 +129,7 @@ public class Xomw_ThumbnailImage extends Xomw_MediaTransformOutput { private fin
// For images, desc-link and file-link are implemented as a click-through. For
// sounds and videos, they may be displayed in other ways.
// XO.MW:SYNC:1.29; DATE:2017-02-03
@Override public void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_MediaTransformOutputParams options) {
@Override public void toHtml(Bry_bfr bfr, Bry_bfr tmp, Xomw_params_mto options) {
byte[] alt = options.alt;
// byte[] query = options.desc_query;

@ -22,6 +22,7 @@ public class Xomw_parser_ctx {
public Xomw_image_params Lnki_wkr__make_image__img_params = new Xomw_image_params();
public byte[][] Lnki_wkr__make_image__match_magic_word = new byte[2][];
public int[] Lnki_wkr__make_image__img_size = new int[2];
public Xomw_params_mto Linker__makeImageLink__prms = new Xomw_params_mto();
public void Init_by_page(Xoa_ttl page_title) {
this.page_title = page_title;

@ -668,7 +668,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
// byte[] time = options.time;
Object time = null;
// options = $this->mOptions->getThumbSize()
linker.makeImageLink(bfr, parser, title, file, frameParams, handlerParams, time, desc_query, null);
linker.makeImageLink(bfr, pctx, parser, title, file, frameParams, handlerParams, time, desc_query, null);
// Give the handler a chance to modify the parser Object
// if (handler != null) {

@ -16,7 +16,9 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.parsers.*;
import org.junit.*; import gplx.core.tests.*; import gplx.xowa.mws.filerepo.*; import gplx.xowa.mws.filerepo.file.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.xowa.mws.filerepo.*; import gplx.xowa.mws.filerepo.file.*;
import gplx.xowa.mws.media.*;
public class Xomw_lnki_wkr__file__tst {
private final Xomw_lnki_wkr__fxt fxt = new Xomw_lnki_wkr__fxt();
@Before public void init() {
@ -24,14 +26,28 @@ public class Xomw_lnki_wkr__file__tst {
fxt.Init__file("A.png", 300, 200);
}
@Test public void Plain() {
fxt.Test__to_html("[[File:A.png]]", "<img alt='A.png' src='/orig/7/70/A.png' />");
fxt.Test__to_html("[[File:A.png]]", "<a><img alt='A.png' src='/orig/7/70/A.png' /></a>");
}
@Test public void Thumb() {
fxt.Test__to_html("[[File:A.png|thumb]]", "<div class='thumb tright'><div class='thumbinner' style='width:222px;'><a><img alt='A.png' src='/thumb/7/70/A.png/220px-A.png' class='thumbimage' /></a> <div class='thumbcaption'><div class='magnify'><a href='' class='internal'></a></div></div></div></div>");
}
@Test public void Size() {
fxt.Test__to_html("[[File:A.png|123x456px]]", "<img alt='A.png' src='/thumb/7/70/A.png/123px-A.png' />");
fxt.Test__to_html("[[File:A.png|123x456px]]", "<a><img alt='A.png' src='/thumb/7/70/A.png/123px-A.png' /></a>");
}
@Test public void fitBoxWidth() {
// COMMENT:"Height is the relative smaller dimension, so scale width accordingly"
// consider file of 200,100 (2:1)
// EX_1: view is 120,40 (3:1)
// - dimensions are either (a) 120,80 or (b) 80,40
// - use (b) 80,40
// EX_2: view is 120,80 (1.5:1)
// - dimensions are either (a) 120,60 or (b) 160,80
// - use (a) 120,60
fxt.Init__file("A.png", 200, 100);
fxt.Test__to_html__has("[[File:A.png|120x40px]]", "/80px-A.png");
fxt.Test__to_html__has("[[File:A.png|120x80px]]", "/120px-A.png");
}
@Test public void Test__parseWidthParam() {
int[] img_size = new int[2];
// WxHpx
@ -76,7 +92,7 @@ class Xomw_lnki_wkr__fxt {
wkr.Clear_state();
}
public void Init__file(String title, int w, int h) {
file_finder.Add(title, repo, w, h, gplx.xowa.files.Xof_ext_.Mime_type__ary[gplx.xowa.files.Xof_ext_.Id_png]);
file_finder.Add(title, repo, w, h, Xomw_MediaHandlerFactory.Mime__image__png);
}
public void Test__parse(String src_str, String expd) {
byte[] src_bry = Bry_.new_u8(src_str);
@ -85,11 +101,18 @@ class Xomw_lnki_wkr__fxt {
Gftest.Eq__ary__lines(expd, pbfr.Rslt().To_str_and_clear(), src_str);
}
public void Test__to_html(String src_str, String expd) {
if (apos) expd = gplx.langs.htmls.Gfh_utl.Replace_apos(expd);
Gftest.Eq__ary__lines(expd, Exec__to_html(src_str), src_str);
}
public void Test__to_html__has(String src_str, String expd) {
if (apos) expd = gplx.langs.htmls.Gfh_utl.Replace_apos(expd);
Gftest.Eq__bool_y(String_.Has(Exec__to_html(src_str), expd));
}
private String Exec__to_html(String src_str) {
byte[] src_bry = Bry_.new_u8(src_str);
wkr.Replace_internal_links(pctx, pbfr.Init(src_bry));
wkr.Replace_link_holders(pctx, pbfr);
if (apos) expd = gplx.langs.htmls.Gfh_utl.Replace_apos(expd);
Gftest.Eq__ary__lines(expd, pbfr.Rslt().To_str_and_clear(), src_str);
return pbfr.Rslt().To_str_and_clear();
}
public void Test__parseWidthParam(int[] img_size, String src_str, int expd_w, int expd_h) {
wkr.parseWidthParam(img_size, Bry_.new_u8(src_str));

@ -34,6 +34,10 @@ public class Xomw_params_frame {
public byte[] link_target = null;
public byte[] no_link = null;
public byte[] border = null;
public byte[] custom_url_link = null;
public byte[] custom_target_link = null;
public boolean desc_link = false;
public byte[] desc_query = null;
public double upright = -1;
public void Set(int uid, byte[] val_bry, int val_int) {
switch (uid) {
@ -41,13 +45,18 @@ public class Xomw_params_frame {
}
}
public Xomw_params_frame Clear() {
desc_link = false;
upright = -1;
align = valign = caption = frame = framed = frameless
= thumbnail = manual_thumb = alt = title = cls = img_cls
= link_title = link_url = link_target = no_link = null;
upright = -1;
= link_title = link_url = link_target = no_link
= custom_url_link = custom_target_link = desc_query
= null;
return this;
}
public void Copy_to(Xomw_params_frame src) {
this.desc_link = src.desc_link;
this.upright = src.upright;
this.align = src.align;
this.valign = src.valign;
this.caption = src.caption;
@ -65,7 +74,9 @@ public class Xomw_params_frame {
this.link_target = src.link_target;
this.no_link = src.no_link;
this.border = src.border;
this.upright = src.upright;
this.custom_url_link = src.custom_url_link;
this.custom_target_link = src.custom_target_link;
this.desc_query = src.desc_query;
}
public static byte[] Cls_add(byte[] lhs, byte[] rhs) {
return Bry_.Len_eq_0(lhs) ? rhs : Bry_.Add(lhs, Byte_ascii.Space_bry, rhs);

@ -15,8 +15,8 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.media; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_MediaTransformOutputParams {
package gplx.xowa.mws.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; import gplx.xowa.mws.parsers.*;
public class Xomw_params_mto {
public boolean desc_link;
public byte[] alt = null;
public byte[] title = null;
@ -32,12 +32,13 @@ public class Xomw_MediaTransformOutputParams {
public byte[] custom_target_link = null;
public byte[] parser_extlink_rel = null;
public byte[] parser_extlink_target = null;
public void Clear() {
public Xomw_params_mto Clear() {
desc_link = false;
alt = title = file_link = valign
= desc_query = override_width = override_height = no_dimensions
= custom_url_link = custom_title_link
= parser_extlink_rel = parser_extlink_target
= null;
return this;
}
}

@ -38,4 +38,5 @@ public class Php_utl_ {
return true;
}
public static final int Null_int = Int_.Max_value;
public static final byte[] Null_bry = null;
}

Loading…
Cancel
Save