Skip to content

Commit

Permalink
Moved letterboxing code from WebRenderer to DefaultRenderer.
Browse files Browse the repository at this point in the history
The initial implementation of letterboxing incorrectly assumed that subs should always be rendered with the same width:height ratio as the script resolution. In fact desktop renderers stretch the width and height individually, so the presence or absence of letterboxing can only be determined based on the original video dimensions. WebRenderer is abstracted from the original video, so it cannot do this.

So now WebRenderer.resize() takes additional left and top parameters and expects the caller to calculate the letterboxing and adjust width, height, left and top accordingly. DefaultRenderer does this.

Also removed the redundant width and height parameters from DefaultRenderer.resize() since it was always expected to resize to the video's width and height anyway.

Fixes Arnavion#62
  • Loading branch information
Arnavion committed Jan 23, 2016
1 parent 795bef9 commit 9b0e15c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
33 changes: 26 additions & 7 deletions src/renderers/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,37 @@ export class DefaultRenderer extends WebRenderer {
}

/**
* @deprecated
* Resize the subtitles to the dimensions of the video element.
*
* @param {number} width
* @param {number} height
* This method accounts for letterboxing if the video element's size is not the same ratio as the video resolution.
*/
resize(): void {
// Handle letterboxing around the video. If the width or height are greater than the video can be, then consider that dead space.

const videoWidth = this._video.videoWidth;
const videoHeight = this._video.videoHeight;
const videoOffsetWidth = this._video.offsetWidth;
const videoOffsetHeight = this._video.offsetHeight;

const ratio = Math.min(videoOffsetWidth / videoWidth, videoOffsetHeight / videoHeight);
const subsWrapperWidth = videoWidth * ratio;
const subsWrapperHeight = videoHeight * ratio;
const subsWrapperLeft = (videoOffsetWidth - subsWrapperWidth) / 2;
const subsWrapperTop = (videoOffsetHeight - subsWrapperHeight) / 2;

super.resize(subsWrapperWidth, subsWrapperHeight, subsWrapperLeft, subsWrapperTop);
}

/**
* @deprecated
*/
resizeVideo(width: number, height: number): void {
console.warn("`DefaultRenderer.resizeVideo(width, height)` has been deprecated. Use `DefaultRenderer.resize(width, height)` instead.");
this.resize(width, height);
resizeVideo(): void {
console.warn("`DefaultRenderer.resizeVideo(width, height)` has been deprecated. Use `DefaultRenderer.resize()` instead.");
this.resize();
}

protected _ready(): void {
this.resize(this._video.offsetWidth, this._video.offsetHeight);
this.resize();

super._ready();
}
Expand Down
21 changes: 11 additions & 10 deletions src/renderers/web/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,20 +321,21 @@ export class WebRenderer extends NullRenderer implements EventSource<string> {
*
* @param {number} width
* @param {number} height
* @param {number=0} left
* @param {number=0} top
*/
resize(width: number, height: number): void {
resize(width: number, height: number, left: number = 0, top: number = 0): void {
this._removeAllSubs();

const ratio = Math.min(width / this.ass.properties.resolutionX, height / this.ass.properties.resolutionY);
this._subsWrapperWidth = this.ass.properties.resolutionX * ratio;
const subsWrapperHeight = this.ass.properties.resolutionY * ratio;
this._subsWrapper.style.width = `${ this._subsWrapperWidth.toFixed(3) }px`;
this._subsWrapper.style.height = `${ subsWrapperHeight.toFixed(3) }px`;
this._subsWrapper.style.left = `${ ((width - this._subsWrapperWidth) / 2).toFixed(3) }px`;
this._subsWrapper.style.top = `${ ((height - subsWrapperHeight) / 2).toFixed(3) }px`;
this._subsWrapper.style.width = `${ width.toFixed(3) }px`;
this._subsWrapper.style.height = `${ height.toFixed(3) }px`;
this._subsWrapper.style.left = `${ left.toFixed(3) }px`;
this._subsWrapper.style.top = `${ top.toFixed(3) }px`;

this._scaleX = this._subsWrapperWidth / this.ass.properties.resolutionX;
this._scaleY = subsWrapperHeight / this.ass.properties.resolutionY;
this._subsWrapperWidth = width;

this._scaleX = width / this.ass.properties.resolutionX;
this._scaleY = height / this.ass.properties.resolutionY;

// Any dialogues which have been pre-rendered will need to be pre-rendered again.
this._preRenderedSubs.clear();
Expand Down

0 comments on commit 9b0e15c

Please sign in to comment.