rename - work.

This commit is contained in:
Christopher Jeffrey 2015-07-12 05:19:00 -07:00
parent aa9a85be9d
commit abdd0a8c89
5 changed files with 34 additions and 902 deletions

View File

@ -94,11 +94,12 @@ var box = blessed.box({
// Append our box to the screen. // Append our box to the screen.
screen.append(box); screen.append(box);
// Add a PNG icon to the box (X11 only) // Add a png icon to the box
var icon = blessed.image({ var icon = blessed.image({
parent: box, parent: box,
top: 0, top: 0,
left: 0, left: 0,
itype: 'overlay',
width: 'shrink', width: 'shrink',
height: 'shrink', height: 'shrink',
file: __dirname + '/my-program-icon.png', file: __dirname + '/my-program-icon.png',
@ -172,8 +173,8 @@ screen.render();
- [Special Elements](#special-elements) - [Special Elements](#special-elements)
- [Terminal](#terminal-from-box) - [Terminal](#terminal-from-box)
- [Image](#image-from-box) - [Image](#image-from-box)
- [PNG](#png-from-box) - [ANSIImage](#ansiimage-from-box)
- [W3MImage](#w3mimage-from-box) - [OverlayImage](#overlayimage-from-box)
- [Video](#video-from-box) - [Video](#video-from-box)
- [Layout](#layout-from-element) - [Layout](#layout-from-element)
@ -1395,43 +1396,43 @@ manager. Requires term.js and pty.js to be installed. See
#### Image (from Box) #### Image (from Box)
Display an image in the terminal (jpeg, png, gif) using either blessed's Display an image in the terminal (jpeg, png, gif) using either blessed's
internal png/gif-to-terminal renderer (using a [PNG element](#png-from-box)) or internal png/gif-to-terminal renderer (using a [ANSIImage element](#ansiimage-from-box)) or
using `w3mimgdisplay` (using a [W3MImage element](#w3mimage-from-box)). using `w3mimgdisplay` (using a [OverlayImage element](#overlayimage-from-box)).
##### Options: ##### Options:
- Inherits all from Box. - Inherits all from Box.
- __file__ - Path to image. - __file__ - Path to image.
- __itype__ - `ansi` or `w3m`. Whether to render the file as ANSI art or using - __itype__ - `ansi` or `overlay`. Whether to render the file as ANSI art or
`w3m` to overlay Internally uses the PNG element. See the [PNG using `w3m` to overlay. See the [ANSIImage element](#ansiimage-from-box) for
element](#png-from-box) for more information/options. (__default__: `ansi`). more information/options. (__default__: `ansi`).
##### Properties: ##### Properties:
- Inherits all from Box. - Inherits all from Box.
- See [PNG element](#png-from-box) - See [ANSIImage element](#ansiimage-from-box)
- See [W3MImage element](#w3mimage-from-box) - See [OverlayImage element](#overlayimage-from-box)
##### Events: ##### Events:
- Inherits all from Box. - Inherits all from Box.
- See [PNG element](#png-from-box) - See [ANSIImage element](#ansiimage-from-box)
- See [W3MImage element](#w3mimage-from-box) - See [OverlayImage element](#overlayimage-from-box)
##### Methods: ##### Methods:
- Inherits all from Box. - Inherits all from Box.
- See [PNG element](#png-from-box) - See [ANSIImage element](#ansiimage-from-box)
- See [W3MImage element](#w3mimage-from-box) - See [OverlayImage element](#overlayimage-from-box)
#### PNG (from Box) #### ANSIImage (from Box)
Convert any `.png` file (or `.gif`, see below) to an ANSI image and display it Convert any `.png` file (or `.gif`, see below) to an ANSI image and display it
as an element. This differs from the `Image` element in that it uses blessed's as an element. This differs from the `Image` element in that it uses blessed's
internal PNG parser and does not require external dependencies. internal PNG/GIF parser and does not require external dependencies.
Blessed uses an internal from-scratch PNG reader because no other javascript Blessed uses an internal from-scratch PNG/GIF reader because no other javascript
PNG reader supports Adam7 interlaced images (much less pass the png test PNG reader supports Adam7 interlaced images (much less pass the png test
suite). suite).
@ -1452,12 +1453,12 @@ installed.
##### Options: ##### Options:
- Inherits all from Box. - Inherits all from Box.
- __file__ - URL or path to PNG file. Can also be a buffer. - __file__ - URL or path to PNG/GIF file. Can also be a buffer.
- __scale__ - Scale cellmap down (`0-1.0`) from its original pixel width/height - __scale__ - Scale cellmap down (`0-1.0`) from its original pixel width/height
(Default: `1.0`). (Default: `1.0`).
- __width/height__ - This differs from other element's `width` or `height` in - __width/height__ - This differs from other element's `width` or `height` in
that only one of them is needed: blessed will maintain the aspect ratio of that only one of them is needed: blessed will maintain the aspect ratio of
the image as it scales down to the proper number of cells. __NOTE__: PNG's the image as it scales down to the proper number of cells. __NOTE__: PNG/GIF's
are always automatically shrunken to size (based on scale) if a `width` or are always automatically shrunken to size (based on scale) if a `width` or
`height` is not given. `height` is not given.
- __ascii__ - Add various "density" ASCII characters over the rendering to give - __ascii__ - Add various "density" ASCII characters over the rendering to give
@ -1494,7 +1495,7 @@ installed.
- __clearImage()__ - Clear the image. - __clearImage()__ - Clear the image.
#### W3MImage (from Box) #### OverlayImage (from Box)
Display an image in the terminal (jpeg, png, gif) using w3mimgdisplay. Requires Display an image in the terminal (jpeg, png, gif) using w3mimgdisplay. Requires
w3m to be installed. X11 required: works in xterm, urxvt, and possibly other w3m to be installed. X11 required: works in xterm, urxvt, and possibly other
@ -1505,7 +1506,7 @@ terminals.
- Inherits all from Box. - Inherits all from Box.
- __file__ - Path to image. - __file__ - Path to image.
- __ansi__ - Render the file as ANSI art instead of using `w3m` to overlay - __ansi__ - Render the file as ANSI art instead of using `w3m` to overlay
Internally uses the PNG element. See the [PNG element](#png-from-box) for Internally uses the ANSIImage element. See the [ANSIImage element](#ansiimage-from-box) for
more information/options. (Default: `true`). more information/options. (Default: `true`).
- __w3m__ - Path to w3mimgdisplay. If a proper `w3mimgdisplay` path is not - __w3m__ - Path to w3mimgdisplay. If a proper `w3mimgdisplay` path is not
given, blessed will search the entire disk for the binary. given, blessed will search the entire disk for the binary.

View File

@ -37,8 +37,8 @@ widget.classes = [
'ListTable', 'ListTable',
'Terminal', 'Terminal',
'Image', 'Image',
'PNG', 'ANSIImage',
'W3MImage', 'OverlayImage',
'Video', 'Video',
'Layout' 'Layout'
]; ];

View File

@ -29,25 +29,25 @@ function Image(options) {
Box.call(this, options); Box.call(this, options);
if (options.itype === 'ansi' && this.type !== 'png') { if (options.itype === 'ansi' && this.type !== 'ansiimage') {
var PNG = require('./png'); var ANSIImage = require('./ansiimage');
Object.getOwnPropertyNames(PNG.prototype).forEach(function(key) { Object.getOwnPropertyNames(ANSIImage.prototype).forEach(function(key) {
if (key === 'type') return; if (key === 'type') return;
Object.defineProperty(this, key, Object.defineProperty(this, key,
Object.getOwnPropertyDescriptor(PNG.prototype, key)); Object.getOwnPropertyDescriptor(ANSIImage.prototype, key));
}, this); }, this);
PNG.call(this, options); ANSIImage.call(this, options);
return this; return this;
} }
if (options.itype === 'w3m' && this.type !== 'w3mimage') { if (options.itype === 'overlay' && this.type !== 'overlayimage') {
var W3MImage = require('./w3mimage'); var OverlayImage = require('./overlayimage');
Object.getOwnPropertyNames(W3MImage.prototype).forEach(function(key) { Object.getOwnPropertyNames(OverlayImage.prototype).forEach(function(key) {
if (key === 'type') return; if (key === 'type') return;
Object.defineProperty(this, key, Object.defineProperty(this, key,
Object.getOwnPropertyDescriptor(W3MImage.prototype, key)); Object.getOwnPropertyDescriptor(OverlayImage.prototype, key));
}, this); }, this);
W3MImage.call(this, options); OverlayImage.call(this, options);
return this; return this;
} }
} }

View File

@ -1,144 +0,0 @@
/**
* png.js - render PNGs as ANSI
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
* https://github.com/chjj/blessed
*/
/**
* Modules
*/
var cp = require('child_process')
, path = require('path')
, fs = require('fs');
var helpers = require('../helpers');
var colors = require('../colors');
var Node = require('./node');
var Box = require('./box');
var tng = require('../../vendor/tng');
/**
* PNG
*/
function PNG(options) {
var self = this;
if (!(this instanceof Node)) {
return new PNG(options);
}
options = options || {};
options.shrink = true;
Box.call(this, options);
this.scale = this.options.scale || 1.0;
this.options.animate = this.options.animate !== false;
this._noFill = true;
if (this.options.file) {
this.setImage(this.options.file);
}
this.screen.on('prerender', function() {
var lpos = self.lpos;
if (!lpos) return;
// prevent image from blending with itself if there are alpha channels
self.screen.clearRegion(lpos.xi, lpos.xl, lpos.yi, lpos.yl);
});
}
PNG.prototype.__proto__ = Box.prototype;
PNG.prototype.type = 'png';
PNG.curl = function(url) {
try {
return cp.execFileSync('curl',
['-s', '-A', '', url],
{ stdio: ['ignore', 'pipe', 'ignore'] });
} catch (e) {
;
}
try {
return cp.execFileSync('wget',
['-U', '', '-O', '-', url],
{ stdio: ['ignore', 'pipe', 'ignore'] });
} catch (e) {
;
}
throw new Error('curl or wget failed.');
};
PNG.prototype.setImage = function(file) {
var self = this;
this.file = typeof file === 'string' ? file : null;
if (/^https?:/.test(file)) {
file = PNG.curl(file);
}
var width = this.position.width;
var height = this.position.height;
if (width != null) {
width = this.width;
}
if (height != null) {
height = this.height;
}
try {
this.setContent('');
this.img = tng(file, {
colors: colors,
width: width,
height: height,
scale: this.scale,
ascii: this.options.ascii,
speed: this.options.speed,
filename: this.file
});
if (width == null || height == null) {
this.width = this.img.cellmap[0].length;
this.height = this.img.cellmap.length;
}
if (this.img.frames && this.options.animate) {
this.img.play(function(bmp, cellmap) {
self.cellmap = cellmap;
self.screen.render();
});
} else {
self.cellmap = self.img.cellmap;
}
} catch (e) {
this.setContent('PNG Error: ' + e.message);
this.img = null;
this.cellmap = null;
}
};
PNG.prototype.clearImage = function() {
this.setContent('');
this.img = null;
this.cellmap = null;
};
PNG.prototype.render = function() {
var self = this;
var coords = this._render();
if (!coords) return;
if (this.img) {
this.img.renderElement(this.cellmap, this);
}
return coords;
};
/**
* Expose
*/
module.exports = PNG;

View File

@ -1,725 +0,0 @@
/**
* w3mimage.js - w3m image element for blessed
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
* https://github.com/chjj/blessed
*/
/**
* Modules
*/
var fs = require('fs')
, cp = require('child_process');
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
/**
* W3MImage
* Good example of w3mimgdisplay commands:
* https://github.com/hut/ranger/blob/master/ranger/ext/img_display.py
*/
function W3MImage(options) {
var self = this;
if (!(this instanceof Node)) {
return new W3MImage(options);
}
options = options || {};
Box.call(this, options);
if (options.w3m) {
W3MImage.w3mdisplay = options.w3m;
}
if (W3MImage.hasW3MDisplay == null) {
if (fs.existsSync(W3MImage.w3mdisplay)) {
W3MImage.hasW3MDisplay = true;
} else if (options.search !== false) {
var file = helpers.findFile('/usr', 'w3mimgdisplay')
|| helpers.findFile('/lib', 'w3mimgdisplay')
|| helpers.findFile('/bin', 'w3mimgdisplay');
if (file) {
W3MImage.hasW3MDisplay = true;
W3MImage.w3mdisplay = file;
} else {
W3MImage.hasW3MDisplay = false;
}
}
}
this.on('hide', function() {
self._lastFile = self.file;
self.clearImage();
});
this.on('show', function() {
if (!self._lastFile) return;
self.setImage(self._lastFile);
});
this.on('detach', function() {
self._lastFile = self.file;
self.clearImage();
});
this.on('attach', function() {
if (!self._lastFile) return;
self.setImage(self._lastFile);
});
this.onScreenEvent('resize', function() {
self._needsRatio = true;
});
// Get images to overlap properly. Maybe not worth it:
// this.onScreenEvent('render', function() {
// self.screen.program.flush();
// if (!self._noImage) return;
// function display(el, next) {
// if (el.type === 'w3mimage' && el.file) {
// el.setImage(el.file, next);
// } else {
// next();
// }
// }
// function done(el) {
// el.children.forEach(recurse);
// }
// function recurse(el) {
// display(el, function() {
// var pending = el.children.length;
// el.children.forEach(function(el) {
// display(el, function() {
// if (!--pending) done(el);
// });
// });
// });
// }
// recurse(self.screen);
// });
this.onScreenEvent('render', function() {
self.screen.program.flush();
if (!self._noImage) {
self.setImage(self.file);
}
});
if (this.options.file || this.options.img) {
this.setImage(this.options.file || this.options.img);
}
}
W3MImage.prototype.__proto__ = Box.prototype;
W3MImage.prototype.type = 'w3mimage';
W3MImage.w3mdisplay = '/usr/lib/w3m/w3mimgdisplay';
W3MImage.prototype.spawn = function(file, args, opt, callback) {
var screen = this.screen
, opt = opt || {}
, spawn = require('child_process').spawn
, ps;
ps = spawn(file, args, opt);
ps.on('error', function(err) {
if (!callback) return;
return callback(err);
});
ps.on('exit', function(code) {
if (!callback) return;
if (code !== 0) return callback(new Error('Exit Code: ' + code));
return callback(null, code === 0);
});
return ps;
};
W3MImage.prototype.setImage = function(img, callback) {
var self = this;
if (this._settingImage) {
this._queue = this._queue || [];
this._queue.push([img, callback]);
return;
}
this._settingImage = true;
var reset = function(err, success) {
self._settingImage = false;
self._queue = self._queue || [];
var item = self._queue.shift();
if (item) {
self.setImage(item[0], item[1]);
}
};
if (W3MImage.hasW3MDisplay === false) {
reset();
if (!callback) return;
return callback(new Error('W3M Image Display not available.'));
}
if (!img) {
reset();
if (!callback) return;
return callback(new Error('No image.'));
}
this.file = img;
return this.getPixelRatio(function(err, ratio) {
if (err) {
reset();
if (!callback) return;
return callback(err);
}
return self.renderImage(img, ratio, function(err, success) {
if (err) {
reset();
if (!callback) return;
return callback(err);
}
if (self.shrink || self.options.autofit) {
delete self.shrink;
delete self.options.shrink;
self.options.autofit = true;
return self.imageSize(function(err, size) {
if (err) {
reset();
if (!callback) return;
return callback(err);
}
if (self._lastSize
&& ratio.tw === self._lastSize.tw
&& ratio.th === self._lastSize.th
&& size.width === self._lastSize.width
&& size.height === self._lastSize.height
&& self.aleft === self._lastSize.aleft
&& self.atop === self._lastSize.atop) {
reset();
if (!callback) return;
return callback(null, success);
}
self._lastSize = {
tw: ratio.tw,
th: ratio.th,
width: size.width,
height: size.height,
aleft: self.aleft,
atop: self.atop
};
self.position.width = size.width / ratio.tw | 0;
self.position.height = size.height / ratio.th | 0;
self._noImage = true;
self.screen.render();
self._noImage = false;
reset();
return self.renderImage(img, ratio, callback);
});
}
reset();
if (!callback) return;
return callback(null, success);
});
});
};
W3MImage.prototype.renderImage = function(img, ratio, callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
return callback(null, this.renderImageSync(img, ratio));
} catch (e) {
return callback(e);
}
}
if (W3MImage.hasW3MDisplay === false) {
if (!callback) return;
return callback(new Error('W3M Image Display not available.'));
}
if (!ratio) {
if (!callback) return;
return callback(new Error('No ratio.'));
}
// clearImage unsets these:
var _file = self.file;
var _lastSize = self._lastSize;
return self.clearImage(function(err) {
if (err) return callback(err);
self.file = _file;
self._lastSize = _lastSize;
var opt = {
stdio: 'pipe',
env: process.env,
cwd: process.env.HOME
};
var ps = self.spawn(W3MImage.w3mdisplay, [], opt, function(err, success) {
if (!callback) return;
return err
? callback(err)
: callback(null, success);
});
var width = self.width * ratio.tw | 0
, height = self.height * ratio.th | 0
, aleft = self.aleft * ratio.tw | 0
, atop = self.atop * ratio.th | 0;
var input = '0;1;'
+ aleft + ';'
+ atop + ';'
+ width + ';'
+ height + ';;;;;'
+ img
+ '\n4;\n3;\n';
self._props = {
aleft: aleft,
atop: atop,
width: width,
height: height
};
ps.stdin.write(input);
ps.stdin.end();
});
};
W3MImage.prototype.clearImage = function(callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
return callback(null, this.clearImageSync());
} catch (e) {
return callback(e);
}
}
if (W3MImage.hasW3MDisplay === false) {
if (!callback) return;
return callback(new Error('W3M Image Display not available.'));
}
if (!this._props) {
if (!callback) return;
return callback(null);
}
var opt = {
stdio: 'pipe',
env: process.env,
cwd: process.env.HOME
};
var ps = this.spawn(W3MImage.w3mdisplay, [], opt, function(err, success) {
if (!callback) return;
return err
? callback(err)
: callback(null, success);
});
var width = this._props.width + 2
, height = this._props.height + 2
, aleft = this._props.aleft
, atop = this._props.atop;
if (this._drag) {
aleft -= 10;
atop -= 10;
width += 10;
height += 10;
}
var input = '6;'
+ aleft + ';'
+ atop + ';'
+ width + ';'
+ height
+ '\n4;\n3;\n';
delete this.file;
delete this._props;
delete this._lastSize;
ps.stdin.write(input);
ps.stdin.end();
};
W3MImage.prototype.imageSize = function(callback) {
var self = this;
var img = this.file;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
return callback(null, this.imageSizeSync());
} catch (e) {
return callback(e);
}
}
if (W3MImage.hasW3MDisplay === false) {
if (!callback) return;
return callback(new Error('W3M Image Display not available.'));
}
if (!img) {
if (!callback) return;
return callback(new Error('No image.'));
}
var opt = {
stdio: 'pipe',
env: process.env,
cwd: process.env.HOME
};
var ps = this.spawn(W3MImage.w3mdisplay, [], opt);
var buf = '';
ps.stdout.setEncoding('utf8');
ps.stdout.on('data', function(data) {
buf += data;
});
ps.on('error', function(err) {
if (!callback) return;
return callback(err);
});
ps.on('exit', function() {
if (!callback) return;
var size = buf.trim().split(/\s+/);
return callback(null, {
raw: buf.trim(),
width: +size[0],
height: +size[1]
});
});
var input = '5;' + img + '\n';
ps.stdin.write(input);
ps.stdin.end();
};
W3MImage.prototype.termSize = function(callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
return callback(null, this.termSizeSync());
} catch (e) {
return callback(e);
}
}
if (W3MImage.hasW3MDisplay === false) {
if (!callback) return;
return callback(new Error('W3M Image Display not available.'));
}
var opt = {
stdio: 'pipe',
env: process.env,
cwd: process.env.HOME
};
var ps = this.spawn(W3MImage.w3mdisplay, ['-test'], opt);
var buf = '';
ps.stdout.setEncoding('utf8');
ps.stdout.on('data', function(data) {
buf += data;
});
ps.on('error', function(err) {
if (!callback) return;
return callback(err);
});
ps.on('exit', function() {
if (!callback) return;
if (!buf.trim()) {
// Bug: w3mimgdisplay will sometimes
// output nothing. Try again:
return self.termSize(callback);
}
var size = buf.trim().split(/\s+/);
return callback(null, {
raw: buf.trim(),
width: +size[0],
height: +size[1]
});
});
ps.stdin.end();
};
W3MImage.prototype.getPixelRatio = function(callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
return callback(null, this.getPixelRatioSync());
} catch (e) {
return callback(e);
}
}
// XXX We could cache this, but sometimes it's better
// to recalculate to be pixel perfect.
if (this._ratio && !this._needsRatio) {
return callback(null, this._ratio);
}
return this.termSize(function(err, dimensions) {
if (err) return callback(err);
self._ratio = {
tw: dimensions.width / self.screen.width,
th: dimensions.height / self.screen.height
};
self._needsRatio = false;
return callback(null, self._ratio);
});
};
W3MImage.prototype.renderImageSync = function(img, ratio) {
var self = this;
if (W3MImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
if (!ratio) {
throw new Error('No ratio.');
}
// clearImage unsets these:
var _file = this.file;
var _lastSize = this._lastSize;
this.clearImageSync();
this.file = _file;
this._lastSize = _lastSize;
var width = this.width * ratio.tw | 0
, height = this.height * ratio.th | 0
, aleft = this.aleft * ratio.tw | 0
, atop = this.atop * ratio.th | 0;
var input = '0;1;'
+ aleft + ';'
+ atop + ';'
+ width + ';'
+ height + ';;;;;'
+ img
+ '\n4;\n3;\n';
this._props = {
aleft: aleft,
atop: atop,
width: width,
height: height
};
try {
cp.execFileSync(W3MImage.w3mdisplay, [], {
env: process.env,
encoding: 'utf8',
input: input,
timeout: 1000
});
} catch (e) {
;
}
return true;
};
W3MImage.prototype.clearImageSync = function() {
if (W3MImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
if (!this._props) {
return false;
}
var width = this._props.width + 2
, height = this._props.height + 2
, aleft = this._props.aleft
, atop = this._props.atop;
if (this._drag) {
aleft -= 10;
atop -= 10;
width += 10;
height += 10;
}
var input = '6;'
+ aleft + ';'
+ atop + ';'
+ width + ';'
+ height
+ '\n4;\n3;\n';
delete this.file;
delete this._props;
delete this._lastSize;
try {
cp.execFileSync(W3MImage.w3mdisplay, [], {
env: process.env,
encoding: 'utf8',
input: input,
timeout: 1000
});
} catch (e) {
;
}
return true;
};
W3MImage.prototype.imageSizeSync = function() {
var img = this.file;
if (W3MImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
if (!img) {
throw new Error('No image.');
}
var buf = '';
var input = '5;' + img + '\n';
try {
buf = cp.execFileSync(W3MImage.w3mdisplay, [], {
env: process.env,
encoding: 'utf8',
input: input,
timeout: 1000
});
} catch (e) {
;
}
var size = buf.trim().split(/\s+/);
return {
raw: buf.trim(),
width: +size[0],
height: +size[1]
};
};
W3MImage.prototype.termSizeSync = function(_, recurse) {
if (W3MImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
var buf = '';
try {
buf = cp.execFileSync(W3MImage.w3mdisplay, ['-test'], {
env: process.env,
encoding: 'utf8',
timeout: 1000
});
} catch (e) {
;
}
if (!buf.trim()) {
// Bug: w3mimgdisplay will sometimes
// output nothing. Try again:
recurse = recurse || 0;
if (++recurse === 5) {
throw new Error('Term size not determined.');
}
return this.termSizeSync(_, recurse);
}
var size = buf.trim().split(/\s+/);
return {
raw: buf.trim(),
width: +size[0],
height: +size[1]
};
};
W3MImage.prototype.getPixelRatioSync = function() {
var self = this;
// XXX We could cache this, but sometimes it's better
// to recalculate to be pixel perfect.
if (this._ratio && !this._needsRatio) {
return this._ratio;
}
this._needsRatio = false;
var dimensions = this.termSizeSync();
this._ratio = {
tw: dimensions.width / this.screen.width,
th: dimensions.height / this.screen.height
};
return this._ratio;
};
W3MImage.prototype.displayImage = function(callback) {
return this.screen.displayImage(this.file, callback);
};
/**
* Expose
*/
module.exports = W3MImage;