From 275a937439fbd02dfc63a43dabee558aedabf54c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 4 Jan 2018 14:14:47 -0800 Subject: [PATCH] Fix colors and view box for the reference in the SVG reftest --- demo/client/src/benchmark.ts | 10 +++++----- demo/client/src/reference-test.ts | 11 +++++------ demo/client/src/svg-demo.ts | 8 ++++---- demo/client/src/svg-loader.ts | 22 ++++++++++------------ demo/client/src/svg-renderer.ts | 19 +++++++++++++++---- demo/server/src/main.rs | 4 +++- resources/svg/Ghostscript_Tiger.svg | 4 ++-- 7 files changed, 44 insertions(+), 34 deletions(-) diff --git a/demo/client/src/benchmark.ts b/demo/client/src/benchmark.ts index 12a8f234..a329bff0 100644 --- a/demo/client/src/benchmark.ts +++ b/demo/client/src/benchmark.ts @@ -243,7 +243,7 @@ class BenchmarkAppController extends DemoAppController { this.view.then(view => { view.recreateRenderer(); view.attachMeshes([meshes]); - view.initCameraBounds(this.svgLoader.svgBounds); + view.initCameraBounds(this.svgLoader.svgViewBox); }); }); } @@ -401,9 +401,9 @@ class BenchmarkTestView extends DemoView { } } - initCameraBounds(bounds: glmatrix.vec4): void { + initCameraBounds(viewBox: glmatrix.vec4): void { if (this.renderer instanceof BenchmarkSVGRenderer) - this.renderer.initCameraBounds(bounds); + this.renderer.initCameraBounds(viewBox); } protected renderingFinished(): void { @@ -470,7 +470,7 @@ class BenchmarkTextRenderer extends Renderer { return glmatrix.vec2.clone([1.0, 1.0]); } - protected get worldTransform() { + protected get worldTransform(): glmatrix.mat4 { const canvas = this.renderContext.canvas; const transform = glmatrix.mat4.create(); @@ -612,7 +612,7 @@ class BenchmarkSVGRenderer extends SVGRenderer { } constructor(renderContext: BenchmarkTestView) { - super(renderContext); + super(renderContext, {sizeToFit: false}); } } diff --git a/demo/client/src/reference-test.ts b/demo/client/src/reference-test.ts index 10e3f188..a5630c29 100644 --- a/demo/client/src/reference-test.ts +++ b/demo/client/src/reference-test.ts @@ -516,7 +516,7 @@ class ReferenceTestAppController extends DemoAppController { this.view.then(view => { view.recreateRenderer(); view.attachMeshes([meshes]); - view.initCameraBounds(this.svgLoader.svgBounds); + view.initCameraBounds(this.svgLoader.svgViewBox); }); }); } @@ -537,7 +537,6 @@ class ReferenceTestAppController extends DemoAppController { break; case 'svg': // TODO(pcwalton): Custom SVGs. - // TODO(pcwalton): Detect scale. request = { name: unwrapNull(this.builtinSvgName), renderer: 'pixman', @@ -614,9 +613,9 @@ class ReferenceTestView extends DemoView { } } - initCameraBounds(bounds: glmatrix.vec4): void { + initCameraBounds(viewBox: glmatrix.vec4): void { if (this.renderer instanceof ReferenceTestSVGRenderer) - this.renderer.initCameraBounds(bounds); + this.renderer.initCameraBounds(viewBox); } protected renderingFinished(): void { @@ -701,7 +700,7 @@ class ReferenceTestTextRenderer extends Renderer { return glmatrix.vec2.clone([1.0, 1.0]); } - protected get worldTransform() { + protected get worldTransform(): glmatrix.mat4 { const canvas = this.renderContext.canvas; const transform = glmatrix.mat4.create(); @@ -836,7 +835,7 @@ class ReferenceTestSVGRenderer extends SVGRenderer { } constructor(renderContext: ReferenceTestView) { - super(renderContext); + super(renderContext, {sizeToFit: false}); } } diff --git a/demo/client/src/svg-demo.ts b/demo/client/src/svg-demo.ts index 01d6ffec..597c5203 100644 --- a/demo/client/src/svg-demo.ts +++ b/demo/client/src/svg-demo.ts @@ -62,7 +62,7 @@ class SVGDemoController extends DemoAppController { private meshesReceived(): void { this.view.then(view => { view.attachMeshes([this.meshes]); - view.initCameraBounds(this.loader.svgBounds); + view.initCameraBounds(this.loader.svgViewBox); }); } } @@ -82,13 +82,13 @@ class SVGDemoView extends DemoView { super(gammaLUT, commonShaderSource, shaderSources); this.appController = appController; - this.renderer = new SVGDemoRenderer(this); + this.renderer = new SVGDemoRenderer(this, {sizeToFit: true}); this.resizeToFit(true); } - initCameraBounds(bounds: glmatrix.vec4): void { - this.renderer.initCameraBounds(bounds); + initCameraBounds(viewBox: glmatrix.vec4): void { + this.renderer.initCameraBounds(viewBox); } } diff --git a/demo/client/src/svg-loader.ts b/demo/client/src/svg-loader.ts index 4c0e7dc8..ceac148d 100644 --- a/demo/client/src/svg-loader.ts +++ b/demo/client/src/svg-loader.ts @@ -95,6 +95,7 @@ export class SVGLoader { scale: number; pathBounds: glmatrix.vec4[]; svgBounds: glmatrix.vec4; + svgViewBox: glmatrix.vec4; isMonochrome: boolean; private svg: SVGSVGElement; @@ -146,6 +147,10 @@ export class SVGLoader { while ((kid = svgElement.firstChild) != null) this.svg.appendChild(kid); + const viewBox = svgElement.viewBox.baseVal; + this.svg.setAttribute('width', "" + viewBox.width); + this.svg.setAttribute('height', "" + viewBox.height); + // Scan for geometry elements. this.pathInstances.length = 0; this.clipPathIDs = {}; @@ -153,15 +158,12 @@ export class SVGLoader { this.paths = []; - const svgBottomLeft = glmatrix.vec2.create(), svgTopRight = glmatrix.vec2.create(); - for (const instance of this.pathInstances) { const element = instance.element; const svgCTM = element.getCTM(); - const ctm = glmatrix.mat2d.fromValues(svgCTM.a, svgCTM.b, - svgCTM.c, svgCTM.d, - svgCTM.e, svgCTM.f); - glmatrix.mat2d.scale(ctm, ctm, [1.0, -1.0]); + const ctm = glmatrix.mat2d.fromValues(svgCTM.a, -svgCTM.b, + svgCTM.c, -svgCTM.d, + svgCTM.e, viewBox.height - svgCTM.f); glmatrix.mat2d.scale(ctm, ctm, [this.scale, this.scale]); const bottomLeft = glmatrix.vec2.create(); @@ -188,9 +190,6 @@ export class SVGLoader { topRight[0], topRight[1], ]); - glmatrix.vec2.min(svgBottomLeft, svgBottomLeft, bottomLeft); - glmatrix.vec2.max(svgTopRight, svgTopRight, topRight); - if (instance instanceof SVGFill) { this.paths.push({ kind: { Fill: instance.pathfinderFillRule }, @@ -207,9 +206,8 @@ export class SVGLoader { return glmatrix.vec4.equals(pathInstance.color, this.pathInstances[0].color); }); - this.svgBounds = glmatrix.vec4.clone([ - svgBottomLeft[0], svgBottomLeft[1], - svgTopRight[0], svgTopRight[1], + this.svgViewBox = glmatrix.vec4.clone([ + viewBox.x, viewBox.y, viewBox.x + viewBox.width, viewBox.y + viewBox.height, ]); } diff --git a/demo/client/src/svg-renderer.ts b/demo/client/src/svg-renderer.ts index 8922c808..63f8d966 100644 --- a/demo/client/src/svg-renderer.ts +++ b/demo/client/src/svg-renderer.ts @@ -35,11 +35,17 @@ const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = { xcaa: MCAAStrategy, }; +export interface SVGRendererOptions { + sizeToFit?: boolean; +} + export abstract class SVGRenderer extends Renderer { renderContext: RenderContext; camera: OrthographicCamera; + private options: SVGRendererOptions; + get isMulticolor(): boolean { return !this.loader.isMonochrome; } @@ -80,9 +86,11 @@ export abstract class SVGRenderer extends Renderer { protected abstract get loader(): SVGLoader; protected abstract get canvas(): HTMLCanvasElement; - constructor(renderContext: RenderContext) { + constructor(renderContext: RenderContext, options: SVGRendererOptions) { super(renderContext); + this.options = options; + this.camera = new OrthographicCamera(this.canvas, { scaleBounds: true }); this.camera.onPan = () => this.renderContext.setDirty(); this.camera.onZoom = () => this.renderContext.setDirty(); @@ -107,9 +115,12 @@ export abstract class SVGRenderer extends Renderer { this.uploadPathTransforms(1); } - initCameraBounds(bounds: glmatrix.vec4): void { - this.camera.bounds = bounds; - this.camera.zoomToFit(); + initCameraBounds(svgViewBox: glmatrix.vec4): void { + // The SVG origin is in the upper left, but the camera origin is in the lower left. + this.camera.bounds = svgViewBox; + + if (this.options.sizeToFit) + this.camera.zoomToFit(); } meshIndexForObject(objectIndex: number): number { diff --git a/demo/server/src/main.rs b/demo/server/src/main.rs index f25d8c80..c03fabac 100644 --- a/demo/server/src/main.rs +++ b/demo/server/src/main.rs @@ -640,7 +640,9 @@ fn render_reference_svg(request: Json) svg_handle.render_cairo(&cairo_context); } - let image_data = (*surface.get_data().unwrap()).to_vec(); + let mut image_data = (*surface.get_data().unwrap()).to_vec(); + image_data.chunks_mut(4).for_each(|color| color.swap(0, 2)); + let image_buffer = match ImageBuffer::from_raw(image_size.width as u32, image_size.height as u32, image_data) { diff --git a/resources/svg/Ghostscript_Tiger.svg b/resources/svg/Ghostscript_Tiger.svg index 67ba6369..30a544a0 100644 --- a/resources/svg/Ghostscript_Tiger.svg +++ b/resources/svg/Ghostscript_Tiger.svg @@ -1,6 +1,6 @@ - - + +