import { SVG } from "../util" ; import { Blob } from "./Blob" ; import { GDIContext } from "./GDIContext" ; import { Helper , WMFJSError } from "./Helper" ; import { WMFRecords } from "./WMFRecords" ; export interface IRendererSettings { width : string ; height : string ; xExt : number ; yExt : number ; mapMode : number ; } export class Renderer { private _img : WMF ; constructor ( blob ) { this . parse ( blob ) ; Helper . log ( "WMFJS.Renderer instantiated" ) ; } public render ( info ) { const svgElement = document . createElementNS ( "http://www.w3.org/2000/svg" , "svg" ) ; this . _render ( new SVG ( svgElement ) , info . mapMode , info . xExt , info . yExt ) ; svgElement . setAttribute ( "viewBox" , [ 0 , 0 , info . xExt , info . yExt ] . join ( " " ) ) ; svgElement . setAttribute ( "preserveAspectRatio" , "none" ) ; svgElement . setAttribute ( "width" , info . width ) ; svgElement . setAttribute ( "height" , info . height ) ; return svgElement ; } private parse ( blob ) { this . _img = null ; const reader = new Blob ( blob ) ; let type ; let size ; let placable ; let headerstart ; const key = reader . readUint32 ( ) ; if ( key === 0x9ac6cdd7 ) { placable = new WMFPlacable ( reader ) ; headerstart = reader . pos ; type = reader . readUint16 ( ) ; size = reader . readUint16 ( ) ; } else { headerstart = 0 ; type = key & 0xffff ; size = ( key >>> 16 ) & 0xffff ; } switch ( type ) { case Helper . GDI . MetafileType . MEMORYMETAFILE : case Helper . GDI . MetafileType . DISKMETAFILE : if ( size === Helper . GDI . METAHEADER_SIZE / 2 ) { const version = reader . readUint16 ( ) ; switch ( version ) { case Helper . GDI . MetafileVersion . METAVERSION100 : case Helper . GDI . MetafileVersion . METAVERSION300 : this . _img = new WMF ( reader , placable , version , headerstart + ( size * 2 ) ) ; break ; } } break ; } if ( this . _img == null ) { throw new WMFJSError ( "Format not recognized" ) ; } } private _render ( svg , mapMode , xExt , yExt ) { const gdi = new GDIContext ( svg ) ; gdi . setViewportExt ( xExt , yExt ) ; gdi . setMapMode ( mapMode ) ; Helper . log ( "[WMF] BEGIN RENDERING --->" ) ; this . _img . render ( gdi ) ; Helper . log ( "[WMF] <--- DONE RENDERING" ) ; } } class WMFRect16 { private left : number ; private top : number ; private right : number ; private bottom : number ; constructor ( reader ) { this . left = reader . readInt16 ( ) ; this . top = reader . readInt16 ( ) ; this . right = reader . readInt16 ( ) ; this . bottom = reader . readInt16 ( ) ; } public toString ( ) { return "{left: " + this . left + ", top: " + this . top + ", right: " + this . right + ", bottom: " + this . bottom + "}" ; } } class WMFPlacable { private boundingBox : WMFRect16 ; private unitsPerInch : number ; constructor ( reader ) { reader . skip ( 2 ) ; this . boundingBox = new WMFRect16 ( reader ) ; this . unitsPerInch = reader . readInt16 ( ) ; reader . skip ( 4 ) ; reader . skip ( 2 ) ; Helper . log ( "Got bounding box " + this . boundingBox + " and " + this . unitsPerInch + " units/inch" ) ; } } class WMF { private _version : number ; private _hdrsize : number ; private _placable : WMFPlacable ; private _records : WMFRecords ; constructor ( reader , placable , version , hdrsize ) { this . _version = version ; this . _hdrsize = hdrsize ; this . _placable = placable ; this . _records = new WMFRecords ( reader , this . _hdrsize ) ; } public render ( gdi ) { this . _records . play ( gdi ) ; } }