1.0.1: poly fill/stroke color
This commit is contained in:
parent
40c6036085
commit
10e0364e32
|
@ -2,3 +2,4 @@ fonts/
|
|||
node_modules/
|
||||
*.[wWeE][mM][fF]
|
||||
*.[pP][nN][gG]
|
||||
*.[tT][gG][zZ]
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
js/canvas.js
11
js/canvas.js
|
@ -33,6 +33,12 @@ exports.render_actions_to_context = function (out, ctx) {
|
|||
switch (act.t) {
|
||||
case "poly":
|
||||
ctx.beginPath();
|
||||
if (act.s.Pen.Color != null)
|
||||
ctx.strokeStyle = exports.css_color(act.s.Pen.Color);
|
||||
if (act.s.Pen.Width > 0)
|
||||
ctx.lineWidth = act.s.Pen.Width;
|
||||
if (act.s.Brush.Color != null)
|
||||
ctx.fillStyle = exports.css_color(act.s.Brush.Color);
|
||||
ctx.moveTo(act.p[0][0], act.p[0][1]);
|
||||
act.p.slice(1).forEach(function (_a) {
|
||||
var x = _a[0], y = _a[1];
|
||||
|
@ -40,7 +46,10 @@ exports.render_actions_to_context = function (out, ctx) {
|
|||
});
|
||||
if (act.g)
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
if (act.s.Pen.Style != 5)
|
||||
ctx.stroke();
|
||||
if (act.s.Brush.Style != 1)
|
||||
ctx.fill();
|
||||
break;
|
||||
case "text":
|
||||
if (act.s && act.s.TextColor)
|
||||
|
|
File diff suppressed because one or more lines are too long
47
js/wmf.js
47
js/wmf.js
|
@ -50,18 +50,16 @@ var parse_dib = function (data) {
|
|||
return out;
|
||||
};
|
||||
var add_to_objects = function (objects, obj) {
|
||||
var found = false;
|
||||
for (var i = 0; i < objects.length; ++i)
|
||||
if (!objects[i]) {
|
||||
objects[i] = obj;
|
||||
found = true;
|
||||
return;
|
||||
}
|
||||
if (!found)
|
||||
objects.push(obj);
|
||||
objects.push(obj);
|
||||
};
|
||||
exports.get_actions_prepped_bytes = function (data) {
|
||||
var out = [];
|
||||
/* 2.3.22 META_HEADER */
|
||||
/* 2.3.2.2 META_HEADER */
|
||||
// Type (2 bytes) must be 1 or 2
|
||||
var h = data.read_shift(2);
|
||||
if (h != 1 && h != 2)
|
||||
|
@ -73,12 +71,15 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
h = data.read_shift(2);
|
||||
if (h != 0x0100 && h != 0x0300)
|
||||
throw "Header: Version " + h + " must be 0x0100 or 0x0300";
|
||||
// SizeLow
|
||||
// SizeHigh
|
||||
// SizeLow / SizeHigh
|
||||
data.l += 4;
|
||||
// #Objects
|
||||
var NumberOfObjects = data.read_shift(2);
|
||||
var objects = Array.from({ length: NumberOfObjects }, function () { return null; });
|
||||
// MaxRecord
|
||||
data.l += 4;
|
||||
// NumberOfMembers
|
||||
data.l = 18;
|
||||
data.l += 2;
|
||||
var rt = 0;
|
||||
/* used for EMF */
|
||||
var escapecnt = 0;
|
||||
|
@ -86,7 +87,6 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
var RemainingBytes = 0;
|
||||
var EnhancedMetafileDataSize = 0;
|
||||
var bufs = [];
|
||||
var objects = [];
|
||||
var states = [];
|
||||
var state = {};
|
||||
var sidx = -1;
|
||||
|
@ -102,7 +102,6 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
{ // META_ESCAPE
|
||||
var EscapeFunction = data.read_shift(2);
|
||||
var Escape = Records_1.WMFEscapes[EscapeFunction];
|
||||
//console.log("::", Escape);
|
||||
/* 2.3.6 */
|
||||
switch (EscapeFunction) {
|
||||
case 0x000F:
|
||||
|
@ -236,7 +235,7 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
var points = [];
|
||||
for (var i = 0; i < nPoints; ++i)
|
||||
points.push([data.read_shift(2), data.read_shift(2)]);
|
||||
out.push({ t: "poly", p: points, g: rt !== 0x0325, s: state });
|
||||
out.push({ t: "poly", p: points, g: rt !== 0x0325, s: Object.assign({}, state) });
|
||||
}
|
||||
break;
|
||||
case 0x0538:
|
||||
|
@ -251,7 +250,7 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
polys[i] = [];
|
||||
for (var j = 0; j < szs[i]; ++j)
|
||||
polys[i].push([data.read_shift(2), data.read_shift(2)]);
|
||||
out.push({ t: "poly", p: polys[i], g: true, s: state });
|
||||
out.push({ t: "poly", p: polys[i], g: true, s: Object.assign({}, state) });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -309,21 +308,18 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
case 0x01F0:
|
||||
{ // 2.3.4.7 META_DELETEOBJECT
|
||||
var ObjectIndex = data.read_shift(2);
|
||||
//console.log("DELETE", ObjectIndex, objects[ObjectIndex]);
|
||||
objects[ObjectIndex] = null;
|
||||
}
|
||||
break;
|
||||
case 0x012C:
|
||||
{ // 2.3.4.9 META_SELECTCLIPREGION
|
||||
var Region = data.read_shift(2);
|
||||
//console.log("CLIPREGION", Region, objects[Region]);
|
||||
//Object.assign(state, objects[Region]);
|
||||
}
|
||||
break;
|
||||
case 0x012D:
|
||||
{ // 2.3.4.10 META_SELECTOBJECT
|
||||
var ObjectIndex = data.read_shift(2);
|
||||
//console.log("SELECT", ObjectIndex, objects[ObjectIndex]);
|
||||
Object.assign(state, objects[ObjectIndex]);
|
||||
// TODO!!
|
||||
}
|
||||
|
@ -378,19 +374,16 @@ exports.get_actions_prepped_bytes = function (data) {
|
|||
break;
|
||||
// #endregion
|
||||
default:
|
||||
if (!Record)
|
||||
throw "Record: Unrecognized type 0x" + rt.toString(16);
|
||||
//if(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`;
|
||||
console.log(Record);
|
||||
}
|
||||
data.l = end;
|
||||
//if(rt != 0x0626) console.log(Record);
|
||||
}
|
||||
if (rt !== 0)
|
||||
throw "Record: Last Record Type " + rt + " is not EOF type";
|
||||
return out;
|
||||
};
|
||||
exports.image_size_prepped_bytes = function (data) {
|
||||
var origin = [NaN, NaN], extents = [NaN, NaN];
|
||||
/* 2.3.22 META_HEADER */
|
||||
// Type (2 bytes) must be 1 or 2
|
||||
var h = data.read_shift(2);
|
||||
|
@ -411,18 +404,14 @@ exports.image_size_prepped_bytes = function (data) {
|
|||
rt = data.read_shift(2);
|
||||
if (rt == 0x0000)
|
||||
break; // META_EOF
|
||||
switch (rt) {
|
||||
case 0x020C: // 2.3.5.30 META_SETWINDOWEXT
|
||||
extents[1] = data.read_shift(2);
|
||||
extents[0] = data.read_shift(2);
|
||||
break;
|
||||
case 0x020B: // 2.3.5.31 META_SETWINDOWORG
|
||||
origin[1] = data.read_shift(2);
|
||||
origin[0] = data.read_shift(2);
|
||||
break;
|
||||
if (rt == 0x020C) { // 2.3.5.30 META_SETWINDOWEXT
|
||||
var extents = [NaN, NaN];
|
||||
extents[1] = data.read_shift(2);
|
||||
extents[0] = data.read_shift(2);
|
||||
return extents;
|
||||
}
|
||||
data.l = end;
|
||||
}
|
||||
return [extents[0] - origin[0], extents[1] - origin[1]];
|
||||
return [NaN, NaN];
|
||||
};
|
||||
//# sourceMappingURL=wmf.js.map
|
File diff suppressed because one or more lines are too long
|
@ -10,7 +10,7 @@ module.exports = {
|
|||
output: {
|
||||
library: 'WMF',
|
||||
libraryTarget: 'var',
|
||||
filename: 'wmf.js',
|
||||
filename: 'wmf.js'
|
||||
},
|
||||
node: { process: false },
|
||||
module: {
|
||||
|
|
60
package.json
60
package.json
|
@ -1,20 +1,68 @@
|
|||
{
|
||||
"name": "wmf",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"author": "sheetjs",
|
||||
"description": "Windows MetaFile (WMF) parser",
|
||||
"keywords": [ "wmf", "image" ],
|
||||
"keywords": [
|
||||
"wmf",
|
||||
"image",
|
||||
"office",
|
||||
"word"
|
||||
],
|
||||
"bin": {
|
||||
},
|
||||
"main": "./dist/wmf.node.js",
|
||||
"browser": "./js/index.js",
|
||||
"unpkg": "./dist/wmf.js",
|
||||
"jsdelivr": "./dist/wmf.js",
|
||||
"types": "types",
|
||||
"browser": {
|
||||
"buffer": false,
|
||||
"crypto": false,
|
||||
"stream": false,
|
||||
"process": false,
|
||||
"fs": false
|
||||
},
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"source-map-loader": "^0.2.4",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/SheetJS/js-wmf.git"
|
||||
},
|
||||
"scripts": {
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
"pattern": "wmf.js"
|
||||
}
|
||||
},
|
||||
"alex": {
|
||||
"allow": [
|
||||
"special",
|
||||
"simple",
|
||||
"just",
|
||||
"crash",
|
||||
"wtf",
|
||||
"holes"
|
||||
]
|
||||
},
|
||||
"homepage": "https://sheetjs.com/",
|
||||
"files": ["dist/", "LICENSE", "README.md", "js/"],
|
||||
"bugs": { "url": "https://github.com/SheetJS/js-wmf/issues" },
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"dist/wmf.js",
|
||||
"dist/wmf.node.js",
|
||||
"dist/wmf.js.map",
|
||||
"dist/wmf.node.js.map"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/SheetJS/js-wmf/issues"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"engines": { "node": ">=12.0" }
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,16 @@ export const render_actions_to_context = (out: Action[], ctx: CanvasRenderingCon
|
|||
switch(act.t) {
|
||||
case "poly":
|
||||
ctx.beginPath();
|
||||
if(act.s.Pen.Color != null) ctx.strokeStyle = css_color(act.s.Pen.Color);
|
||||
if(act.s.Pen.Width > 0) ctx.lineWidth = act.s.Pen.Width;
|
||||
if(act.s.Brush.Color != null) ctx.fillStyle = css_color(act.s.Brush.Color);
|
||||
ctx.moveTo(act.p[0][0], act.p[0][1]);
|
||||
act.p.slice(1).forEach(([x,y]) => {
|
||||
ctx.lineTo(x, y);
|
||||
});
|
||||
if(act.g) ctx.closePath();
|
||||
ctx.stroke();
|
||||
if(act.s.Pen.Style != 5) ctx.stroke();
|
||||
if(act.s.Brush.Style != 1) ctx.fill();
|
||||
break;
|
||||
case "text":
|
||||
if(act.s && act.s.TextColor) ctx.fillStyle = css_color(act.s.TextColor);
|
||||
|
|
55
src/wmf.ts
55
src/wmf.ts
|
@ -164,29 +164,37 @@ const parse_dib = (data: PreppedBytes) => {
|
|||
}
|
||||
|
||||
const add_to_objects = (objects: PlaybackDeviceContextState[], obj: PlaybackDeviceContextState): void => {
|
||||
let found = false;
|
||||
for(var i = 0; i < objects.length; ++i) if(!objects[i]) { objects[i] = obj; found = true; }
|
||||
if(!found) objects.push(obj);
|
||||
for(var i = 0; i < objects.length; ++i) if(!objects[i]) { objects[i] = obj; return }
|
||||
objects.push(obj);
|
||||
}
|
||||
|
||||
export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
||||
const out: Action[] = [];
|
||||
|
||||
/* 2.3.22 META_HEADER */
|
||||
/* 2.3.2.2 META_HEADER */
|
||||
// Type (2 bytes) must be 1 or 2
|
||||
let h = data.read_shift(2);
|
||||
if(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`;
|
||||
|
||||
// HeaderSize expected to be 9
|
||||
if((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`;
|
||||
|
||||
// Version (2 bytes) 1 or 3
|
||||
h = data.read_shift(2);
|
||||
if(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`;
|
||||
// SizeLow
|
||||
// SizeHigh
|
||||
|
||||
// SizeLow / SizeHigh
|
||||
data.l += 4;
|
||||
|
||||
// #Objects
|
||||
const NumberOfObjects = data.read_shift(2);
|
||||
let objects: PlaybackDeviceContextState[] = Array.from({length: NumberOfObjects}, () => null);
|
||||
|
||||
// MaxRecord
|
||||
data.l += 4;
|
||||
|
||||
// NumberOfMembers
|
||||
data.l = 18;
|
||||
data.l += 2;
|
||||
|
||||
let rt = 0;
|
||||
|
||||
|
@ -197,7 +205,6 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
let EnhancedMetafileDataSize = 0;
|
||||
let bufs: RawBytes[] = [];
|
||||
|
||||
let objects: PlaybackDeviceContextState[] = [];
|
||||
let states: PlaybackDeviceContextState[] = [];
|
||||
let state: PlaybackDeviceContextState = {};
|
||||
let sidx = -1;
|
||||
|
@ -209,12 +216,10 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
rt = data.read_shift(2);
|
||||
let Record = WMFRecords[rt];
|
||||
if(rt == 0x0000) break; // META_EOF
|
||||
|
||||
switch(rt) {
|
||||
case 0x0626: { // META_ESCAPE
|
||||
const EscapeFunction = data.read_shift(2);
|
||||
const Escape = WMFEscapes[EscapeFunction];
|
||||
//console.log("::", Escape);
|
||||
/* 2.3.6 */
|
||||
switch(EscapeFunction) {
|
||||
case 0x000F: { // META_ESCAPE_ENHANCED_METAFILE
|
||||
|
@ -335,7 +340,7 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
const nPoints = data.read_shift(2);
|
||||
const points: Array<Point> = [];
|
||||
for(let i = 0; i < nPoints; ++i) points.push([data.read_shift(2), data.read_shift(2)])
|
||||
out.push({t: "poly", p: points, g: rt !== 0x0325, s: state});
|
||||
out.push({t: "poly", p: points, g: rt !== 0x0325, s: Object.assign({}, state)});
|
||||
} break;
|
||||
|
||||
case 0x0538: { // 2.3.3.16 META_POLYPOLYGON
|
||||
|
@ -347,7 +352,7 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
for(let i = 0; i < szs.length; ++i) {
|
||||
polys[i] = [];
|
||||
for(let j = 0; j < szs[i]; ++j) polys[i].push([data.read_shift(2), data.read_shift(2)])
|
||||
out.push({t: "poly", p: polys[i], g: true, s: state});
|
||||
out.push({t: "poly", p: polys[i], g: true, s: Object.assign({}, state)});
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -403,19 +408,16 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
|
||||
case 0x01F0: { // 2.3.4.7 META_DELETEOBJECT
|
||||
const ObjectIndex = data.read_shift(2);
|
||||
//console.log("DELETE", ObjectIndex, objects[ObjectIndex]);
|
||||
objects[ObjectIndex] = null;
|
||||
} break;
|
||||
|
||||
case 0x012C: { // 2.3.4.9 META_SELECTCLIPREGION
|
||||
const Region = data.read_shift(2);
|
||||
//console.log("CLIPREGION", Region, objects[Region]);
|
||||
//Object.assign(state, objects[Region]);
|
||||
} break;
|
||||
|
||||
case 0x012D: { // 2.3.4.10 META_SELECTOBJECT
|
||||
const ObjectIndex = data.read_shift(2);
|
||||
//console.log("SELECT", ObjectIndex, objects[ObjectIndex]);
|
||||
Object.assign(state, objects[ObjectIndex]);
|
||||
// TODO!!
|
||||
} break;
|
||||
|
@ -482,19 +484,16 @@ export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {
|
|||
// #endregion
|
||||
|
||||
default:
|
||||
if(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`;
|
||||
//if(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`;
|
||||
console.log(Record);
|
||||
}
|
||||
data.l = end;
|
||||
//if(rt != 0x0626) console.log(Record);
|
||||
}
|
||||
if(rt !== 0) throw `Record: Last Record Type ${rt} is not EOF type`;
|
||||
return out;
|
||||
}
|
||||
|
||||
export const image_size_prepped_bytes = (data: PreppedBytes): [number, number] => {
|
||||
const origin: Point = [NaN, NaN], extents: Point = [NaN, NaN];
|
||||
|
||||
/* 2.3.22 META_HEADER */
|
||||
// Type (2 bytes) must be 1 or 2
|
||||
let h = data.read_shift(2);
|
||||
|
@ -514,20 +513,14 @@ export const image_size_prepped_bytes = (data: PreppedBytes): [number, number] =
|
|||
|
||||
rt = data.read_shift(2);
|
||||
if(rt == 0x0000) break; // META_EOF
|
||||
|
||||
switch(rt) {
|
||||
case 0x020C: // 2.3.5.30 META_SETWINDOWEXT
|
||||
extents[1] = data.read_shift(2);
|
||||
extents[0] = data.read_shift(2);
|
||||
break;
|
||||
|
||||
case 0x020B: // 2.3.5.31 META_SETWINDOWORG
|
||||
origin[1] = data.read_shift(2);
|
||||
origin[0] = data.read_shift(2);
|
||||
break;
|
||||
if(rt == 0x020C) {// 2.3.5.30 META_SETWINDOWEXT
|
||||
const extents: [number, number] = [NaN, NaN];
|
||||
extents[1] = data.read_shift(2);
|
||||
extents[0] = data.read_shift(2);
|
||||
return extents;
|
||||
}
|
||||
data.l = end;
|
||||
}
|
||||
|
||||
return [extents[0] - origin[0], extents[1] - origin[1]];
|
||||
return [NaN, NaN];
|
||||
};
|
Loading…
Reference in New Issue