1.0.1: poly fill/stroke color
This commit is contained in:
parent
40c6036085
commit
10e0364e32
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ fonts/
|
||||
node_modules/
|
||||
*.[wWeE][mM][fF]
|
||||
*.[pP][nN][gG]
|
||||
*.[tT][gG][zZ]
|
||||
|
2
dist/wmf.js
vendored
2
dist/wmf.js
vendored
File diff suppressed because one or more lines are too long
2
dist/wmf.js.map
vendored
2
dist/wmf.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/wmf.node.js
vendored
2
dist/wmf.node.js
vendored
File diff suppressed because one or more lines are too long
2
dist/wmf.node.js.map
vendored
2
dist/wmf.node.js.map
vendored
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
Block a user