1.0.1: poly fill/stroke color

This commit is contained in:
SheetJS 2020-03-09 17:18:57 -04:00
parent 40c6036085
commit 10e0364e32
13 changed files with 119 additions and 75 deletions

1
.gitignore vendored

@ -2,3 +2,4 @@ fonts/
node_modules/
*.[wWeE][mM][fF]
*.[pP][nN][gG]
*.[tT][gG][zZ]

2
dist/wmf.js vendored

File diff suppressed because one or more lines are too long

2
dist/wmf.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/wmf.node.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -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

@ -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: {

@ -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);

@ -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];
};