Add an experimental implementation of macOS-like font dilation
Following Apple's earlier terminology, this is exposed as "strong" subpixel AA.
This commit is contained in:
parent
99f6f2a104
commit
60ff71be84
|
@ -54,12 +54,14 @@
|
|||
<option value="ecaa" selected>ECAA</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" value="" type="checkbox"
|
||||
id="pf-subpixel-aa" checked>
|
||||
Subpixel AA
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label for="pf-subpixel-aa-select">Subpixel AA</label>
|
||||
<select id="pf-subpixel-aa-select"
|
||||
class="form-control custom-select">
|
||||
<option value="none">None</option>
|
||||
<option value="medium" selected>Medium</option>
|
||||
<option value="strong">Strong</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pf-hinting-select">Hinting</label>
|
||||
|
|
|
@ -14,6 +14,7 @@ import * as opentype from "opentype.js";
|
|||
|
||||
import {mat4, vec2} from "gl-matrix";
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||
import {SubpixelAAType} from "./aa-strategy";
|
||||
import {DemoAppController} from "./app-controller";
|
||||
import PathfinderBufferTexture from "./buffer-texture";
|
||||
import {PerspectiveCamera} from "./camera";
|
||||
|
@ -285,7 +286,7 @@ class ThreeDView extends PathfinderDemoView {
|
|||
|
||||
protected createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean):
|
||||
subpixelAA: SubpixelAAType):
|
||||
AntialiasingStrategy {
|
||||
if (aaType !== 'ecaa')
|
||||
return new (ANTIALIASING_STRATEGIES[aaType])(aaLevel, subpixelAA);
|
||||
|
|
|
@ -14,6 +14,8 @@ import {PathfinderDemoView} from './view';
|
|||
|
||||
export type AntialiasingStrategyName = 'none' | 'ssaa' | 'ecaa';
|
||||
|
||||
export type SubpixelAAType = 'none' | 'medium' | 'strong';
|
||||
|
||||
export abstract class AntialiasingStrategy {
|
||||
// True if direct rendering should occur.
|
||||
shouldRenderDirect: boolean;
|
||||
|
@ -51,7 +53,7 @@ export abstract class AntialiasingStrategy {
|
|||
export class NoAAStrategy extends AntialiasingStrategy {
|
||||
framebufferSize: glmatrix.vec2;
|
||||
|
||||
constructor(level: number, subpixelAA: boolean) {
|
||||
constructor(level: number, subpixelAA: SubpixelAAType) {
|
||||
super();
|
||||
this.framebufferSize = glmatrix.vec2.create();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
import {AntialiasingStrategyName} from "./aa-strategy";
|
||||
import { AntialiasingStrategyName, SubpixelAAType } from "./aa-strategy";
|
||||
import {FilePickerView} from "./file-picker";
|
||||
import {ShaderLoader, ShaderMap, ShaderProgramSource} from './shader-loader';
|
||||
import {expectNotNull, unwrapNull, unwrapUndef} from './utils';
|
||||
|
@ -56,7 +56,7 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
|
|||
protected shaderSources: ShaderMap<ShaderProgramSource> | null;
|
||||
|
||||
private aaLevelSelect: HTMLSelectElement | null;
|
||||
private subpixelAASwitch: HTMLInputElement | null;
|
||||
private subpixelAASelect: HTMLSelectElement | null;
|
||||
private fpsLabel: HTMLElement | null;
|
||||
|
||||
constructor() {
|
||||
|
@ -143,10 +143,10 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
|
|||
if (this.aaLevelSelect != null)
|
||||
this.aaLevelSelect.addEventListener('change', () => this.updateAALevel(), false);
|
||||
|
||||
this.subpixelAASwitch =
|
||||
document.getElementById('pf-subpixel-aa') as HTMLInputElement | null;
|
||||
if (this.subpixelAASwitch != null)
|
||||
this.subpixelAASwitch.addEventListener('change', () => this.updateAALevel(), false);
|
||||
this.subpixelAASelect =
|
||||
document.getElementById('pf-subpixel-aa-select') as HTMLSelectElement | null;
|
||||
if (this.subpixelAASelect != null)
|
||||
this.subpixelAASelect.addEventListener('change', () => this.updateAALevel(), false);
|
||||
|
||||
this.updateAALevel();
|
||||
}
|
||||
|
@ -191,7 +191,11 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
|
|||
aaLevel = 0;
|
||||
}
|
||||
|
||||
const subpixelAA = this.subpixelAASwitch == null ? false : this.subpixelAASwitch.checked;
|
||||
let subpixelAA: SubpixelAAType;
|
||||
if (this.subpixelAASelect != null)
|
||||
subpixelAA = this.subpixelAASelect.selectedOptions[0].value as SubpixelAAType;
|
||||
else
|
||||
subpixelAA = 'none';
|
||||
this.view.then(view => view.setAntialiasingOptions(aaType, aaLevel, subpixelAA));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import * as glmatrix from 'gl-matrix';
|
|||
import * as opentype from "opentype.js";
|
||||
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||
import {SubpixelAAType} from "./aa-strategy";
|
||||
import {AppController, DemoAppController} from "./app-controller";
|
||||
import PathfinderBufferTexture from './buffer-texture';
|
||||
import {OrthographicCamera} from './camera';
|
||||
|
@ -221,7 +222,7 @@ class BenchmarkTestView extends MonochromePathfinderView {
|
|||
|
||||
protected createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean):
|
||||
subpixelAA: SubpixelAAType):
|
||||
AntialiasingStrategy {
|
||||
return new (ANTIALIASING_STRATEGIES[aaType])(aaLevel, subpixelAA);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import * as glmatrix from 'gl-matrix';
|
||||
|
||||
import {AntialiasingStrategy} from './aa-strategy';
|
||||
import { AntialiasingStrategy, SubpixelAAType } from './aa-strategy';
|
||||
import PathfinderBufferTexture from './buffer-texture';
|
||||
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
|
||||
import {createFramebufferDepthTexture, setTextureParameters, UniformMap} from './gl-utils';
|
||||
|
@ -35,7 +35,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
protected supersampledFramebufferSize: glmatrix.vec2;
|
||||
protected destFramebufferSize: glmatrix.vec2;
|
||||
|
||||
protected subpixelAA: boolean;
|
||||
protected subpixelAA: SubpixelAAType;
|
||||
|
||||
private bVertexPositionBufferTexture: PathfinderBufferTexture;
|
||||
private bVertexPathIDBufferTexture: PathfinderBufferTexture;
|
||||
|
@ -47,7 +47,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
private curveVAOs: UpperAndLower<WebGLVertexArrayObject>;
|
||||
private resolveVAO: WebGLVertexArrayObject;
|
||||
|
||||
constructor(level: number, subpixelAA: boolean) {
|
||||
constructor(level: number, subpixelAA: SubpixelAAType) {
|
||||
super();
|
||||
|
||||
this.subpixelAA = subpixelAA;
|
||||
|
@ -472,13 +472,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
}
|
||||
|
||||
protected get supersampleScale(): glmatrix.vec2 {
|
||||
return glmatrix.vec2.fromValues(this.subpixelAA ? 3.0 : 1.0, 1.0);
|
||||
return glmatrix.vec2.fromValues(this.subpixelAA !== 'none' ? 3.0 : 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
export class ECAAMonochromeStrategy extends ECAAStrategy {
|
||||
protected getResolveProgram(view: MonochromePathfinderView): PathfinderShaderProgram {
|
||||
if (this.subpixelAA)
|
||||
if (this.subpixelAA !== 'none')
|
||||
return view.shaderPrograms.ecaaMonoSubpixelResolve;
|
||||
return view.shaderPrograms.ecaaMonoResolve;
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
|
||||
import * as glmatrix from 'gl-matrix';
|
||||
|
||||
import {AntialiasingStrategy} from './aa-strategy';
|
||||
import {AntialiasingStrategy, SubpixelAAType} from './aa-strategy';
|
||||
import {createFramebuffer, createFramebufferDepthTexture, setTextureParameters} from './gl-utils';
|
||||
import {unwrapNull} from './utils';
|
||||
import {PathfinderDemoView} from './view';
|
||||
|
||||
export default class SSAAStrategy extends AntialiasingStrategy {
|
||||
private level: number;
|
||||
private subpixelAA: boolean;
|
||||
private subpixelAA: SubpixelAAType;
|
||||
|
||||
private destFramebufferSize: glmatrix.vec2;
|
||||
private supersampledFramebufferSize: glmatrix.vec2;
|
||||
|
@ -25,7 +25,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
|||
private supersampledDepthTexture: WebGLTexture;
|
||||
private supersampledFramebuffer: WebGLFramebuffer;
|
||||
|
||||
constructor(level: number, subpixelAA: boolean) {
|
||||
constructor(level: number, subpixelAA: SubpixelAAType) {
|
||||
super();
|
||||
this.level = level;
|
||||
this.subpixelAA = subpixelAA;
|
||||
|
@ -96,7 +96,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
|||
|
||||
// Set up the blit program VAO.
|
||||
let resolveProgram;
|
||||
if (this.subpixelAA)
|
||||
if (this.subpixelAA !== 'none')
|
||||
resolveProgram = view.shaderPrograms.ssaaSubpixelResolve;
|
||||
else
|
||||
resolveProgram = view.shaderPrograms.blit;
|
||||
|
@ -120,7 +120,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
|||
}
|
||||
|
||||
private get supersampleScale(): glmatrix.vec2 {
|
||||
return glmatrix.vec2.fromValues(this.subpixelAA ? 3 : 2, this.level === 2 ? 1 : 2);
|
||||
return glmatrix.vec2.clone([this.subpixelAA !== 'none' ? 3 : 2, this.level === 2 ? 1 : 2]);
|
||||
}
|
||||
|
||||
private usedSupersampledFramebufferSize(view: PathfinderDemoView): glmatrix.vec2 {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import * as glmatrix from 'gl-matrix';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||
import { AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy, SubpixelAAType } from "./aa-strategy";
|
||||
import {DemoAppController} from './app-controller';
|
||||
import PathfinderBufferTexture from "./buffer-texture";
|
||||
import {OrthographicCamera} from "./camera";
|
||||
|
@ -153,7 +153,7 @@ class SVGDemoView extends PathfinderDemoView {
|
|||
|
||||
protected createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean):
|
||||
subpixelAA: SubpixelAAType):
|
||||
AntialiasingStrategy {
|
||||
return new (ANTIALIASING_STRATEGIES[aaType])(aaLevel, subpixelAA);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ import * as _ from 'lodash';
|
|||
import * as opentype from 'opentype.js';
|
||||
|
||||
import {Metrics} from 'opentype.js';
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from './aa-strategy';
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||
import {SubpixelAAType} from './aa-strategy';
|
||||
import {DemoAppController} from './app-controller';
|
||||
import PathfinderBufferTexture from './buffer-texture';
|
||||
import {OrthographicCamera} from "./camera";
|
||||
|
@ -71,6 +72,11 @@ const INITIAL_FONT_SIZE: number = 72.0;
|
|||
|
||||
const DEFAULT_FONT: string = 'open-sans';
|
||||
|
||||
const FONT_DILATION_FACTOR: number = 1.0242;
|
||||
|
||||
/// In pixels.
|
||||
const MAX_FONT_DILATION: number = 0.3;
|
||||
|
||||
const B_POSITION_SIZE: number = 8;
|
||||
|
||||
const B_PATH_INDEX_SIZE: number = 2;
|
||||
|
@ -172,10 +178,6 @@ class TextDemoController extends DemoAppController<TextDemoView> {
|
|||
window.jQuery(this.editTextModal).modal();
|
||||
}
|
||||
|
||||
createHint(): Hint {
|
||||
return new Hint(this.font, this.pixelsPerUnit, this.useHinting);
|
||||
}
|
||||
|
||||
protected createView() {
|
||||
return new TextDemoView(this,
|
||||
unwrapNull(this.commonShaderSource),
|
||||
|
@ -245,7 +247,7 @@ class TextDemoController extends DemoAppController<TextDemoView> {
|
|||
this.view.then(view => view.relayoutText());
|
||||
}
|
||||
|
||||
get pixelsPerUnit(): number {
|
||||
get layoutPixelsPerUnit(): number {
|
||||
return this._fontSize / this.font.opentypeFont.unitsPerEm;
|
||||
}
|
||||
|
||||
|
@ -283,6 +285,8 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
|
||||
protected depthFunction: number = this.gl.GREATER;
|
||||
|
||||
private subpixelAA: SubpixelAAType;
|
||||
|
||||
constructor(appController: TextDemoController,
|
||||
commonShaderSource: string,
|
||||
shaderSources: ShaderMap<ShaderProgramSource>) {
|
||||
|
@ -327,6 +331,17 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
this.setDirty();
|
||||
}
|
||||
|
||||
setAntialiasingOptions(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: SubpixelAAType) {
|
||||
super.setAntialiasingOptions(aaType, aaLevel, subpixelAA);
|
||||
|
||||
// Need to relayout because changing AA options can cause font dilation to change...
|
||||
this.layoutText();
|
||||
this.buildAtlasGlyphs();
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
protected initContext() {
|
||||
super.initContext();
|
||||
}
|
||||
|
@ -348,7 +363,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
protected pathTransformsForObject(objectIndex: number): Float32Array {
|
||||
const pathCount = this.appController.pathCount;
|
||||
const atlasGlyphs = this.appController.atlasGlyphs;
|
||||
const pixelsPerUnit = this.appController.pixelsPerUnit;
|
||||
const pixelsPerUnit = this.displayPixelsPerUnit;
|
||||
|
||||
const transforms = new Float32Array((pathCount + 1) * 4);
|
||||
|
||||
|
@ -435,8 +450,9 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
|
||||
protected createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean):
|
||||
subpixelAA: SubpixelAAType):
|
||||
AntialiasingStrategy {
|
||||
this.subpixelAA = subpixelAA;
|
||||
return new (ANTIALIASING_STRATEGIES[aaType])(aaLevel, subpixelAA);
|
||||
}
|
||||
|
||||
|
@ -444,6 +460,12 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
this.appController.newTimingsReceived(this.lastTimings);
|
||||
}
|
||||
|
||||
private createHint(): Hint {
|
||||
return new Hint(this.appController.font,
|
||||
this.displayPixelsPerUnit,
|
||||
this.appController.useHinting);
|
||||
}
|
||||
|
||||
/// Lays out glyphs on the canvas.
|
||||
private layoutText() {
|
||||
const layout = this.appController.layout;
|
||||
|
@ -456,8 +478,9 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
const glyphPositions = new Float32Array(totalGlyphCount * 8);
|
||||
const glyphIndices = new Uint32Array(totalGlyphCount * 6);
|
||||
|
||||
const hint = this.appController.createHint();
|
||||
const pixelsPerUnit = this.appController.pixelsPerUnit;
|
||||
const hint = this.createHint();
|
||||
const displayPixelsPerUnit = this.displayPixelsPerUnit;
|
||||
const layoutPixelsPerUnit = this.appController.layoutPixelsPerUnit;
|
||||
|
||||
let globalGlyphIndex = 0;
|
||||
for (const run of layout.textFrame.runs) {
|
||||
|
@ -465,7 +488,8 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
glyphIndex < run.glyphIDs.length;
|
||||
glyphIndex++, globalGlyphIndex++) {
|
||||
const rect = run.pixelRectForGlyphAt(glyphIndex,
|
||||
pixelsPerUnit,
|
||||
layoutPixelsPerUnit,
|
||||
displayPixelsPerUnit,
|
||||
hint,
|
||||
SUBPIXEL_GRANULARITY);
|
||||
glyphPositions.set([
|
||||
|
@ -495,10 +519,11 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
private buildAtlasGlyphs() {
|
||||
const font = this.appController.font;
|
||||
const glyphStore = this.appController.glyphStore;
|
||||
const pixelsPerUnit = this.appController.pixelsPerUnit;
|
||||
const layoutPixelsPerUnit = this.appController.layoutPixelsPerUnit;
|
||||
const displayPixelsPerUnit = this.displayPixelsPerUnit;
|
||||
|
||||
const textFrame = this.appController.layout.textFrame;
|
||||
const hint = this.appController.createHint();
|
||||
const hint = this.createHint();
|
||||
|
||||
// Only build glyphs in view.
|
||||
const translation = this.camera.translation;
|
||||
|
@ -511,7 +536,8 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
for (const run of textFrame.runs) {
|
||||
for (let glyphIndex = 0; glyphIndex < run.glyphIDs.length; glyphIndex++) {
|
||||
const pixelRect = run.pixelRectForGlyphAt(glyphIndex,
|
||||
pixelsPerUnit,
|
||||
layoutPixelsPerUnit,
|
||||
displayPixelsPerUnit,
|
||||
hint,
|
||||
SUBPIXEL_GRANULARITY);
|
||||
if (!rectsIntersect(pixelRect, canvasRect))
|
||||
|
@ -523,7 +549,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
continue;
|
||||
|
||||
const subpixel = run.subpixelForGlyphAt(glyphIndex,
|
||||
pixelsPerUnit,
|
||||
layoutPixelsPerUnit,
|
||||
hint,
|
||||
SUBPIXEL_GRANULARITY);
|
||||
const glyphKey = new GlyphKey(glyphID, subpixel);
|
||||
|
@ -537,7 +563,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
return;
|
||||
|
||||
this.appController.atlasGlyphs = atlasGlyphs;
|
||||
this.appController.atlas.layoutGlyphs(atlasGlyphs, font, pixelsPerUnit, hint);
|
||||
this.appController.atlas.layoutGlyphs(atlasGlyphs, font, displayPixelsPerUnit, hint);
|
||||
|
||||
this.uploadPathTransforms(1);
|
||||
|
||||
|
@ -577,8 +603,9 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
const font = this.appController.font;
|
||||
const atlasGlyphs = this.appController.atlasGlyphs;
|
||||
|
||||
const hint = this.appController.createHint();
|
||||
const pixelsPerUnit = this.appController.pixelsPerUnit;
|
||||
const hint = this.createHint();
|
||||
const layoutPixelsPerUnit = this.appController.layoutPixelsPerUnit;
|
||||
const displayPixelsPerUnit = this.displayPixelsPerUnit;
|
||||
|
||||
const atlasGlyphKeys = atlasGlyphs.map(atlasGlyph => atlasGlyph.glyphKey.sortKey);
|
||||
|
||||
|
@ -592,7 +619,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
const textGlyphID = run.glyphIDs[glyphIndex];
|
||||
|
||||
const subpixel = run.subpixelForGlyphAt(glyphIndex,
|
||||
pixelsPerUnit,
|
||||
layoutPixelsPerUnit,
|
||||
hint,
|
||||
SUBPIXEL_GRANULARITY);
|
||||
|
||||
|
@ -608,10 +635,10 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
if (atlasGlyphMetrics == null)
|
||||
continue;
|
||||
|
||||
const atlasGlyphPixelOrigin = atlasGlyph.calculateSubpixelOrigin(pixelsPerUnit);
|
||||
const atlasGlyphPixelOrigin = atlasGlyph.calculateSubpixelOrigin(displayPixelsPerUnit);
|
||||
const atlasGlyphRect = calculatePixelRectForGlyph(atlasGlyphMetrics,
|
||||
atlasGlyphPixelOrigin,
|
||||
pixelsPerUnit,
|
||||
displayPixelsPerUnit,
|
||||
hint);
|
||||
const atlasGlyphBL = atlasGlyphRect.slice(0, 2) as glmatrix.vec2;
|
||||
const atlasGlyphTR = atlasGlyphRect.slice(2, 4) as glmatrix.vec2;
|
||||
|
@ -678,6 +705,18 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
protected get directInteriorProgramName(): keyof ShaderMap<void> {
|
||||
return 'directInterior';
|
||||
}
|
||||
|
||||
/// Pixels per unit, including dilation.
|
||||
private get displayPixelsPerUnit(): number {
|
||||
// FIXME(pcwalton): Check against Cocoa and make sure this is what they do.
|
||||
const layoutPixelsPerUnit = this.appController.layoutPixelsPerUnit;
|
||||
if (this.subpixelAA !== 'strong')
|
||||
return layoutPixelsPerUnit;
|
||||
|
||||
const ascender = this.appController.font.opentypeFont.ascender * layoutPixelsPerUnit;
|
||||
const maxFontDilationFactor = (ascender + MAX_FONT_DILATION) / ascender;
|
||||
return Math.min(maxFontDilationFactor, FONT_DILATION_FACTOR) * layoutPixelsPerUnit;
|
||||
}
|
||||
}
|
||||
|
||||
interface AntialiasingStrategyTable {
|
||||
|
|
|
@ -99,27 +99,32 @@ export class TextRun {
|
|||
}
|
||||
}
|
||||
|
||||
calculatePixelOriginForGlyphAt(index: number, pixelsPerUnit: number, hint: Hint):
|
||||
calculatePixelOriginForGlyphAt(index: number,
|
||||
layoutPixelsPerUnit: number,
|
||||
hint: Hint):
|
||||
glmatrix.vec2 {
|
||||
const textGlyphOrigin = glmatrix.vec2.clone(this.origin);
|
||||
textGlyphOrigin[0] += this.advances[index];
|
||||
glmatrix.vec2.scale(textGlyphOrigin, textGlyphOrigin, pixelsPerUnit);
|
||||
glmatrix.vec2.scale(textGlyphOrigin, textGlyphOrigin, layoutPixelsPerUnit);
|
||||
return textGlyphOrigin;
|
||||
}
|
||||
|
||||
pixelRectForGlyphAt(index: number,
|
||||
pixelsPerUnit: number,
|
||||
layoutPixelsPerUnit: number,
|
||||
displayPixelsPerUnit: number,
|
||||
hint: Hint,
|
||||
subpixelGranularity: number):
|
||||
glmatrix.vec4 {
|
||||
const metrics = unwrapNull(this.font.metricsForGlyph(this.glyphIDs[index]));
|
||||
const textGlyphOrigin = this.calculatePixelOriginForGlyphAt(index, pixelsPerUnit, hint);
|
||||
const textGlyphOrigin = this.calculatePixelOriginForGlyphAt(index,
|
||||
layoutPixelsPerUnit,
|
||||
hint);
|
||||
|
||||
textGlyphOrigin[0] *= subpixelGranularity;
|
||||
glmatrix.vec2.round(textGlyphOrigin, textGlyphOrigin);
|
||||
textGlyphOrigin[0] /= subpixelGranularity;
|
||||
|
||||
return calculatePixelRectForGlyph(metrics, textGlyphOrigin, pixelsPerUnit, hint);
|
||||
return calculatePixelRectForGlyph(metrics, textGlyphOrigin, displayPixelsPerUnit, hint);
|
||||
}
|
||||
|
||||
subpixelForGlyphAt(index: number,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import * as glmatrix from 'gl-matrix';
|
||||
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from "./aa-strategy";
|
||||
import { AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy, SubpixelAAType } from "./aa-strategy";
|
||||
import PathfinderBufferTexture from './buffer-texture';
|
||||
import {Camera} from "./camera";
|
||||
import {QUAD_ELEMENTS, UniformMap} from './gl-utils';
|
||||
|
@ -164,13 +164,13 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
|
||||
this.wantsScreenshot = false;
|
||||
|
||||
this.antialiasingStrategy = new NoAAStrategy(0, false);
|
||||
this.antialiasingStrategy = new NoAAStrategy(0, 'none');
|
||||
this.antialiasingStrategy.init(this);
|
||||
}
|
||||
|
||||
setAntialiasingOptions(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean) {
|
||||
subpixelAA: SubpixelAAType) {
|
||||
this.antialiasingStrategy = this.createAAStrategy(aaType, aaLevel, subpixelAA);
|
||||
|
||||
const canvas = this.canvas;
|
||||
|
@ -385,7 +385,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
|
||||
protected abstract createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
subpixelAA: boolean):
|
||||
subpixelAA: SubpixelAAType):
|
||||
AntialiasingStrategy;
|
||||
|
||||
protected abstract compositeIfNecessary(): void;
|
||||
|
|
Loading…
Reference in New Issue