Upgrade ST-transforms to affine transforms where possible, and add

incomplete rotation support to the text demo
This commit is contained in:
Patrick Walton 2017-11-29 10:50:47 -08:00
parent 58260beb8c
commit 86660572bd
25 changed files with 304 additions and 124 deletions

View File

@ -0,0 +1,18 @@
<div id="pf-rotate-slider-container">
<div id="pf-rotate-slider-card" class="card mb-4 pf-invisible">
<div class="card-body">
<form class="d-inline mr-3">
<input id="pf-rotate-slider" type="range" min="-3.14159" max="3.14159"
step="0.006136" value="0.0" autocomplete="off">
</form>
<button id="pf-rotate-close-button" type="button" class="close" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="pf-arrow-box"></div>
</div>
</div>
<button id="pf-rotate-button" type="button" title="Rotate"
class="btn btn-outline-secondary pf-toolbar-button">
<span class="pf-material-icons">rotate_left</span>
</button>

View File

@ -24,25 +24,7 @@
<span class="pf-material-icons">add</span>
</button>
</div>
<div id="pf-rotate-slider-container">
<div id="pf-rotate-slider-card" class="card mb-4 pf-invisible">
<div class="card-body">
<form class="d-inline mr-3">
<input id="pf-rotate-slider" type="range" min="-3.14159"
max="3.14159" step="0.006136" value="0.0" autocomplete="off">
</form>
<button id="pf-rotate-close-button" type="button" class="close"
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="pf-arrow-box"></div>
</div>
</div>
<button id="pf-rotate-button" type="button" title="Rotate"
class="btn btn-outline-secondary pf-toolbar-button">
<span class="pf-material-icons">rotate_left</span>
</button>
{{>partials/rotate.html}}
<button id="pf-zoom-pulse-button" type="button" title="Pulse Zoom"
class="btn btn-outline-secondary pf-toolbar-button">
<span class="pf-material-icons">play_arrow</span>

View File

@ -23,6 +23,7 @@
<span class="pf-material-icons">add</span>
</button>
</div>
{{>partials/rotate.html}}
<button id="pf-zoom-pulse-button" type="button" title="Pulse Zoom"
class="btn btn-outline-secondary pf-toolbar-button">
<span class="pf-material-icons">play_arrow</span>

View File

