Do some more refactoring in preparation for the 3D view
This commit is contained in:
parent
b75c327017
commit
f182686ba8
|
@ -8,55 +8,151 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
import {AntialiasingStrategy, AntialiasingStrategyName} from "./aa-strategy";
|
import * as glmatrix from 'gl-matrix';
|
||||||
|
|
||||||
|
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||||
import {mat4, vec2} from "gl-matrix";
|
import {mat4, vec2} from "gl-matrix";
|
||||||
|
import {PathfinderMeshData} from "./meshes";
|
||||||
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
||||||
|
import {BUILTIN_FONT_URI, TextLayout, PathfinderGlyph} from "./text";
|
||||||
import {PathfinderView, Timings} from "./view";
|
import {PathfinderView, Timings} from "./view";
|
||||||
import AppController from "./app-controller";
|
import AppController from "./app-controller";
|
||||||
|
import SSAAStrategy from "./ssaa-strategy";
|
||||||
|
import { panic, PathfinderError } from "./utils";
|
||||||
|
|
||||||
|
const TEXT: string = "Lorem ipsum dolor sit amet";
|
||||||
|
|
||||||
|
const FONT: string = 'open-sans';
|
||||||
|
|
||||||
|
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
||||||
|
none: NoAAStrategy,
|
||||||
|
ssaa: SSAAStrategy,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface AntialiasingStrategyTable {
|
||||||
|
none: typeof NoAAStrategy;
|
||||||
|
ssaa: typeof SSAAStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
class ThreeDController extends AppController<ThreeDView> {
|
class ThreeDController extends AppController<ThreeDView> {
|
||||||
protected fileLoaded(): void {
|
protected fileLoaded(): void {
|
||||||
throw new Error("Method not implemented.");
|
this.layout = new TextLayout(this.fileData, TEXT, glyph => new Glyph(glyph));
|
||||||
|
this.layout.partition().then((meshes: PathfinderMeshData) => {
|
||||||
|
this.meshes = meshes;
|
||||||
|
this.view.then(view => {
|
||||||
|
view.uploadPathMetadata(this.layout.textGlyphs.length);
|
||||||
|
view.attachMeshes(this.meshes);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createView(canvas: HTMLCanvasElement,
|
protected createView(canvas: HTMLCanvasElement,
|
||||||
commonShaderSource: string,
|
commonShaderSource: string,
|
||||||
shaderSources: ShaderMap<ShaderProgramSource>):
|
shaderSources: ShaderMap<ShaderProgramSource>):
|
||||||
ThreeDView {
|
ThreeDView {
|
||||||
throw new Error("Method not implemented.");
|
return new ThreeDView(this, canvas, commonShaderSource, shaderSources);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected builtinFileURI: string;
|
protected get builtinFileURI(): string {
|
||||||
|
return BUILTIN_FONT_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get defaultFile(): string {
|
||||||
|
return FONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout: TextLayout<Glyph>;
|
||||||
|
private meshes: PathfinderMeshData;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThreeDView extends PathfinderView {
|
class ThreeDView extends PathfinderView {
|
||||||
protected resized(initialSize: boolean): void {
|
constructor(appController: ThreeDController,
|
||||||
throw new Error("Method not implemented.");
|
canvas: HTMLCanvasElement,
|
||||||
|
commonShaderSource: string,
|
||||||
|
shaderSources: ShaderMap<ShaderProgramSource>) {
|
||||||
|
super(canvas, commonShaderSource, shaderSources);
|
||||||
|
|
||||||
|
this.appController = appController;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadPathMetadata(pathCount: number) {
|
||||||
|
const pathColors = new Uint8Array(4 * (pathCount + 1));
|
||||||
|
for (let pathIndex = 0; pathIndex < pathCount; pathIndex++) {
|
||||||
|
for (let channel = 0; channel < 3; channel++)
|
||||||
|
pathColors[(pathIndex + 1) * 4 + channel] = 0x00; // RGB
|
||||||
|
pathColors[(pathIndex + 1) * 4 + 3] = 0xff; // alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pathColorsBufferTexture.upload(this.gl, pathColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createAAStrategy(aaType: AntialiasingStrategyName, aaLevel: number):
|
protected createAAStrategy(aaType: AntialiasingStrategyName, aaLevel: number):
|
||||||
AntialiasingStrategy {
|
AntialiasingStrategy {
|
||||||
throw new Error("Method not implemented.");
|
if (aaType != 'ecaa')
|
||||||
|
return new (ANTIALIASING_STRATEGIES[aaType])(aaLevel);
|
||||||
|
throw new PathfinderError("Unsupported antialiasing type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected compositeIfNecessary(): void {
|
protected compositeIfNecessary(): void {}
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updateTimings(timings: Timings): void {
|
protected updateTimings(timings: Timings) {
|
||||||
throw new Error("Method not implemented.");
|
// TODO(pcwalton)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected panned(): void {
|
protected panned(): void {
|
||||||
throw new Error("Method not implemented.");
|
this.setDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
destFramebuffer: WebGLFramebuffer | null;
|
get destAllocatedSize(): glmatrix.vec2 {
|
||||||
destAllocatedSize: vec2;
|
return glmatrix.vec2.fromValues(this.canvas.width, this.canvas.height);
|
||||||
destUsedSize: vec2;
|
}
|
||||||
protected usedSizeFactor: vec2;
|
|
||||||
protected scale: number;
|
get destFramebuffer(): WebGLFramebuffer | null {
|
||||||
protected worldTransform: mat4;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get destUsedSize(): glmatrix.vec2 {
|
||||||
|
return this.destAllocatedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get usedSizeFactor(): glmatrix.vec2 {
|
||||||
|
return glmatrix.vec2.fromValues(1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get scale(): number {
|
||||||
|
return this._scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected set scale(newScale: number) {
|
||||||
|
this._scale = newScale;
|
||||||
|
this.setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected get worldTransform() {
|
||||||
|
const transform = glmatrix.mat4.create();
|
||||||
|
glmatrix.mat4.fromTranslation(transform, [this.translation[0], this.translation[1], 0]);
|
||||||
|
glmatrix.mat4.scale(transform, transform, [this.scale, this.scale, 1.0]);
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _scale: number;
|
||||||
|
|
||||||
|
private appController: ThreeDController;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Glyph extends PathfinderGlyph {
|
||||||
|
constructor(glyph: opentype.Glyph) {
|
||||||
|
super(glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRect(pixelsPerUnit: number): glmatrix.vec4 {
|
||||||
|
const rect = glmatrix.vec4.fromValues(this.position[0],
|
||||||
|
this.position[1],
|
||||||
|
this.metrics.xMax - this.metrics.xMin,
|
||||||
|
this.metrics.yMax - this.metrics.yMin);
|
||||||
|
glmatrix.vec4.scale(rect, rect, pixelsPerUnit);
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
|
|
|
@ -30,13 +30,21 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
this.settingsCard.classList.add('pf-invisible');
|
this.settingsCard.classList.add('pf-invisible');
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.filePickerElement = document.getElementById('pf-file-select') as HTMLInputElement;
|
this.filePickerElement = document.getElementById('pf-file-select') as
|
||||||
this.filePickerElement.addEventListener('change', () => this.loadFile(), false);
|
(HTMLInputElement | null);
|
||||||
|
if (this.filePickerElement != null) {
|
||||||
|
this.filePickerElement.addEventListener('change',
|
||||||
|
event => this.loadFile(event),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
this.selectFileElement = document.getElementById('pf-select-file') as HTMLSelectElement;
|
const selectFileElement = document.getElementById('pf-select-file') as
|
||||||
this.selectFileElement.addEventListener('click', () => {
|
(HTMLSelectElement | null);
|
||||||
this.fileSelectionChanged();
|
if (selectFileElement != null) {
|
||||||
}, false);
|
selectFileElement.addEventListener('click',
|
||||||
|
event => this.fileSelectionChanged(event),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
const shaderLoader = new ShaderLoader;
|
const shaderLoader = new ShaderLoader;
|
||||||
shaderLoader.load();
|
shaderLoader.load();
|
||||||
|
@ -51,7 +59,7 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadInitialFile() {
|
protected loadInitialFile() {
|
||||||
this.fileSelectionChanged();
|
this.fetchFile(this.defaultFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAALevel() {
|
private updateAALevel() {
|
||||||
|
@ -62,8 +70,9 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
this.view.then(view => view.setAntialiasingOptions(aaType, aaLevel));
|
this.view.then(view => view.setAntialiasingOptions(aaType, aaLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected loadFile() {
|
protected loadFile(event: Event) {
|
||||||
const file = expectNotNull(this.filePickerElement.files, "No file selected!")[0];
|
const filePickerElement = event.target as HTMLInputElement;
|
||||||
|
const file = expectNotNull(filePickerElement.files, "No file selected!")[0];
|
||||||
const reader = new FileReader;
|
const reader = new FileReader;
|
||||||
reader.addEventListener('loadend', () => {
|
reader.addEventListener('loadend', () => {
|
||||||
this.fileData = reader.result;
|
this.fileData = reader.result;
|
||||||
|
@ -72,28 +81,33 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
reader.readAsArrayBuffer(file);
|
reader.readAsArrayBuffer(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fileSelectionChanged() {
|
private fileSelectionChanged(event: Event) {
|
||||||
const selectedOption = this.selectFileElement.selectedOptions[0] as HTMLOptionElement;
|
const selectFileElement = event.target as HTMLSelectElement;
|
||||||
|
const selectedOption = selectFileElement.selectedOptions[0] as HTMLOptionElement;
|
||||||
|
|
||||||
if (selectedOption.value === 'load-custom') {
|
if (selectedOption.value === 'load-custom' && this.filePickerElement != null) {
|
||||||
this.filePickerElement.click();
|
this.filePickerElement.click();
|
||||||
|
|
||||||
const oldSelectedIndex = this.selectFileElement.selectedIndex;
|
const oldSelectedIndex = selectFileElement.selectedIndex;
|
||||||
const newOption = document.createElement('option');
|
const newOption = document.createElement('option');
|
||||||
newOption.id = 'pf-custom-option-placeholder';
|
newOption.id = 'pf-custom-option-placeholder';
|
||||||
newOption.appendChild(document.createTextNode("Custom"));
|
newOption.appendChild(document.createTextNode("Custom"));
|
||||||
this.selectFileElement.insertBefore(newOption, selectedOption);
|
selectFileElement.insertBefore(newOption, selectedOption);
|
||||||
this.selectFileElement.selectedIndex = oldSelectedIndex;
|
selectFileElement.selectedIndex = oldSelectedIndex;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the "Custom…" placeholder if it exists.
|
// Remove the "Custom…" placeholder if it exists.
|
||||||
const placeholder = document.getElementById('pf-custom-option-placeholder');
|
const placeholder = document.getElementById('pf-custom-option-placeholder');
|
||||||
if (placeholder != null)
|
if (placeholder != null)
|
||||||
this.selectFileElement.removeChild(placeholder);
|
selectFileElement.removeChild(placeholder);
|
||||||
|
|
||||||
// Fetch the file.
|
// Fetch the file.
|
||||||
window.fetch(`${this.builtinFileURI}/${selectedOption.value}`)
|
this.fetchFile(selectedOption.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private fetchFile(file: string) {
|
||||||
|
window.fetch(`${this.builtinFileURI}/${file}`)
|
||||||
.then(response => response.arrayBuffer())
|
.then(response => response.arrayBuffer())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.fileData = data;
|
this.fileData = data;
|
||||||
|
@ -105,6 +119,8 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
|
|
||||||
protected abstract get builtinFileURI(): string;
|
protected abstract get builtinFileURI(): string;
|
||||||
|
|
||||||
|
protected abstract get defaultFile(): string;
|
||||||
|
|
||||||
protected abstract createView(canvas: HTMLCanvasElement,
|
protected abstract createView(canvas: HTMLCanvasElement,
|
||||||
commonShaderSource: string,
|
commonShaderSource: string,
|
||||||
shaderSources: ShaderMap<ShaderProgramSource>): View;
|
shaderSources: ShaderMap<ShaderProgramSource>): View;
|
||||||
|
@ -114,8 +130,7 @@ export default abstract class AppController<View extends PathfinderView> {
|
||||||
protected fileData: ArrayBuffer;
|
protected fileData: ArrayBuffer;
|
||||||
|
|
||||||
protected canvas: HTMLCanvasElement;
|
protected canvas: HTMLCanvasElement;
|
||||||
protected selectFileElement: HTMLSelectElement;
|
protected filePickerElement: HTMLInputElement | null;
|
||||||
protected filePickerElement: HTMLInputElement;
|
|
||||||
private aaLevelSelect: HTMLSelectElement;
|
private aaLevelSelect: HTMLSelectElement;
|
||||||
private settingsCard: HTMLElement;
|
private settingsCard: HTMLElement;
|
||||||
private settingsButton: HTMLButtonElement;
|
private settingsButton: HTMLButtonElement;
|
||||||
|
|
|
@ -29,6 +29,8 @@ const PARTITION_SVG_PATHS_ENDPOINT_URL: string = "/partition-svg-paths";
|
||||||
|
|
||||||
const BUILTIN_SVG_URI: string = "/svg/demo";
|
const BUILTIN_SVG_URI: string = "/svg/demo";
|
||||||
|
|
||||||
|
const DEFAULT_FILE: string = 'tiger';
|
||||||
|
|
||||||
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
||||||
none: NoAAStrategy,
|
none: NoAAStrategy,
|
||||||
ssaa: SSAAStrategy,
|
ssaa: SSAAStrategy,
|
||||||
|
@ -147,6 +149,10 @@ class SVGDemoController extends AppController<SVGDemoView> {
|
||||||
return BUILTIN_SVG_URI;
|
return BUILTIN_SVG_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get defaultFile(): string {
|
||||||
|
return DEFAULT_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
private meshesReceived() {
|
private meshesReceived() {
|
||||||
this.view.then(view => {
|
this.view.then(view => {
|
||||||
view.uploadPathData(this.pathElements);
|
view.uploadPathData(this.pathElements);
|
||||||
|
@ -171,11 +177,6 @@ class SVGDemoView extends PathfinderView {
|
||||||
this._scale = 1.0;
|
this._scale = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected resized(initialSize: boolean) {
|
|
||||||
this.antialiasingStrategy.init(this);
|
|
||||||
this.setDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
get destAllocatedSize(): glmatrix.vec2 {
|
get destAllocatedSize(): glmatrix.vec2 {
|
||||||
return glmatrix.vec2.fromValues(this.canvas.width, this.canvas.height);
|
return glmatrix.vec2.fromValues(this.canvas.width, this.canvas.height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {createFramebufferDepthTexture, QUAD_ELEMENTS, setTextureParameters} from
|
||||||
import {UniformMap} from './gl-utils';
|
import {UniformMap} from './gl-utils';
|
||||||
import {PathfinderMeshBuffers, PathfinderMeshData} from './meshes';
|
import {PathfinderMeshBuffers, PathfinderMeshData} from './meshes';
|
||||||
import {PathfinderShaderProgram, ShaderMap, ShaderProgramSource} from './shader-loader';
|
import {PathfinderShaderProgram, ShaderMap, ShaderProgramSource} from './shader-loader';
|
||||||
import {PathfinderGlyph, TextLayout} from "./text";
|
import {BUILTIN_FONT_URI, PathfinderGlyph, TextLayout} from "./text";
|
||||||
import {PathfinderError, assert, expectNotNull, UINT32_SIZE, unwrapNull, panic} from './utils';
|
import {PathfinderError, assert, expectNotNull, UINT32_SIZE, unwrapNull, panic} from './utils';
|
||||||
import {MonochromePathfinderView, Timings} from './view';
|
import {MonochromePathfinderView, Timings} from './view';
|
||||||
import AppController from './app-controller';
|
import AppController from './app-controller';
|
||||||
|
@ -68,7 +68,7 @@ const INITIAL_FONT_SIZE: number = 72.0;
|
||||||
|
|
||||||
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
const PARTITION_FONT_ENDPOINT_URL: string = "/partition-font";
|
||||||
|
|
||||||
const BUILTIN_FONT_URI: string = "/otf/demo";
|
const DEFAULT_FONT: string = 'open-sans';
|
||||||
|
|
||||||
const B_POSITION_SIZE: number = 8;
|
const B_POSITION_SIZE: number = 8;
|
||||||
|
|
||||||
|
@ -115,9 +115,7 @@ class TextDemoController extends AppController<TextDemoView> {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
this._fontSize = INITIAL_FONT_SIZE;
|
this._fontSize = INITIAL_FONT_SIZE;
|
||||||
|
|
||||||
this.fpsLabel = unwrapNull(document.getElementById('pf-fps-label'));
|
this.fpsLabel = unwrapNull(document.getElementById('pf-fps-label'));
|
||||||
|
|
||||||
this.loadInitialFile();
|
this.loadInitialFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,18 +129,14 @@ class TextDemoController extends AppController<TextDemoView> {
|
||||||
this.layout = new TextLayout(this.fileData, TEXT, glyph => new GlyphInstance(glyph));
|
this.layout = new TextLayout(this.fileData, TEXT, glyph => new GlyphInstance(glyph));
|
||||||
this.layout.partition().then((meshes: PathfinderMeshData) => {
|
this.layout.partition().then((meshes: PathfinderMeshData) => {
|
||||||
this.meshes = meshes;
|
this.meshes = meshes;
|
||||||
this.meshesReceived();
|
this.view.then(view => {
|
||||||
|
view.attachText();
|
||||||
|
view.uploadPathMetadata(this.layout.uniqueGlyphs.length);
|
||||||
|
view.attachMeshes(this.meshes);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private meshesReceived() {
|
|
||||||
this.view.then(view => {
|
|
||||||
view.attachText();
|
|
||||||
view.uploadPathData(this.layout.uniqueGlyphs.length);
|
|
||||||
view.attachMeshes(this.meshes);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTimings(newTimes: Timings) {
|
updateTimings(newTimes: Timings) {
|
||||||
this.fpsLabel.innerHTML =
|
this.fpsLabel.innerHTML =
|
||||||
`${newTimes.atlasRendering} ms atlas, ${newTimes.compositing} ms compositing`;
|
`${newTimes.atlasRendering} ms atlas, ${newTimes.compositing} ms compositing`;
|
||||||
|
@ -160,7 +154,6 @@ class TextDemoController extends AppController<TextDemoView> {
|
||||||
/// The font size in pixels per em.
|
/// The font size in pixels per em.
|
||||||
set fontSize(newFontSize: number) {
|
set fontSize(newFontSize: number) {
|
||||||
this._fontSize = newFontSize;
|
this._fontSize = newFontSize;
|
||||||
this.layout
|
|
||||||
this.view.then(view => view.attachText());
|
this.view.then(view => view.attachText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +165,10 @@ class TextDemoController extends AppController<TextDemoView> {
|
||||||
return BUILTIN_FONT_URI;
|
return BUILTIN_FONT_URI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected get defaultFile(): string {
|
||||||
|
return DEFAULT_FONT;
|
||||||
|
}
|
||||||
|
|
||||||
private fpsLabel: HTMLElement;
|
private fpsLabel: HTMLElement;
|
||||||
|
|
||||||
private _atlas: Atlas;
|
private _atlas: Atlas;
|
||||||
|
@ -198,7 +195,7 @@ class TextDemoView extends MonochromePathfinderView {
|
||||||
super.initContext();
|
super.initContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadPathData(pathCount: number) {
|
uploadPathMetadata(pathCount: number) {
|
||||||
const pathColors = new Uint8Array(4 * (pathCount + 1));
|
const pathColors = new Uint8Array(4 * (pathCount + 1));
|
||||||
for (let pathIndex = 0; pathIndex < pathCount; pathIndex++) {
|
for (let pathIndex = 0; pathIndex < pathCount; pathIndex++) {
|
||||||
for (let channel = 0; channel < 3; channel++)
|
for (let channel = 0; channel < 3; channel++)
|
||||||
|
@ -354,12 +351,6 @@ class TextDemoView extends MonochromePathfinderView {
|
||||||
this.rebuildAtlasIfNecessary();
|
this.rebuildAtlasIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected resized(initialSize: boolean) {
|
|
||||||
if (!initialSize)
|
|
||||||
this.antialiasingStrategy.init(this);
|
|
||||||
this.setDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private setIdentityTexScaleUniform(uniforms: UniformMap) {
|
private setIdentityTexScaleUniform(uniforms: UniformMap) {
|
||||||
this.gl.uniform2f(uniforms.uTexScale, 1.0, 1.0);
|
this.gl.uniform2f(uniforms.uTexScale, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ import * as opentype from "opentype.js";
|
||||||
import {PathfinderMeshData} from "./meshes";
|
import {PathfinderMeshData} from "./meshes";
|
||||||
import {assert, panic} from "./utils";
|
import {assert, panic} from "./utils";
|
||||||
|
|
||||||
|
export const BUILTIN_FONT_URI: string = "/otf/demo";
|
||||||
|
|
||||||
const PARTITION_FONT_ENDPOINT_URI: string = "/partition-font";
|
const PARTITION_FONT_ENDPOINT_URI: string = "/partition-font";
|
||||||
|
|
||||||
opentype.Font.prototype.isSupported = function() {
|
opentype.Font.prototype.isSupported = function() {
|
||||||
|
|
|
@ -105,10 +105,13 @@ export abstract class PathfinderView {
|
||||||
this.canvas.width = canvasSize[0];
|
this.canvas.width = canvasSize[0];
|
||||||
this.canvas.height = canvasSize[1];
|
this.canvas.height = canvasSize[1];
|
||||||
|
|
||||||
this.resized(initialSize);
|
this.resized();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract resized(initialSize: boolean): void;
|
private resized(): void {
|
||||||
|
this.antialiasingStrategy.init(this);
|
||||||
|
this.setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
protected initContext() {
|
protected initContext() {
|
||||||
// Initialize the OpenGL context.
|
// Initialize the OpenGL context.
|
||||||
|
|
Loading…
Reference in New Issue