rename - work.
This commit is contained in:
parent
aa9a85be9d
commit
abdd0a8c89
43
README.md
43
README.md
|
@ -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.
|
||||||
|
|
|
@ -37,8 +37,8 @@ widget.classes = [
|
||||||
'ListTable',
|
'ListTable',
|
||||||
'Terminal',
|
'Terminal',
|
||||||
'Image',
|
'Image',
|
||||||
'PNG',
|
'ANSIImage',
|
||||||
'W3MImage',
|
'OverlayImage',
|
||||||
'Video',
|
'Video',
|
||||||
'Layout'
|
'Layout'
|
||||||
];
|
];
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
|
@ -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;
|
|
Loading…
Reference in New Issue