@ -21,7 +21,7 @@ import PathfinderBufferTexture from "./buffer-texture";
import {CameraView, PerspectiveCamera} from "./camera";
import {UniformMap} from './gl-utils';
import {PathfinderMeshData} from "./meshes";
import {Renderer} from './renderer';
import {PathTransformBuffers, Renderer} from './renderer';
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
import SSAAStrategy from "./ssaa-strategy";
import {BUILTIN_FONT_URI, ExpandedMeshData} from "./text";
@ -480,13 +480,13 @@ class ThreeDRenderer extends Renderer {
return TEXT_COLOR;
}
protected pathTransformsForObject(objectIndex: number): Float32Array {
protected pathTransformsForObject(objectIndex: number): PathTransformBuffers<Float32Array> {
const meshDescriptor = this.renderContext.appController.meshDescriptors[objectIndex];
const pathCount = this.pathCountForObject(objectIndex);
const pathTransforms = new Float32Array(4 * (pathCount + 1));
const pathTransforms = this.createPathTransformBuffers(pathCount);
for (let pathIndex = 0; pathIndex < pathCount; pathIndex++) {
const glyphOrigin = meshDescriptor.positions[pathIndex];
pathTransforms.set([1, 1, glyphOrigin[0], glyphOrigin[1]], (pathIndex + 1) * 4);
pathTransforms.st.set([1, 1, glyphOrigin[0], glyphOrigin[1]], (pathIndex + 1) * 4);
}
return pathTransforms;
}

View File

@ -19,7 +19,7 @@ import PathfinderBufferTexture from './buffer-texture';
import {OrthographicCamera} from './camera';
import {UniformMap} from './gl-utils';
import {PathfinderMeshData} from "./meshes";
import {Renderer} from './renderer';
import {PathTransformBuffers, Renderer} from './renderer';
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
import SSAAStrategy from './ssaa-strategy';
import {BUILTIN_FONT_URI, ExpandedMeshData, GlyphStore, PathfinderFont, TextFrame} from "./text";
@ -415,12 +415,12 @@ class BenchmarkRenderer extends Renderer {
return pathColors;
}
protected pathTransformsForObject(objectIndex: number): Float32Array {
protected pathTransformsForObject(objectIndex: number): PathTransformBuffers<Float32Array> {
const appController = this.renderContext.appController;
const canvas = this.renderContext.canvas;
const font = unwrapNull(appController.font);
const pathTransforms = new Float32Array(4 * (STRING.length + 1));
const pathTransforms = this.createPathTransformBuffers(STRING.length);
let currentX = 0, currentY = 0;
const availableWidth = canvas.width / this.pixelsPerUnit;
@ -428,7 +428,7 @@ class BenchmarkRenderer extends Renderer {
for (let glyphIndex = 0; glyphIndex < STRING.length; glyphIndex++) {
const glyphID = unwrapNull(appController.textRun).glyphIDs[glyphIndex];
pathTransforms.set([1, 1, currentX, currentY], (glyphIndex + 1) * 4);
pathTransforms.st.set([1, 1, currentX, currentY], (glyphIndex + 1) * 4);
currentX += font.opentypeFont.glyphs.get(glyphID).advanceWidth;
if (currentX > availableWidth) {

View File

@ -20,7 +20,7 @@ import {SUBPIXEL_GRANULARITY} from './atlas';
import {OrthographicCamera} from './camera';
import {UniformMap} from './gl-utils';
import {PathfinderMeshData} from './meshes';
import {Renderer} from "./renderer";
import {PathTransformBuffers, Renderer} from "./renderer";
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
import SSAAStrategy from './ssaa-strategy';
import {BUILTIN_FONT_URI, computeStemDarkeningAmount, ExpandedMeshData, GlyphStore} from "./text";
@ -600,13 +600,13 @@ class ReferenceTestRenderer extends Renderer {
return pathColors;
}
protected pathTransformsForObject(objectIndex: number): Float32Array {
protected pathTransformsForObject(objectIndex: number): PathTransformBuffers<Float32Array> {
const appController = this.renderContext.appController;
const canvas = this.renderContext.canvas;
const font = unwrapNull(appController.font);
const hint = new Hint(font, this.pixelsPerUnit, true);
const pathTransforms = new Float32Array(4 * 2);
const pathTransforms = this.createPathTransformBuffers(1);
const textRun = unwrapNull(appController.textRun);
const glyphID = textRun.glyphIDs[0];
@ -620,7 +620,7 @@ class ReferenceTestRenderer extends Renderer {
const x = -pixelRect[0] / this.pixelsPerUnit;
const y = (canvas.height - (pixelRect[3] - pixelRect[1])) / this.pixelsPerUnit;
pathTransforms.set([1, 1, x, y], 1 * 4);
pathTransforms.st.set([1, 1, x, y], 1 * 4);
return pathTransforms;
}

View File

@ -31,10 +31,15 @@ const B_LOOP_BLINN_DATA_SIZE: number = 4;
const B_LOOP_BLINN_DATA_TEX_COORD_OFFSET: number = 0;
const B_LOOP_BLINN_DATA_SIGN_OFFSET: number = 2;
export interface PathTransformBuffers<T> {
st: T;
ext: T;
}
export abstract class Renderer {
readonly renderContext: RenderContext;
readonly pathTransformBufferTextures: PathfinderBufferTexture[];
readonly pathTransformBufferTextures: Array<PathTransformBuffers<PathfinderBufferTexture>>;
meshes: PathfinderMeshBuffers[] | null;
meshData: PathfinderMeshData[] | null;
@ -279,16 +284,19 @@ export abstract class Renderer {
for (let objectIndex = 0; objectIndex < objectCount; objectIndex++) {
const pathTransforms = this.pathTransformsForObject(objectIndex);
let pathTransformBufferTexture;
let pathTransformBufferTextures;
if (objectIndex >= this.pathTransformBufferTextures.length) {
pathTransformBufferTexture = new PathfinderBufferTexture(renderContext.gl,
'uPathTransform');
this.pathTransformBufferTextures[objectIndex] = pathTransformBufferTexture;
pathTransformBufferTextures = {
ext: new PathfinderBufferTexture(renderContext.gl, 'uPathTransformExt'),
st: new PathfinderBufferTexture(renderContext.gl, 'uPathTransformST'),
};
this.pathTransformBufferTextures[objectIndex] = pathTransformBufferTextures;
} else {
pathTransformBufferTexture = this.pathTransformBufferTextures[objectIndex];
pathTransformBufferTextures = this.pathTransformBufferTextures[objectIndex];
}
pathTransformBufferTexture.upload(renderContext.gl, pathTransforms);
pathTransformBufferTextures.st.upload(renderContext.gl, pathTransforms.st);
pathTransformBufferTextures.ext.upload(renderContext.gl, pathTransforms.ext);
}
}
@ -346,7 +354,8 @@ export abstract class Renderer {
AntialiasingStrategy;
protected abstract compositeIfNecessary(): void;
protected abstract pathColorsForObject(objectIndex: number): Uint8Array;
protected abstract pathTransformsForObject(objectIndex: number): Float32Array;
protected abstract pathTransformsForObject(objectIndex: number):
PathTransformBuffers<Float32Array>;
protected abstract directCurveProgramName(): keyof ShaderMap<void>;
protected abstract directInteriorProgramName(): keyof ShaderMap<void>;
@ -404,6 +413,14 @@ export abstract class Renderer {
/// Called whenever new GPU timing statistics are available.
protected newTimingsReceived(): void {}
protected createPathTransformBuffers(pathCount: number): PathTransformBuffers<Float32Array> {
pathCount += 1;
return {
ext: new Float32Array((pathCount + (pathCount & 1)) * 2),
st: new Float32Array(pathCount * 4),
};
}
private directlyRenderObject(objectIndex: number): void {
if (this.meshes == null || this.meshData == null)
return;
@ -447,11 +464,13 @@ export abstract class Renderer {
this.setHintsUniform(directInteriorProgram.uniforms);
this.setPathColorsUniform(objectIndex, directInteriorProgram.uniforms, 0);
this.setEmboldenAmountUniform(objectIndex, directInteriorProgram.uniforms);
this.pathTransformBufferTextures[meshIndex].st.bind(gl, directInteriorProgram.uniforms, 1);
this.pathTransformBufferTextures[meshIndex]
.bind(gl, directInteriorProgram.uniforms, 1);
.ext
.bind(gl, directInteriorProgram.uniforms, 2);
if (renderingMode === 'color-depth') {
const strategy = antialiasingStrategy as ECAAMulticolorStrategy;
strategy.bindEdgeDepthTexture(gl, directInteriorProgram.uniforms, 2);
strategy.bindEdgeDepthTexture(gl, directInteriorProgram.uniforms, 3);
}
const coverInteriorRange = getMeshIndexRange(meshes.coverInteriorIndexRanges, pathRange);
if (!this.pathIDsAreInstanced) {
@ -490,10 +509,11 @@ export abstract class Renderer {
this.setHintsUniform(directCurveProgram.uniforms);
this.setPathColorsUniform(objectIndex, directCurveProgram.uniforms, 0);
this.setEmboldenAmountUniform(objectIndex, directCurveProgram.uniforms);
this.pathTransformBufferTextures[meshIndex].bind(gl, directCurveProgram.uniforms, 1);
this.pathTransformBufferTextures[meshIndex].st.bind(gl, directCurveProgram.uniforms, 1);
this.pathTransformBufferTextures[meshIndex].ext.bind(gl, directCurveProgram.uniforms, 2);
if (renderingMode === 'color-depth') {
const strategy = antialiasingStrategy as ECAAMulticolorStrategy;
strategy.bindEdgeDepthTexture(gl, directCurveProgram.uniforms, 2);
strategy.bindEdgeDepthTexture(gl, directCurveProgram.uniforms, 3);
}
const coverCurveRange = getMeshIndexRange(meshes.coverCurveIndexRanges, pathRange);
if (!this.pathIDsAreInstanced) {

View File

@ -19,7 +19,7 @@ import {OrthographicCamera} from "./camera";
import {UniformMap} from './gl-utils';
import {PathfinderMeshData} from "./meshes";
import {CompositingOperation, RenderTaskType} from './render-task';
import {Renderer} from './renderer';
import {PathTransformBuffers, Renderer} from './renderer';
import {ShaderMap, ShaderProgramSource} from './shader-loader';
import SSAAStrategy from "./ssaa-strategy";
import {BUILTIN_SVG_URI, SVGLoader} from './svg-loader';
@ -254,14 +254,14 @@ class SVGDemoRenderer extends Renderer {
return pathColors;
}
protected pathTransformsForObject(objectIndex: number): Float32Array {
protected pathTransformsForObject(objectIndex: number): PathTransformBuffers<Float32Array> {
const instances = this.renderContext.appController.loader.pathInstances;
const pathTransforms = new Float32Array(4 * (instances.length + 1));
const pathTransforms = this.createPathTransformBuffers(instances.length);
for (let pathIndex = 0; pathIndex < instances.length; pathIndex++) {
// TODO(pcwalton): Set transform.
const startOffset = (pathIndex + 1) * 4;
pathTransforms.set([1, 1, 0, 0], startOffset);
pathTransforms.st.set([1, 1, 0, 0], startOffset);
}
return pathTransforms;

View File

@ -131,6 +131,7 @@ class TextDemoController extends DemoAppController<TextDemoView> {
private meshes: PathfinderMeshData;
private _fontSize: number;
private _rotationAngle: number;
private text: string;
@ -144,6 +145,7 @@ class TextDemoController extends DemoAppController<TextDemoView> {
super.start();
this._fontSize = INITIAL_FONT_SIZE;
this._rotationAngle = 0.0;
this.hintingSelect = unwrapNull(document.getElementById('pf-hinting-select')) as
HTMLSelectElement;
@ -235,6 +237,15 @@ class TextDemoController extends DemoAppController<TextDemoView> {
this.view.then(view => view.renderer.relayoutText());
}
get rotationAngle(): number {
return this._rotationAngle;
}
set rotationAngle(newRotationAngle: number) {
this._rotationAngle = newRotationAngle;
this.view.then(view => view.renderer.relayoutText());
}
get layoutPixelsPerUnit(): number {
return this._fontSize / this.font.opentypeFont.unitsPerEm;
}
@ -333,22 +344,28 @@ class TextDemoView extends DemoView implements TextRenderContext {
this.appController.newTimingsReceived(newTimings);
}
protected onPan() {
protected onPan(): void {
this.renderer.viewPanned();
}
protected onZoom() {
protected onZoom(): void {
this.appController.fontSize = this.renderer.camera.scale *
this.appController.font.opentypeFont.unitsPerEm;
}
protected onRotate(): void {
this.appController.rotationAngle = this.renderer.camera.rotationAngle;
}
private set panZoomEventsEnabled(flag: boolean) {
if (flag) {
this.renderer.camera.onPan = () => this.onPan();
this.renderer.camera.onZoom = () => this.onZoom();
this.renderer.camera.onRotate = () => this.onRotate();
} else {
this.renderer.camera.onPan = null;
this.renderer.camera.onZoom = null;
this.renderer.camera.onRotate = null;
}
}
}
@ -370,6 +387,10 @@ class TextDemoRenderer extends TextRenderer {
return glmatrix.vec4.create();
}
get rotationAngle(): number {
return this.renderContext.appController.rotationAngle;
}
prepareToAttachText(): void {
if (this.atlasFramebuffer == null)
this.createAtlasFramebuffer();

View File

@ -17,7 +17,7 @@ import {Atlas, ATLAS_SIZE, AtlasGlyph, GlyphKey, SUBPIXEL_GRANULARITY} from './a
import {CameraView, OrthographicCamera} from './camera';
import {createFramebuffer, createFramebufferDepthTexture, QUAD_ELEMENTS} from './gl-utils';
import {UniformMap} from './gl-utils';
import {Renderer} from './renderer';
import {PathTransformBuffers, Renderer} from './renderer';
import {ShaderMap} from './shader-loader';
import SSAAStrategy from './ssaa-strategy';
import {calculatePixelRectForGlyph, computeStemDarkeningAmount, GlyphStore, Hint} from "./text";
@ -88,6 +88,10 @@ export abstract class TextRenderer extends Renderer {
return glmatrix.vec4.clone([1.0, 1.0, 1.0, 1.0]);
}
get rotationAngle(): number {
return 0.0;
}
protected get layoutPixelsPerUnit(): number {
return this.renderContext.fontSize / this.renderContext.font.opentypeFont.unitsPerEm;
}
@ -230,10 +234,11 @@ export abstract class TextRenderer extends Renderer {
return pathColors;
}
protected pathTransformsForObject(objectIndex: number): Float32Array {
protected pathTransformsForObject(objectIndex: number): PathTransformBuffers<Float32Array> {
const pathCount = this.pathCount;
const atlasGlyphs = this.renderContext.atlasGlyphs;
const pixelsPerUnit = this.displayPixelsPerUnit;
const rotationAngle = this.rotationAngle;
// FIXME(pcwalton): This is a hack that tries to preserve the vertical extents of the glyph
// after stem darkening. It's better than nothing, but we should really do better.
@ -250,16 +255,28 @@ export abstract class TextRenderer extends Renderer {
glmatrix.vec2.scale(stemDarkeningOffset, stemDarkeningOffset, SQRT_1_2);
glmatrix.vec2.mul(stemDarkeningOffset, stemDarkeningOffset, [1, stemDarkeningYScale]);
const transforms = new Float32Array((pathCount + 1) * 4);
const transform = glmatrix.mat2d.create();
const transforms = this.createPathTransformBuffers(pathCount);
for (const glyph of atlasGlyphs) {
const pathID = glyph.pathID;
const atlasOrigin = glyph.calculateSubpixelOrigin(pixelsPerUnit);
transforms[pathID * 4 + 0] = pixelsPerUnit;
transforms[pathID * 4 + 1] = pixelsPerUnit * stemDarkeningYScale;
transforms[pathID * 4 + 2] = atlasOrigin[0] + stemDarkeningOffset[0];
transforms[pathID * 4 + 3] = atlasOrigin[1] + stemDarkeningOffset[1];
glmatrix.mat2d.identity(transform);
glmatrix.mat2d.translate(transform, transform, atlasOrigin);
glmatrix.mat2d.translate(transform, transform, stemDarkeningOffset);
glmatrix.mat2d.rotate(transform, transform, rotationAngle);
glmatrix.mat2d.scale(transform,
transform,
[pixelsPerUnit, pixelsPerUnit * stemDarkeningYScale]);
transforms.st[pathID * 4 + 0] = transform[0];
transforms.st[pathID * 4 + 1] = transform[3];
transforms.st[pathID * 4 + 2] = transform[4];
transforms.st[pathID * 4 + 3] = transform[5];
transforms.ext[pathID * 2 + 0] = transform[1];
transforms.ext[pathID * 2 + 1] = transform[2];
}
return transforms;

View File

@ -235,8 +235,9 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
gl.uniform2i(uniforms.uFramebufferSize,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1]);
renderer.pathTransformBufferTextures[0].bind(gl, uniforms, 0);
this.pathBoundsBufferTexture.bind(gl, uniforms, 1);
renderer.pathTransformBufferTextures[0].ext.bind(gl, uniforms, 0);
renderer.pathTransformBufferTextures[0].st.bind(gl, uniforms, 1);
this.pathBoundsBufferTexture.bind(gl, uniforms, 2);
renderer.setHintsUniform(uniforms);
}

View File

@ -48,8 +48,12 @@ vec2 transformVertexPosition(vec2 position, mat4 transform) {
///
/// An ST-transform is a combined 2D scale and translation, where the (x, y) coordinates specify
/// the scale and and the (z, w) coordinates specify the translation.
vec2 transformVertexPositionST(vec2 position, vec4 stTransform) {
return position * stTransform.xy + stTransform.zw;
vec2 transformVertexPositionST(vec2 position, vec4 transformST) {
return position * transformST.xy + transformST.zw;
}
vec2 transformVertexPositionAffine(vec2 position, vec4 transformST, vec2 transformExt) {
return position * transformST.xy + position.yx * transformExt + transformST.zw;
}
/// Interpolates the given 2D position in the vertical direction using the given ultra-slight
@ -160,6 +164,7 @@ bool computeECAAQuadPosition(out vec2 outPosition,
vec2 quadPosition,
ivec2 framebufferSize,
vec4 localTransformST,
vec2 localTransformExt,
mat4 globalTransform,
vec4 hints,
vec4 bounds,
@ -174,12 +179,16 @@ bool computeECAAQuadPosition(out vec2 outPosition,
leftPosition = hintPosition(leftPosition, hints);
rightPosition = hintPosition(rightPosition, hints);
leftPosition = transformVertexPositionST(leftPosition, localTransformST);
rightPosition = transformVertexPositionST(rightPosition, localTransformST);
edgeBL = transformVertexPositionST(edgeBL, localTransformST);
edgeTL = transformVertexPositionST(edgeTL, localTransformST);
edgeBR = transformVertexPositionST(edgeBR, localTransformST);
edgeTR = transformVertexPositionST(edgeTR, localTransformST);
leftPosition = transformVertexPositionAffine(leftPosition,
localTransformST,
localTransformExt);
rightPosition = transformVertexPositionAffine(rightPosition,
localTransformST,
localTransformExt);
edgeBL = transformVertexPositionAffine(edgeBL, localTransformST, localTransformExt);
edgeTL = transformVertexPositionAffine(edgeTL, localTransformST, localTransformExt);
edgeBR = transformVertexPositionAffine(edgeBR, localTransformST, localTransformExt);
edgeTR = transformVertexPositionAffine(edgeTR, localTransformST, localTransformExt);
leftPosition = transformVertexPosition(leftPosition, globalTransform);
rightPosition = transformVertexPosition(rightPosition, globalTransform);
@ -226,9 +235,14 @@ bool computeECAAMultiEdgeMaskQuadPosition(out vec2 outPosition,
vec2 quadPosition,
ivec2 framebufferSize,
vec4 localTransformST,
vec2 localTransformExt,
mat4 globalTransform) {
leftPosition = transformVertexPositionST(leftPosition, localTransformST);
rightPosition = transformVertexPositionST(rightPosition, localTransformST);
leftPosition = transformVertexPositionAffine(leftPosition,
localTransformST,
localTransformExt);
rightPosition = transformVertexPositionAffine(rightPosition,
localTransformST,
localTransformExt);
leftPosition = transformVertexPosition(leftPosition, globalTransform);
rightPosition = transformVertexPosition(rightPosition, globalTransform);
@ -397,6 +411,24 @@ vec4 fetchFloat4Data(sampler2D dataTexture, int index, ivec2 dimensions) {
return texture2D(dataTexture, (vec2(pixelCoord) + 0.5) / vec2(dimensions));
}
vec2 fetchFloat2Data(sampler2D dataTexture, int index, ivec2 dimensions) {
int texelIndex = index / 2;
vec4 texel = fetchFloat4Data(dataTexture, texelIndex, dimensions);
return texelIndex * 2 == index ? texel.xy : texel.zw;
}
vec4 fetchPathAffineTransform(out vec2 outPathTransformExt,
sampler2D pathTransformSTTexture,
ivec2 pathTransformSTDimensions,
sampler2D pathTransformExtTexture,
ivec2 pathTransformExtDimensions,
int pathID) {
outPathTransformExt = fetchFloat2Data(pathTransformExtTexture,
pathID,
pathTransformExtDimensions);
return fetchFloat4Data(pathTransformSTTexture, pathID, pathTransformSTDimensions);
}
vec2 packPathID(int pathID) {
return vec2(imod(pathID, 256), pathID / 256) / 255.0;
}

View File

@ -13,9 +13,11 @@ precision highp float;
uniform mat4 uTransform;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathColors;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
@ -31,10 +33,16 @@ varying float vSign;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
gl_Position = uTransform * vec4(position, 0.0, 1.0);

View File

@ -13,9 +13,11 @@ precision highp float;
uniform mat4 uTransform;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathColors;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute float aPathID;
@ -27,10 +29,16 @@ varying vec2 vPathID;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
gl_Position = uTransform * vec4(position, 0.0, 1.0);

View File

@ -14,9 +14,11 @@ uniform mat4 uTransform;
uniform vec4 uHints;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathColors;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
@ -31,11 +33,17 @@ varying float vSign;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = hintPosition(position, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);

View File

@ -14,9 +14,11 @@ uniform mat4 uTransform;
uniform vec4 uHints;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathColors;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute float aPathID;
@ -27,11 +29,17 @@ varying vec4 vColor;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = hintPosition(position, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);

View File

@ -13,9 +13,11 @@ precision highp float;
uniform mat4 uTransform;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
uniform ivec2 uPathBoundsDimensions;
uniform sampler2D uPathTransform;
uniform sampler2D uPathBounds;
uniform vec2 uEmboldenAmount;
@ -39,7 +41,13 @@ void main() {
float controlPointNormalAngle = aNormalAngles.y;
float rightNormalAngle = aNormalAngles.z;
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec4 bounds = fetchFloat4Data(uPathBounds, pathID, uPathBoundsDimensions);
// Transform the points, and compute the position of this vertex.
@ -51,7 +59,8 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
pathTransformST,
pathTransformExt,
uTransform,
uHints,
bounds,
@ -62,7 +71,9 @@ void main() {
controlPointNormalAngle,
uEmboldenAmount);
controlPointPosition = hintPosition(controlPointPosition, uHints);
controlPointPosition = transformVertexPositionST(controlPointPosition, transform);
controlPointPosition = transformVertexPositionAffine(controlPointPosition,
pathTransformST,
pathTransformExt);
controlPointPosition = transformVertexPosition(controlPointPosition, uTransform);
controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize);
}

View File

@ -13,10 +13,12 @@ precision highp float;
uniform mat4 uTransform;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathBoundsDimensions;
uniform sampler2D uPathTransform;
uniform sampler2D uPathBounds;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
uniform vec2 uEmboldenAmount;
attribute vec2 aQuadPosition;
@ -36,7 +38,13 @@ void main() {
float leftNormalAngle = aLeftNormalAngle;
float rightNormalAngle = aRightNormalAngle;
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec4 bounds = fetchFloat4Data(uPathBounds, pathID, uPathBoundsDimensions);
// Transform the points, and compute the position of this vertex.
@ -48,7 +56,8 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
pathTransformST,
pathTransformExt,
uTransform,
uHints,
bounds,

View File

@ -12,8 +12,10 @@ precision highp float;
uniform mat4 uTransform;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aQuadPosition;
attribute vec2 aLeftPosition;
@ -30,7 +32,13 @@ void main() {
vec2 rightPosition = aRightPosition;
int pathID = int(aPathID);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
// Transform the points, and compute the position of this vertex.
vec2 position;
@ -39,9 +47,12 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
pathTransformST,
pathTransformExt,
uTransform)) {
controlPointPosition = transformVertexPositionST(controlPointPosition, transform);
controlPointPosition = transformVertexPositionAffine(controlPointPosition,
pathTransformST,
pathTransformExt);
controlPointPosition = transformVertexPosition(controlPointPosition, uTransform);
controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize);
}

View File

@ -13,8 +13,10 @@ precision highp float;
uniform mat4 uTransform;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aQuadPosition;
attribute vec2 aLeftPosition;
@ -28,7 +30,13 @@ void main() {
vec2 rightPosition = aRightPosition;
int pathID = int(aPathID);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
// Transform the points, and compute the position of this vertex.
vec2 position;
@ -37,7 +45,8 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
pathTransformST,
pathTransformExt,
uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);

View File

@ -13,8 +13,8 @@ precision highp float;
uniform vec4 uTransformST;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
attribute vec2 aQuadPosition;
attribute vec2 aUpperLeftPosition;
@ -26,13 +26,13 @@ varying vec2 vHorizontalExtents;
void main() {
int pathID = int(aPathID);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec4 transformST = fetchFloat4Data(uPathTransformST, pathID, uPathTransformSTDimensions);
vec2 upperLeftPosition = hintPosition(aUpperLeftPosition, uHints);
vec2 lowerRightPosition = hintPosition(aLowerRightPosition, uHints);
upperLeftPosition = transformVertexPositionST(upperLeftPosition, transform);
lowerRightPosition = transformVertexPositionST(lowerRightPosition, transform);
upperLeftPosition = transformVertexPositionST(upperLeftPosition, transformST);
lowerRightPosition = transformVertexPositionST(lowerRightPosition, transformST);
upperLeftPosition = transformVertexPositionST(upperLeftPosition, uTransformST);
lowerRightPosition = transformVertexPositionST(lowerRightPosition, uTransformST);

View File

@ -13,8 +13,8 @@ precision highp float;
uniform vec4 uTransformST;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform bool uWinding;
attribute vec2 aQuadPosition;
@ -33,7 +33,7 @@ void main() {
vec2 rightPosition = aRightPosition;
int pathID = int(aPathID);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec4 transformST = fetchFloat4Data(uPathTransformST, pathID, uPathTransformSTDimensions);
// Transform the points, and compute the position of this vertex.
vec2 position;
@ -42,11 +42,11 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
transformST,
uTransformST,
uHints)) {
controlPointPosition = hintPosition(aControlPointPosition, uHints);
controlPointPosition = transformVertexPositionST(controlPointPosition, transform);
controlPointPosition = transformVertexPositionST(controlPointPosition, transformST);
controlPointPosition = transformVertexPositionST(controlPointPosition, uTransformST);
controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize);
}

View File

@ -13,8 +13,8 @@ precision highp float;
uniform vec4 uTransformST;
uniform vec4 uHints;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform bool uWinding;
attribute vec2 aQuadPosition;
@ -30,7 +30,7 @@ void main() {
vec2 rightPosition = aRightPosition;
int pathID = int(aPathID);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec4 transformST = fetchFloat4Data(uPathTransformST, pathID, uPathTransformSTDimensions);
// Transform the points, and compute the position of this vertex.
vec2 position;
@ -39,7 +39,7 @@ void main() {
rightPosition,
aQuadPosition,
uFramebufferSize,
transform,
transformST,
uTransformST,
uHints);

View File

@ -15,8 +15,10 @@ uniform vec4 uHints;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform sampler2D uPathColors;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
@ -31,11 +33,17 @@ varying float vSign;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = hintPosition(position, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);

View File

@ -14,9 +14,11 @@ uniform mat4 uTransform;
uniform vec4 uHints;
uniform vec2 uEmboldenAmount;
uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathColors;
uniform sampler2D uPathTransform;
uniform ivec2 uPathTransformSTDimensions;
uniform sampler2D uPathTransformST;
uniform ivec2 uPathTransformExtDimensions;
uniform sampler2D uPathTransformExt;
attribute vec2 aPosition;
attribute float aPathID;
@ -28,11 +30,17 @@ varying float vSign;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 pathTransformExt;
vec4 pathTransformST = fetchPathAffineTransform(pathTransformExt,
uPathTransformST,
uPathTransformSTDimensions,
uPathTransformExt,
uPathTransformExtDimensions,
pathID);
vec2 position = dilatePosition(aPosition, aNormalAngle, uEmboldenAmount);
position = hintPosition(position, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPositionAffine(position, pathTransformST, pathTransformExt);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);