Init SvgToDrawingConverter

This commit is contained in:
ziajka 2018-05-14 15:05:56 +02:00
parent 3ddc2ee550
commit 44f4388e41
7 changed files with 119 additions and 1 deletions

View File

@ -0,0 +1,35 @@
import { SvgToDrawingConverter } from "./svg-to-drawing-converter";
describe('SvgToDrawingHelper', () => {
let svgToDrawingConverter: SvgToDrawingConverter;
beforeEach(() => {
svgToDrawingConverter = new SvgToDrawingConverter();
});
it('should raise Error on empty string', () => {
expect(() => svgToDrawingConverter.convert("")).toThrowError(Error);
});
it('should raise Error on no children', () => {
expect(() => svgToDrawingConverter.convert("<svg></svg>")).toThrowError(Error);
});
it('should raise Error on unknown parser', () => {
expect(() => svgToDrawingConverter.convert("<svg><unkown></unkown></svg>")).toThrowError(Error);
});
it('should parse text drawing', () => {
const svg = '<svg height="53" width="78">' +
'<text fill="#000000" fill-opacity="1.0" font-family="TypeWriter" font-size="10.0" font-weight="bold">' +
'Line' +
'</text>' +
'</svg>';
const drawing = svgToDrawingConverter.convert(svg);
expect(drawing.width).toBe(78);
expect(drawing.height).toBe(53);
});
});

View File

@ -0,0 +1,47 @@
import { Injectable } from "@angular/core";
import { DrawingElement } from "../../shared/models/drawings/drawing-element";
import { SvgConverter } from "./svg-to-drawing-converter/svg-converter";
import { TextConverter } from "./svg-to-drawing-converter/text-converter";
@Injectable()
export class SvgToDrawingConverter {
private parser: DOMParser;
private elementParsers: { [key: string]: SvgConverter };
constructor() {
this.parser = new DOMParser();
this.elementParsers = {
'text': new TextConverter()
};
}
convert(svg: string): DrawingElement {
const svgDom = this.parser.parseFromString(svg, 'text/xml');
const roots = svgDom.getElementsByTagName('svg');
if (roots.length !== 1) {
throw new Error(`Cannot locate svg element root in '${svg}'`);
}
const svgRoot = roots[0];
const child = svgRoot.firstChild;
if (!child) {
throw new Error(`Cannot find first child in '${svg}`);
}
const name = child.nodeName;
if (!(name in this.elementParsers)) {
throw new Error(`Cannot find parser for '${name}'`);
}
const parser = this.elementParsers[name];
const drawing = parser.convert(child);
drawing.width = +svgRoot.getAttribute('width');
drawing.height = +svgRoot.getAttribute('height');
return drawing;
}
}

View File

@ -0,0 +1,5 @@
import { DrawingElement } from "../../../shared/models/drawings/drawing-element";
export interface SvgConverter {
convert(node: Node): DrawingElement;
}

View File

@ -0,0 +1,15 @@
import { SvgConverter } from "./svg-converter";
import { DrawingElement } from "../../../shared/models/drawings/drawing-element";
import { TextElement } from "../../../shared/models/drawings/text-element";
export class TextConverter implements SvgConverter {
convert(node: Node): DrawingElement {
const drawing = new TextElement();
const fill = node.attributes.getNamedItem('fill');
if (fill) {
drawing.fill = fill.value;
}
return drawing;
}
}

View File

@ -0,0 +1,4 @@
export interface DrawingElement {
width: number;
height: number;
}

View File

@ -0,0 +1,12 @@
import { DrawingElement } from "./drawing-element";
export class TextElement implements DrawingElement {
height: number;
width: number;
fill: string;
fill_opacity: string;
font_family: string;
font_size: string;
font_weight: number;
}

View File

@ -42,7 +42,7 @@ export class DrawingsWidget implements Widget {
return 0;
})
.attr('height', (d: Drawing) => {
const svg_dom = parser.parseFromString(d.svg, 'text/xml');
const svg_dom = parser.parseFromString(d.svg, 'text/xml');
const roots = svg_dom.getElementsByTagName('svg');
if (roots.length > 0) {
if (roots[0].hasAttribute('height')) {