Initial commit
This commit is contained in:
commit
a950194247
18 changed files with 2670 additions and 0 deletions
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["svelte.svelte-vscode"]
|
||||||
|
}
|
47
README.md
Normal file
47
README.md
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# Svelte + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Svelte in Vite.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
|
||||||
|
|
||||||
|
## Need an official Svelte framework?
|
||||||
|
|
||||||
|
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
|
||||||
|
|
||||||
|
## Technical considerations
|
||||||
|
|
||||||
|
**Why use this over SvelteKit?**
|
||||||
|
|
||||||
|
- It brings its own routing solution which might not be preferable for some users.
|
||||||
|
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
|
||||||
|
|
||||||
|
This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
|
||||||
|
|
||||||
|
Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
|
||||||
|
|
||||||
|
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
|
||||||
|
|
||||||
|
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
|
||||||
|
|
||||||
|
**Why include `.vscode/extensions.json`?**
|
||||||
|
|
||||||
|
Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
|
||||||
|
|
||||||
|
**Why enable `checkJs` in the JS template?**
|
||||||
|
|
||||||
|
It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration.
|
||||||
|
|
||||||
|
**Why is HMR not preserving my local component state?**
|
||||||
|
|
||||||
|
HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
|
||||||
|
|
||||||
|
If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// store.js
|
||||||
|
// An extremely simple external store
|
||||||
|
import { writable } from 'svelte/store'
|
||||||
|
export default writable(0)
|
||||||
|
```
|
25
index.html
Normal file
25
index.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-us">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="description" content="Free online embroidery files viewer." />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="author" content="Leonardo Murça" />
|
||||||
|
|
||||||
|
<meta property="og:locale" content="en-us">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="Embroidery Viewer">
|
||||||
|
<meta property="og:description" content="Free online embroidery files viewer." />
|
||||||
|
<meta property="og:url" content="https://embroideryviewer.xyz/">
|
||||||
|
<meta property="og:site_name" content="Embroidery Viewer">
|
||||||
|
|
||||||
|
<title>Embroidery Viewer</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
33
jsconfig.json
Normal file
33
jsconfig.json
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
/**
|
||||||
|
* svelte-preprocess cannot figure out whether you have
|
||||||
|
* a value or a type, so tell TypeScript to enforce using
|
||||||
|
* `import type` instead of `import` for Types.
|
||||||
|
*/
|
||||||
|
"importsNotUsedAsValues": "error",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
/**
|
||||||
|
* To have warnings / errors of the Svelte compiler at the
|
||||||
|
* correct position, enable source maps by default.
|
||||||
|
*/
|
||||||
|
"sourceMap": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
/**
|
||||||
|
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||||
|
* Disable this if you'd like to use dynamic types.
|
||||||
|
*/
|
||||||
|
"checkJs": true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Use global.d.ts instead of compilerOptions.types
|
||||||
|
* to avoid limiting type declarations.
|
||||||
|
*/
|
||||||
|
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
|
||||||
|
}
|
1078
package-lock.json
generated
Normal file
1078
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
19
package.json
Normal file
19
package.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "embroidery-viewer",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^1.1.0",
|
||||||
|
"svelte": "^3.52.0",
|
||||||
|
"vite": "^3.2.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jdataview": "^2.5.0"
|
||||||
|
}
|
||||||
|
}
|
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
22
src/App.svelte
Normal file
22
src/App.svelte
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<script>
|
||||||
|
import Counter from './lib/Counter.svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>Embroidery Viewer</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<Counter />
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<p>Copyright © 2022 Leonardo Murça.</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
29
src/app.css
Normal file
29
src/app.css
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 400;
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 80%;
|
||||||
|
background-color: #e5e5e5;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
143
src/lib/Counter.svelte
Normal file
143
src/lib/Counter.svelte
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<script>
|
||||||
|
import { startFileRead } from './main';
|
||||||
|
|
||||||
|
let files;
|
||||||
|
const acceptedFiles = [".pes"];
|
||||||
|
const maxFileSize = 700000;
|
||||||
|
|
||||||
|
function onSubmitHandler(evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
for (var i = 0, file; (file = files[i]); i++) {
|
||||||
|
const canvasContainer = document.getElementById("canvas-container")
|
||||||
|
const canvasCard = document.createElement(`div`)
|
||||||
|
const canvasEl = document.createElement(`canvas`)
|
||||||
|
const fileNameEl = document.createElement(`p`)
|
||||||
|
|
||||||
|
canvasCard.id = `canvas-card-${i}`
|
||||||
|
canvasCard.style['display'] = "flex"
|
||||||
|
canvasCard.style['flex-direction'] = "column"
|
||||||
|
canvasCard.style['justify-content'] = "center"
|
||||||
|
canvasCard.style['align-items'] = "center"
|
||||||
|
canvasCard.style['width'] = "550px"
|
||||||
|
canvasCard.style['height'] = "550px"
|
||||||
|
canvasCard.style['margin-bottom'] = "15px"
|
||||||
|
canvasCard.style['border'] = "2px solid black"
|
||||||
|
|
||||||
|
canvasEl.id = `mycanvas-${i}`
|
||||||
|
canvasEl.style["height"] = "80%";
|
||||||
|
canvasEl.style["width"] = "fit-content";
|
||||||
|
|
||||||
|
fileNameEl.textContent = file.name
|
||||||
|
|
||||||
|
canvasCard.appendChild(canvasEl)
|
||||||
|
canvasCard.appendChild(fileNameEl)
|
||||||
|
canvasContainer.appendChild(canvasCard)
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
startFileRead(file, canvasEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragOver(evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDropHandler(evt) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
evt.preventDefault();
|
||||||
|
onChangeFileHandler(evt)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeFileHandler(evt) {
|
||||||
|
const changedFiles = evt.dataTransfer ? evt.dataTransfer.files : evt.target.files;
|
||||||
|
let filesToUpload = [];
|
||||||
|
for (var i = 0, file; (file = changedFiles[i]); i++) {
|
||||||
|
if (file) {
|
||||||
|
if (file.size <= maxFileSize) {
|
||||||
|
filesToUpload.push(file);
|
||||||
|
} else {
|
||||||
|
console.log("File too large!")
|
||||||
|
console.log(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
files = filesToUpload
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnClick(evt) {
|
||||||
|
document.getElementById("file-input").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOnKeydown(evt) {
|
||||||
|
console.log(evt)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form
|
||||||
|
on:submit={onSubmitHandler}
|
||||||
|
id="form"
|
||||||
|
action="#"
|
||||||
|
enctype="multipart/form-data">
|
||||||
|
<h2>Upload files</h2>
|
||||||
|
<p>Max file size is <strong>{maxFileSize/1000}kb</strong>. Accepted formats: <strong>{acceptedFiles.join(",")}</strong>.</p>
|
||||||
|
|
||||||
|
<div id="dropzone" on:keydown={handleOnKeydown} on:click={handleOnClick} on:dragover={handleDragOver} on:drop={onDropHandler}>
|
||||||
|
<label id="file-label" for="file-input">Drag and drop files here or click to upload.</label>
|
||||||
|
<input id="file-input" type="file" name="files[]" accept={acceptedFiles.join(",")} multiple on:change={onChangeFileHandler} />
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="Render files">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="canvas-container" style="width: 100%; heigth: 100vh;"></div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
input[type="submit"] {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 30px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"]:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dropzone {
|
||||||
|
display: flex;
|
||||||
|
height: 100px;
|
||||||
|
width: 500px;
|
||||||
|
border: 5px dotted black;
|
||||||
|
padding: 15px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#file-label {
|
||||||
|
z-index: -1;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
#file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas-container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dropzone:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 5px dotted #7FB77E;
|
||||||
|
color: #7FB77E;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
848
src/lib/jdataview.js
Normal file
848
src/lib/jdataview.js
Normal file
|
@ -0,0 +1,848 @@
|
||||||
|
// @ts-nocheck
|
||||||
|
//
|
||||||
|
// jDataView by Vjeux <vjeuxx@gmail.com> - Jan 2010
|
||||||
|
// Continued by RReverser <me@rreverser.com> - Feb 2013
|
||||||
|
//
|
||||||
|
// A unique way to work with a binary file in the browser
|
||||||
|
// http://github.com/jDataView/jDataView
|
||||||
|
// http://jDataView.github.io/
|
||||||
|
|
||||||
|
var compatibility = {
|
||||||
|
// NodeJS Buffer in v0.5.5 and newer
|
||||||
|
NodeBuffer: "Buffer" in globalThis && "readInt16LE" in Buffer.prototype,
|
||||||
|
DataView:
|
||||||
|
"DataView" in globalThis &&
|
||||||
|
("getFloat64" in DataView.prototype || // Chrome
|
||||||
|
"getFloat64" in new DataView(new ArrayBuffer(1))), // Node
|
||||||
|
ArrayBuffer: "ArrayBuffer" in globalThis,
|
||||||
|
PixelData:
|
||||||
|
"CanvasPixelArray" in globalThis &&
|
||||||
|
"ImageData" in globalThis &&
|
||||||
|
"document" in globalThis,
|
||||||
|
};
|
||||||
|
|
||||||
|
var createPixelData = function (byteLength, buffer) {
|
||||||
|
var data = createPixelData.context2d.createImageData(
|
||||||
|
(byteLength + 3) / 4,
|
||||||
|
1
|
||||||
|
).data;
|
||||||
|
data.byteLength = byteLength;
|
||||||
|
if (buffer !== undefined) {
|
||||||
|
for (var i = 0; i < byteLength; i++) {
|
||||||
|
data[i] = buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
createPixelData.context2d = document.createElement("canvas").getContext("2d");
|
||||||
|
|
||||||
|
var dataTypes = {
|
||||||
|
Int8: 1,
|
||||||
|
Int16: 2,
|
||||||
|
Int32: 4,
|
||||||
|
Uint8: 1,
|
||||||
|
Uint16: 2,
|
||||||
|
Uint32: 4,
|
||||||
|
Float32: 4,
|
||||||
|
Float64: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
var nodeNaming = {
|
||||||
|
Int8: "Int8",
|
||||||
|
Int16: "Int16",
|
||||||
|
Int32: "Int32",
|
||||||
|
Uint8: "UInt8",
|
||||||
|
Uint16: "UInt16",
|
||||||
|
Uint32: "UInt32",
|
||||||
|
Float32: "Float",
|
||||||
|
Float64: "Double",
|
||||||
|
};
|
||||||
|
|
||||||
|
function arrayFrom(arrayLike, forceCopy) {
|
||||||
|
return !forceCopy && arrayLike instanceof Array
|
||||||
|
? arrayLike
|
||||||
|
: Array.prototype.slice.call(arrayLike);
|
||||||
|
}
|
||||||
|
|
||||||
|
function defined(value, defaultValue) {
|
||||||
|
return value !== undefined ? value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function jDataView(buffer, byteOffset, byteLength, littleEndian) {
|
||||||
|
/* jshint validthis:true */
|
||||||
|
|
||||||
|
if (buffer instanceof jDataView) {
|
||||||
|
var result = buffer.slice(byteOffset, byteOffset + byteLength);
|
||||||
|
result._littleEndian = defined(littleEndian, result._littleEndian);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(this instanceof jDataView)) {
|
||||||
|
return new jDataView(buffer, byteOffset, byteLength, littleEndian);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buffer = buffer = jDataView.wrapBuffer(buffer);
|
||||||
|
|
||||||
|
// Check parameters and existing functionnalities
|
||||||
|
this._isArrayBuffer =
|
||||||
|
compatibility.ArrayBuffer && buffer instanceof ArrayBuffer;
|
||||||
|
this._isPixelData =
|
||||||
|
compatibility.PixelData && buffer instanceof CanvasPixelArray;
|
||||||
|
this._isDataView = compatibility.DataView && this._isArrayBuffer;
|
||||||
|
this._isNodeBuffer = compatibility.NodeBuffer && buffer instanceof Buffer;
|
||||||
|
|
||||||
|
// Handle Type Errors
|
||||||
|
if (
|
||||||
|
!this._isNodeBuffer &&
|
||||||
|
!this._isArrayBuffer &&
|
||||||
|
!this._isPixelData &&
|
||||||
|
!(buffer instanceof Array)
|
||||||
|
) {
|
||||||
|
throw new TypeError("jDataView buffer has an incompatible type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Values
|
||||||
|
this._littleEndian = !!littleEndian;
|
||||||
|
|
||||||
|
var bufferLength = "byteLength" in buffer ? buffer.byteLength : buffer.length;
|
||||||
|
this.byteOffset = byteOffset = defined(byteOffset, 0);
|
||||||
|
this.byteLength = byteLength = defined(byteLength, bufferLength - byteOffset);
|
||||||
|
|
||||||
|
if (!this._isDataView) {
|
||||||
|
this._checkBounds(byteOffset, byteLength, bufferLength);
|
||||||
|
} else {
|
||||||
|
this._view = new DataView(buffer, byteOffset, byteLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create uniform methods (action wrappers) for the following data types
|
||||||
|
|
||||||
|
this._engineAction = this._isDataView
|
||||||
|
? this._dataViewAction
|
||||||
|
: this._isNodeBuffer
|
||||||
|
? this._nodeBufferAction
|
||||||
|
: this._isArrayBuffer
|
||||||
|
? this._arrayBufferAction
|
||||||
|
: this._arrayAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCharCodes(string) {
|
||||||
|
if (compatibility.NodeBuffer) {
|
||||||
|
return new Buffer(string, "binary");
|
||||||
|
}
|
||||||
|
|
||||||
|
var Type = compatibility.ArrayBuffer ? Uint8Array : Array,
|
||||||
|
codes = new Type(string.length);
|
||||||
|
|
||||||
|
for (var i = 0, length = string.length; i < length; i++) {
|
||||||
|
codes[i] = string.charCodeAt(i) & 0xff;
|
||||||
|
}
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mostly internal function for wrapping any supported input (String or Array-like) to best suitable buffer format
|
||||||
|
jDataView.wrapBuffer = function (buffer) {
|
||||||
|
switch (typeof buffer) {
|
||||||
|
case "number":
|
||||||
|
if (compatibility.NodeBuffer) {
|
||||||
|
buffer = new Buffer(buffer);
|
||||||
|
buffer.fill(0);
|
||||||
|
} else if (compatibility.ArrayBuffer) {
|
||||||
|
buffer = new Uint8Array(buffer).buffer;
|
||||||
|
} else if (compatibility.PixelData) {
|
||||||
|
buffer = createPixelData(buffer);
|
||||||
|
} else {
|
||||||
|
buffer = new Array(buffer);
|
||||||
|
for (var i = 0; i < buffer.length; i++) {
|
||||||
|
buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
buffer = getCharCodes(buffer);
|
||||||
|
/* falls through */
|
||||||
|
default:
|
||||||
|
if (
|
||||||
|
"length" in buffer &&
|
||||||
|
!(
|
||||||
|
(compatibility.NodeBuffer && buffer instanceof Buffer) ||
|
||||||
|
(compatibility.ArrayBuffer && buffer instanceof ArrayBuffer) ||
|
||||||
|
(compatibility.PixelData && buffer instanceof CanvasPixelArray)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (compatibility.NodeBuffer) {
|
||||||
|
buffer = new Buffer(buffer);
|
||||||
|
} else if (compatibility.ArrayBuffer) {
|
||||||
|
if (!(buffer instanceof ArrayBuffer)) {
|
||||||
|
buffer = new Uint8Array(buffer).buffer;
|
||||||
|
// bug in Node.js <= 0.8:
|
||||||
|
if (!(buffer instanceof ArrayBuffer)) {
|
||||||
|
buffer = new Uint8Array(arrayFrom(buffer, true)).buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (compatibility.PixelData) {
|
||||||
|
buffer = createPixelData(buffer.length, buffer);
|
||||||
|
} else {
|
||||||
|
buffer = arrayFrom(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function pow2(n) {
|
||||||
|
return n >= 0 && n < 31 ? 1 << n : pow2[n] || (pow2[n] = Math.pow(2, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
// left for backward compatibility
|
||||||
|
jDataView.createBuffer = function () {
|
||||||
|
return jDataView.wrapBuffer(arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Uint64(lo, hi) {
|
||||||
|
this.lo = lo;
|
||||||
|
this.hi = hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
jDataView.Uint64 = Uint64;
|
||||||
|
|
||||||
|
Uint64.prototype = {
|
||||||
|
valueOf: function () {
|
||||||
|
return this.lo + pow2(32) * this.hi;
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function () {
|
||||||
|
return Number.prototype.toString.apply(this.valueOf(), arguments);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Uint64.fromNumber = function (number) {
|
||||||
|
var hi = Math.floor(number / pow2(32)),
|
||||||
|
lo = number - hi * pow2(32);
|
||||||
|
|
||||||
|
return new Uint64(lo, hi);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Int64(lo, hi) {
|
||||||
|
Uint64.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
jDataView.Int64 = Int64;
|
||||||
|
|
||||||
|
Int64.prototype =
|
||||||
|
"create" in Object ? Object.create(Uint64.prototype) : new Uint64();
|
||||||
|
|
||||||
|
Int64.prototype.valueOf = function () {
|
||||||
|
if (this.hi < pow2(31)) {
|
||||||
|
return Uint64.prototype.valueOf.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return -(pow2(32) - this.lo + pow2(32) * (pow2(32) - 1 - this.hi));
|
||||||
|
};
|
||||||
|
|
||||||
|
Int64.fromNumber = function (number) {
|
||||||
|
var lo, hi;
|
||||||
|
if (number >= 0) {
|
||||||
|
var unsigned = Uint64.fromNumber(number);
|
||||||
|
lo = unsigned.lo;
|
||||||
|
hi = unsigned.hi;
|
||||||
|
} else {
|
||||||
|
hi = Math.floor(number / pow2(32));
|
||||||
|
lo = number - hi * pow2(32);
|
||||||
|
hi += pow2(32);
|
||||||
|
}
|
||||||
|
return new Int64(lo, hi);
|
||||||
|
};
|
||||||
|
|
||||||
|
jDataView.prototype = {
|
||||||
|
_offset: 0,
|
||||||
|
_bitOffset: 0,
|
||||||
|
|
||||||
|
compatibility: compatibility,
|
||||||
|
|
||||||
|
_checkBounds: function (byteOffset, byteLength, maxLength) {
|
||||||
|
// Do additional checks to simulate DataView
|
||||||
|
if (typeof byteOffset !== "number") {
|
||||||
|
throw new TypeError("Offset is not a number.");
|
||||||
|
}
|
||||||
|
if (typeof byteLength !== "number") {
|
||||||
|
throw new TypeError("Size is not a number.");
|
||||||
|
}
|
||||||
|
if (byteLength < 0) {
|
||||||
|
throw new RangeError("Length is negative.");
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
byteOffset < 0 ||
|
||||||
|
byteOffset + byteLength > defined(maxLength, this.byteLength)
|
||||||
|
) {
|
||||||
|
throw new RangeError("Offsets are out of bounds.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_action: function (type, isReadAction, byteOffset, littleEndian, value) {
|
||||||
|
return this._engineAction(
|
||||||
|
type,
|
||||||
|
isReadAction,
|
||||||
|
defined(byteOffset, this._offset),
|
||||||
|
defined(littleEndian, this._littleEndian),
|
||||||
|
value
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_dataViewAction: function (
|
||||||
|
type,
|
||||||
|
isReadAction,
|
||||||
|
byteOffset,
|
||||||
|
littleEndian,
|
||||||
|
value
|
||||||
|
) {
|
||||||
|
// Move the internal offset forward
|
||||||
|
this._offset = byteOffset + dataTypes[type];
|
||||||
|
return isReadAction
|
||||||
|
? this._view["get" + type](byteOffset, littleEndian)
|
||||||
|
: this._view["set" + type](byteOffset, value, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_nodeBufferAction: function (
|
||||||
|
type,
|
||||||
|
isReadAction,
|
||||||
|
byteOffset,
|
||||||
|
littleEndian,
|
||||||
|
value
|
||||||
|
) {
|
||||||
|
// Move the internal offset forward
|
||||||
|
this._offset = byteOffset + dataTypes[type];
|
||||||
|
var nodeName =
|
||||||
|
nodeNaming[type] +
|
||||||
|
(type === "Int8" || type === "Uint8" ? "" : littleEndian ? "LE" : "BE");
|
||||||
|
byteOffset += this.byteOffset;
|
||||||
|
return isReadAction
|
||||||
|
? this.buffer["read" + nodeName](byteOffset)
|
||||||
|
: this.buffer["write" + nodeName](value, byteOffset);
|
||||||
|
},
|
||||||
|
|
||||||
|
_arrayBufferAction: function (
|
||||||
|
type,
|
||||||
|
isReadAction,
|
||||||
|
byteOffset,
|
||||||
|
littleEndian,
|
||||||
|
value
|
||||||
|
) {
|
||||||
|
var size = dataTypes[type],
|
||||||
|
TypedArray = globalThis[type + "Array"],
|
||||||
|
typedArray;
|
||||||
|
|
||||||
|
littleEndian = defined(littleEndian, this._littleEndian);
|
||||||
|
|
||||||
|
// ArrayBuffer: we use a typed array of size 1 from original buffer if alignment is good and from slice when it's not
|
||||||
|
if (
|
||||||
|
size === 1 ||
|
||||||
|
((this.byteOffset + byteOffset) % size === 0 && littleEndian)
|
||||||
|
) {
|
||||||
|
typedArray = new TypedArray(this.buffer, this.byteOffset + byteOffset, 1);
|
||||||
|
this._offset = byteOffset + size;
|
||||||
|
return isReadAction ? typedArray[0] : (typedArray[0] = value);
|
||||||
|
} else {
|
||||||
|
var bytes = new Uint8Array(
|
||||||
|
isReadAction
|
||||||
|
? this.getBytes(size, byteOffset, littleEndian, true)
|
||||||
|
: size
|
||||||
|
);
|
||||||
|
typedArray = new TypedArray(bytes.buffer, 0, 1);
|
||||||
|
|
||||||
|
if (isReadAction) {
|
||||||
|
return typedArray[0];
|
||||||
|
} else {
|
||||||
|
typedArray[0] = value;
|
||||||
|
this._setBytes(byteOffset, bytes, littleEndian);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_arrayAction: function (type, isReadAction, byteOffset, littleEndian, value) {
|
||||||
|
return isReadAction
|
||||||
|
? this["_get" + type](byteOffset, littleEndian)
|
||||||
|
: this["_set" + type](byteOffset, value, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
_getBytes: function (length, byteOffset, littleEndian) {
|
||||||
|
littleEndian = defined(littleEndian, this._littleEndian);
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
length = defined(length, this.byteLength - byteOffset);
|
||||||
|
|
||||||
|
this._checkBounds(byteOffset, length);
|
||||||
|
|
||||||
|
byteOffset += this.byteOffset;
|
||||||
|
|
||||||
|
this._offset = byteOffset - this.byteOffset + length;
|
||||||
|
|
||||||
|
var result = this._isArrayBuffer
|
||||||
|
? new Uint8Array(this.buffer, byteOffset, length)
|
||||||
|
: (this.buffer.slice || Array.prototype.slice).call(
|
||||||
|
this.buffer,
|
||||||
|
byteOffset,
|
||||||
|
byteOffset + length
|
||||||
|
);
|
||||||
|
|
||||||
|
return littleEndian || length <= 1 ? result : arrayFrom(result).reverse();
|
||||||
|
},
|
||||||
|
|
||||||
|
// wrapper for external calls (do not return inner buffer directly to prevent it's modifying)
|
||||||
|
getBytes: function (length, byteOffset, littleEndian, toArray) {
|
||||||
|
var result = this._getBytes(
|
||||||
|
length,
|
||||||
|
byteOffset,
|
||||||
|
defined(littleEndian, true)
|
||||||
|
);
|
||||||
|
return toArray ? arrayFrom(result) : result;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setBytes: function (byteOffset, bytes, littleEndian) {
|
||||||
|
var length = bytes.length;
|
||||||
|
|
||||||
|
// needed for Opera
|
||||||
|
if (length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
littleEndian = defined(littleEndian, this._littleEndian);
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
|
||||||
|
this._checkBounds(byteOffset, length);
|
||||||
|
|
||||||
|
if (!littleEndian && length > 1) {
|
||||||
|
bytes = arrayFrom(bytes, true).reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
byteOffset += this.byteOffset;
|
||||||
|
|
||||||
|
if (this._isArrayBuffer) {
|
||||||
|
new Uint8Array(this.buffer, byteOffset, length).set(bytes);
|
||||||
|
} else {
|
||||||
|
if (this._isNodeBuffer) {
|
||||||
|
new Buffer(bytes).copy(this.buffer, byteOffset);
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
this.buffer[byteOffset + i] = bytes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._offset = byteOffset - this.byteOffset + length;
|
||||||
|
},
|
||||||
|
|
||||||
|
setBytes: function (byteOffset, bytes, littleEndian) {
|
||||||
|
this._setBytes(byteOffset, bytes, defined(littleEndian, true));
|
||||||
|
},
|
||||||
|
|
||||||
|
getString: function (byteLength, byteOffset, encoding) {
|
||||||
|
if (this._isNodeBuffer) {
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
byteLength = defined(byteLength, this.byteLength - byteOffset);
|
||||||
|
|
||||||
|
this._checkBounds(byteOffset, byteLength);
|
||||||
|
|
||||||
|
this._offset = byteOffset + byteLength;
|
||||||
|
return this.buffer.toString(
|
||||||
|
encoding || "binary",
|
||||||
|
this.byteOffset + byteOffset,
|
||||||
|
this.byteOffset + this._offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var bytes = this._getBytes(byteLength, byteOffset, true),
|
||||||
|
string = "";
|
||||||
|
byteLength = bytes.length;
|
||||||
|
for (var i = 0; i < byteLength; i++) {
|
||||||
|
string += String.fromCharCode(bytes[i]);
|
||||||
|
}
|
||||||
|
if (encoding === "utf8") {
|
||||||
|
string = decodeURIComponent(escape(string));
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
},
|
||||||
|
|
||||||
|
setString: function (byteOffset, subString, encoding) {
|
||||||
|
if (this._isNodeBuffer) {
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
this._checkBounds(byteOffset, subString.length);
|
||||||
|
this._offset =
|
||||||
|
byteOffset +
|
||||||
|
this.buffer.write(
|
||||||
|
subString,
|
||||||
|
this.byteOffset + byteOffset,
|
||||||
|
encoding || "binary"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (encoding === "utf8") {
|
||||||
|
subString = unescape(encodeURIComponent(subString));
|
||||||
|
}
|
||||||
|
this._setBytes(byteOffset, getCharCodes(subString), true);
|
||||||
|
},
|
||||||
|
|
||||||
|
getChar: function (byteOffset) {
|
||||||
|
return this.getString(1, byteOffset);
|
||||||
|
},
|
||||||
|
|
||||||
|
setChar: function (byteOffset, character) {
|
||||||
|
this.setString(byteOffset, character);
|
||||||
|
},
|
||||||
|
|
||||||
|
tell: function () {
|
||||||
|
return this._offset;
|
||||||
|
},
|
||||||
|
|
||||||
|
seek: function (byteOffset) {
|
||||||
|
this._checkBounds(byteOffset, 0);
|
||||||
|
/* jshint boss: true */
|
||||||
|
return (this._offset = byteOffset);
|
||||||
|
},
|
||||||
|
|
||||||
|
skip: function (byteLength) {
|
||||||
|
return this.seek(this._offset + byteLength);
|
||||||
|
},
|
||||||
|
|
||||||
|
slice: function (start, end, forceCopy) {
|
||||||
|
function normalizeOffset(offset, byteLength) {
|
||||||
|
return offset < 0 ? offset + byteLength : offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = normalizeOffset(start, this.byteLength);
|
||||||
|
end = normalizeOffset(defined(end, this.byteLength), this.byteLength);
|
||||||
|
|
||||||
|
return forceCopy
|
||||||
|
? new jDataView(
|
||||||
|
this.getBytes(end - start, start, true, true),
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
this._littleEndian
|
||||||
|
)
|
||||||
|
: new jDataView(
|
||||||
|
this.buffer,
|
||||||
|
this.byteOffset + start,
|
||||||
|
end - start,
|
||||||
|
this._littleEndian
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
alignBy: function (byteCount) {
|
||||||
|
this._bitOffset = 0;
|
||||||
|
if (defined(byteCount, 1) !== 1) {
|
||||||
|
return this.skip(byteCount - (this._offset % byteCount || byteCount));
|
||||||
|
} else {
|
||||||
|
return this._offset;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Compatibility functions
|
||||||
|
|
||||||
|
_getFloat64: function (byteOffset, littleEndian) {
|
||||||
|
var b = this._getBytes(8, byteOffset, littleEndian),
|
||||||
|
sign = 1 - 2 * (b[7] >> 7),
|
||||||
|
exponent = ((((b[7] << 1) & 0xff) << 3) | (b[6] >> 4)) - ((1 << 10) - 1),
|
||||||
|
// Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead
|
||||||
|
mantissa =
|
||||||
|
(b[6] & 0x0f) * pow2(48) +
|
||||||
|
b[5] * pow2(40) +
|
||||||
|
b[4] * pow2(32) +
|
||||||
|
b[3] * pow2(24) +
|
||||||
|
b[2] * pow2(16) +
|
||||||
|
b[1] * pow2(8) +
|
||||||
|
b[0];
|
||||||
|
|
||||||
|
if (exponent === 1024) {
|
||||||
|
if (mantissa !== 0) {
|
||||||
|
return NaN;
|
||||||
|
} else {
|
||||||
|
return sign * Infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent === -1023) {
|
||||||
|
// Denormalized
|
||||||
|
return sign * mantissa * pow2(-1022 - 52);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign * (1 + mantissa * pow2(-52)) * pow2(exponent);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getFloat32: function (byteOffset, littleEndian) {
|
||||||
|
var b = this._getBytes(4, byteOffset, littleEndian),
|
||||||
|
sign = 1 - 2 * (b[3] >> 7),
|
||||||
|
exponent = (((b[3] << 1) & 0xff) | (b[2] >> 7)) - 127,
|
||||||
|
mantissa = ((b[2] & 0x7f) << 16) | (b[1] << 8) | b[0];
|
||||||
|
|
||||||
|
if (exponent === 128) {
|
||||||
|
if (mantissa !== 0) {
|
||||||
|
return NaN;
|
||||||
|
} else {
|
||||||
|
return sign * Infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent === -127) {
|
||||||
|
// Denormalized
|
||||||
|
return sign * mantissa * pow2(-126 - 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign * (1 + mantissa * pow2(-23)) * pow2(exponent);
|
||||||
|
},
|
||||||
|
|
||||||
|
_get64: function (Type, byteOffset, littleEndian) {
|
||||||
|
littleEndian = defined(littleEndian, this._littleEndian);
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
|
||||||
|
var parts = littleEndian ? [0, 4] : [4, 0];
|
||||||
|
|
||||||
|
for (var i = 0; i < 2; i++) {
|
||||||
|
parts[i] = this.getUint32(byteOffset + parts[i], littleEndian);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._offset = byteOffset + 8;
|
||||||
|
|
||||||
|
return new Type(parts[0], parts[1]);
|
||||||
|
},
|
||||||
|
|
||||||
|
getInt64: function (byteOffset, littleEndian) {
|
||||||
|
return this._get64(Int64, byteOffset, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
getUint64: function (byteOffset, littleEndian) {
|
||||||
|
return this._get64(Uint64, byteOffset, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getInt32: function (byteOffset, littleEndian) {
|
||||||
|
var b = this._getBytes(4, byteOffset, littleEndian);
|
||||||
|
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
_getUint32: function (byteOffset, littleEndian) {
|
||||||
|
return this._getInt32(byteOffset, littleEndian) >>> 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getInt16: function (byteOffset, littleEndian) {
|
||||||
|
return (this._getUint16(byteOffset, littleEndian) << 16) >> 16;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getUint16: function (byteOffset, littleEndian) {
|
||||||
|
var b = this._getBytes(2, byteOffset, littleEndian);
|
||||||
|
return (b[1] << 8) | b[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
_getInt8: function (byteOffset) {
|
||||||
|
return (this._getUint8(byteOffset) << 24) >> 24;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getUint8: function (byteOffset) {
|
||||||
|
return this._getBytes(1, byteOffset)[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
_getBitRangeData: function (bitLength, byteOffset) {
|
||||||
|
var startBit = (defined(byteOffset, this._offset) << 3) + this._bitOffset,
|
||||||
|
endBit = startBit + bitLength,
|
||||||
|
start = startBit >>> 3,
|
||||||
|
end = (endBit + 7) >>> 3,
|
||||||
|
b = this._getBytes(end - start, start, true),
|
||||||
|
wideValue = 0;
|
||||||
|
|
||||||
|
/* jshint boss: true */
|
||||||
|
if ((this._bitOffset = endBit & 7)) {
|
||||||
|
this._bitOffset -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0, length = b.length; i < length; i++) {
|
||||||
|
wideValue = (wideValue << 8) | b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: start,
|
||||||
|
bytes: b,
|
||||||
|
wideValue: wideValue,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getSigned: function (bitLength, byteOffset) {
|
||||||
|
var shift = 32 - bitLength;
|
||||||
|
return (this.getUnsigned(bitLength, byteOffset) << shift) >> shift;
|
||||||
|
},
|
||||||
|
|
||||||
|
getUnsigned: function (bitLength, byteOffset) {
|
||||||
|
var value =
|
||||||
|
this._getBitRangeData(bitLength, byteOffset).wideValue >>>
|
||||||
|
-this._bitOffset;
|
||||||
|
return bitLength < 32 ? value & ~(-1 << bitLength) : value;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setBinaryFloat: function (
|
||||||
|
byteOffset,
|
||||||
|
value,
|
||||||
|
mantSize,
|
||||||
|
expSize,
|
||||||
|
littleEndian
|
||||||
|
) {
|
||||||
|
var signBit = value < 0 ? 1 : 0,
|
||||||
|
exponent,
|
||||||
|
mantissa,
|
||||||
|
eMax = ~(-1 << (expSize - 1)),
|
||||||
|
eMin = 1 - eMax;
|
||||||
|
|
||||||
|
if (value < 0) {
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === 0) {
|
||||||
|
exponent = 0;
|
||||||
|
mantissa = 0;
|
||||||
|
} else if (isNaN(value)) {
|
||||||
|
exponent = 2 * eMax + 1;
|
||||||
|
mantissa = 1;
|
||||||
|
} else if (value === Infinity) {
|
||||||
|
exponent = 2 * eMax + 1;
|
||||||
|
mantissa = 0;
|
||||||
|
} else {
|
||||||
|
exponent = Math.floor(Math.log(value) / Math.LN2);
|
||||||
|
if (exponent >= eMin && exponent <= eMax) {
|
||||||
|
mantissa = Math.floor((value * pow2(-exponent) - 1) * pow2(mantSize));
|
||||||
|
exponent += eMax;
|
||||||
|
} else {
|
||||||
|
mantissa = Math.floor(value / pow2(eMin - mantSize));
|
||||||
|
exponent = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = [];
|
||||||
|
while (mantSize >= 8) {
|
||||||
|
b.push(mantissa % 256);
|
||||||
|
mantissa = Math.floor(mantissa / 256);
|
||||||
|
mantSize -= 8;
|
||||||
|
}
|
||||||
|
exponent = (exponent << mantSize) | mantissa;
|
||||||
|
expSize += mantSize;
|
||||||
|
while (expSize >= 8) {
|
||||||
|
b.push(exponent & 0xff);
|
||||||
|
exponent >>>= 8;
|
||||||
|
expSize -= 8;
|
||||||
|
}
|
||||||
|
b.push((signBit << expSize) | exponent);
|
||||||
|
|
||||||
|
this._setBytes(byteOffset, b, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setFloat32: function (byteOffset, value, littleEndian) {
|
||||||
|
this._setBinaryFloat(byteOffset, value, 23, 8, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setFloat64: function (byteOffset, value, littleEndian) {
|
||||||
|
this._setBinaryFloat(byteOffset, value, 52, 11, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_set64: function (Type, byteOffset, value, littleEndian) {
|
||||||
|
if (!(value instanceof Type)) {
|
||||||
|
value = Type.fromNumber(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
littleEndian = defined(littleEndian, this._littleEndian);
|
||||||
|
byteOffset = defined(byteOffset, this._offset);
|
||||||
|
|
||||||
|
var parts = littleEndian ? { lo: 0, hi: 4 } : { lo: 4, hi: 0 };
|
||||||
|
|
||||||
|
for (var partName in parts) {
|
||||||
|
this.setUint32(
|
||||||
|
byteOffset + parts[partName],
|
||||||
|
value[partName],
|
||||||
|
littleEndian
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._offset = byteOffset + 8;
|
||||||
|
},
|
||||||
|
|
||||||
|
setInt64: function (byteOffset, value, littleEndian) {
|
||||||
|
this._set64(Int64, byteOffset, value, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
setUint64: function (byteOffset, value, littleEndian) {
|
||||||
|
this._set64(Uint64, byteOffset, value, littleEndian);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setUint32: function (byteOffset, value, littleEndian) {
|
||||||
|
this._setBytes(
|
||||||
|
byteOffset,
|
||||||
|
[value & 0xff, (value >>> 8) & 0xff, (value >>> 16) & 0xff, value >>> 24],
|
||||||
|
littleEndian
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setUint16: function (byteOffset, value, littleEndian) {
|
||||||
|
this._setBytes(
|
||||||
|
byteOffset,
|
||||||
|
[value & 0xff, (value >>> 8) & 0xff],
|
||||||
|
littleEndian
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setUint8: function (byteOffset, value) {
|
||||||
|
this._setBytes(byteOffset, [value & 0xff]);
|
||||||
|
},
|
||||||
|
|
||||||
|
setUnsigned: function (byteOffset, value, bitLength) {
|
||||||
|
var data = this._getBitRangeData(bitLength, byteOffset),
|
||||||
|
wideValue = data.wideValue,
|
||||||
|
b = data.bytes;
|
||||||
|
|
||||||
|
wideValue &= ~(~(-1 << bitLength) << -this._bitOffset); // clearing bit range before binary "or"
|
||||||
|
wideValue |=
|
||||||
|
(bitLength < 32 ? value & ~(-1 << bitLength) : value) << -this._bitOffset; // setting bits
|
||||||
|
|
||||||
|
for (var i = b.length - 1; i >= 0; i--) {
|
||||||
|
b[i] = wideValue & 0xff;
|
||||||
|
wideValue >>>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setBytes(data.start, b, true);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var proto = jDataView.prototype;
|
||||||
|
|
||||||
|
for (var type in dataTypes) {
|
||||||
|
(function (type) {
|
||||||
|
proto["get" + type] = function (byteOffset, littleEndian) {
|
||||||
|
return this._action(type, true, byteOffset, littleEndian);
|
||||||
|
};
|
||||||
|
proto["set" + type] = function (byteOffset, value, littleEndian) {
|
||||||
|
this._action(type, false, byteOffset, littleEndian, value);
|
||||||
|
};
|
||||||
|
})(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
proto._setInt32 = proto._setUint32;
|
||||||
|
proto._setInt16 = proto._setUint16;
|
||||||
|
proto._setInt8 = proto._setUint8;
|
||||||
|
proto.setSigned = proto.setUnsigned;
|
||||||
|
|
||||||
|
for (var method in proto) {
|
||||||
|
if (method.slice(0, 3) === "set") {
|
||||||
|
(function (type) {
|
||||||
|
proto["write" + type] = function () {
|
||||||
|
Array.prototype.unshift.call(arguments, undefined);
|
||||||
|
this["set" + type].apply(this, arguments);
|
||||||
|
};
|
||||||
|
})(method.slice(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof module !== "undefined" && typeof module.exports === "object") {
|
||||||
|
module.exports = jDataView;
|
||||||
|
} else if (typeof define === "function" && define.amd) {
|
||||||
|
define([], function () {
|
||||||
|
return jDataView;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var oldGlobalThis = globalThis.jDataView;
|
||||||
|
(globalThis.jDataView = jDataView).noConflict = function () {
|
||||||
|
globalThis.jDataView = oldGlobalThis;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}
|
64
src/lib/main.js
Normal file
64
src/lib/main.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import { jDataView } from "./jdataview";
|
||||||
|
import { pesRead } from "./pesformat";
|
||||||
|
import { Pattern } from "./pattern";
|
||||||
|
|
||||||
|
String.prototype.endsWith = function (suffix) {
|
||||||
|
return this.indexOf(suffix, this.length - suffix.length) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
function displayFileText(filename, evt, canvas) {
|
||||||
|
const view = jDataView(evt.target.result, 0, evt.size);
|
||||||
|
const pattern = new Pattern();
|
||||||
|
filename = filename.toLowerCase();
|
||||||
|
if (filename.endsWith("pes")) {
|
||||||
|
pesRead(view, pattern);
|
||||||
|
}
|
||||||
|
pattern.moveToPositive();
|
||||||
|
pattern.drawShape(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileReadAbort(evt) {
|
||||||
|
alert("File read aborted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileReadError(evt) {
|
||||||
|
let message;
|
||||||
|
switch (evt.target.error.name) {
|
||||||
|
case "NotFoundError":
|
||||||
|
alert("The file could not be found at the time the read was processed.");
|
||||||
|
break;
|
||||||
|
case "SecurityError":
|
||||||
|
message = "<p>A file security error occured. This can be due to:</p>";
|
||||||
|
message +=
|
||||||
|
"<ul><li>Accessing certain files deemed unsafe for Web applications.</li>";
|
||||||
|
message += "<li>Performing too many read calls on file resources.</li>";
|
||||||
|
message +=
|
||||||
|
"<li>The file has changed on disk since the user selected it.</li></ul>";
|
||||||
|
alert(message);
|
||||||
|
break;
|
||||||
|
case "NotReadableError":
|
||||||
|
alert(
|
||||||
|
"The file cannot be read. This can occur if the file is open in another application."
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "EncodingError":
|
||||||
|
alert("The length of the data URL for the file is too long.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alert("File error code " + evt.target.error.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startFileRead(fileObject, canvas) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onloadend = function (x) {
|
||||||
|
displayFileText.apply(null, [fileObject.name, x, canvas]);
|
||||||
|
};
|
||||||
|
reader.abort = handleFileReadAbort;
|
||||||
|
reader.onerror = handleFileReadError;
|
||||||
|
|
||||||
|
if (fileObject) {
|
||||||
|
reader.readAsArrayBuffer(fileObject);
|
||||||
|
}
|
||||||
|
}
|
177
src/lib/pattern.js
Normal file
177
src/lib/pattern.js
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
function Stitch(x, y, flags, color) {
|
||||||
|
this.flags = flags;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Color(r, g, b, description) {
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stitchTypes = {
|
||||||
|
normal: 0,
|
||||||
|
jump: 1,
|
||||||
|
trim: 2,
|
||||||
|
stop: 4,
|
||||||
|
end: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
function Pattern() {
|
||||||
|
this.colors = [];
|
||||||
|
this.stitches = [];
|
||||||
|
this.hoop = {};
|
||||||
|
this.lastX = 0;
|
||||||
|
this.lastY = 0;
|
||||||
|
this.top = 0;
|
||||||
|
this.bottom = 0;
|
||||||
|
this.left = 0;
|
||||||
|
this.right = 0;
|
||||||
|
this.currentColorIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern.prototype.addColorRgb = function (r, g, b, description) {
|
||||||
|
this.colors[this.colors.length] = new Color(r, g, b, description);
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.addColor = function (color) {
|
||||||
|
this.colors[this.colors.length] = color;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.addStitchAbs = function (x, y, flags, isAutoColorIndex) {
|
||||||
|
if ((flags & stitchTypes.end) === stitchTypes.end) {
|
||||||
|
this.calculateBoundingBox();
|
||||||
|
this.fixColorCount();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(flags & stitchTypes.stop) === stitchTypes.stop &&
|
||||||
|
this.stitches.length === 0
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((flags & stitchTypes.stop) === stitchTypes.stop && isAutoColorIndex) {
|
||||||
|
this.currentColorIndex += 1;
|
||||||
|
}
|
||||||
|
this.stitches[this.stitches.length] = new Stitch(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
flags,
|
||||||
|
this.currentColorIndex
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.addStitchRel = function (dx, dy, flags, isAutoColorIndex) {
|
||||||
|
if (this.stitches.length !== 0) {
|
||||||
|
let nx = this.lastX + dx,
|
||||||
|
ny = this.lastY + dy;
|
||||||
|
this.lastX = nx;
|
||||||
|
this.lastY = ny;
|
||||||
|
this.addStitchAbs(nx, ny, flags, isAutoColorIndex);
|
||||||
|
} else {
|
||||||
|
this.addStitchAbs(dx, dy, flags, isAutoColorIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.calculateBoundingBox = function () {
|
||||||
|
let i = 0,
|
||||||
|
stitchCount = this.stitches.length,
|
||||||
|
pt;
|
||||||
|
if (stitchCount === 0) {
|
||||||
|
this.bottom = 1;
|
||||||
|
this.right = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.left = 99999;
|
||||||
|
this.top = 99999;
|
||||||
|
this.right = -99999;
|
||||||
|
this.bottom = -99999;
|
||||||
|
|
||||||
|
for (i = 0; i < stitchCount; i += 1) {
|
||||||
|
pt = this.stitches[i];
|
||||||
|
if (!(pt.flags & stitchTypes.trim)) {
|
||||||
|
this.left = this.left < pt.x ? this.left : pt.x;
|
||||||
|
this.top = this.top < pt.y ? this.top : pt.y;
|
||||||
|
this.right = this.right > pt.x ? this.right : pt.x;
|
||||||
|
this.bottom = this.bottom > pt.y ? this.bottom : pt.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.moveToPositive = function () {
|
||||||
|
let i = 0,
|
||||||
|
stitchCount = this.stitches.length;
|
||||||
|
for (i = 0; i < stitchCount; i += 1) {
|
||||||
|
this.stitches[i].x -= this.left;
|
||||||
|
this.stitches[i].y -= this.top;
|
||||||
|
}
|
||||||
|
this.right -= this.left;
|
||||||
|
this.left = 0;
|
||||||
|
this.bottom -= this.top;
|
||||||
|
this.top = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.invertPatternVertical = function () {
|
||||||
|
let i = 0,
|
||||||
|
temp = -this.top,
|
||||||
|
stitchCount = this.stitches.length;
|
||||||
|
for (i = 0; i < stitchCount; i += 1) {
|
||||||
|
this.stitches[i].y = -this.stitches[i].y;
|
||||||
|
}
|
||||||
|
this.top = -this.bottom;
|
||||||
|
this.bottom = temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.addColorRandom = function () {
|
||||||
|
this.colors[this.colors.length] = new Color(
|
||||||
|
Math.round(Math.random() * 256),
|
||||||
|
Math.round(Math.random() * 256),
|
||||||
|
Math.round(Math.random() * 256),
|
||||||
|
"random"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.fixColorCount = function () {
|
||||||
|
let maxColorIndex = 0,
|
||||||
|
stitchCount = this.stitches.length,
|
||||||
|
i;
|
||||||
|
for (i = 0; i < stitchCount; i += 1) {
|
||||||
|
maxColorIndex = Math.max(maxColorIndex, this.stitches[i].color);
|
||||||
|
}
|
||||||
|
while (this.colors.length <= maxColorIndex) {
|
||||||
|
this.addColorRandom();
|
||||||
|
}
|
||||||
|
this.colors.splice(maxColorIndex + 1, this.colors.length - maxColorIndex - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
Pattern.prototype.drawShape = function (canvas) {
|
||||||
|
canvas.width = this.right;
|
||||||
|
canvas.height = this.bottom;
|
||||||
|
if (canvas.getContext) {
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
let color = this.colors[this.stitches[0].color];
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.strokeStyle = "rgb(" + color.r + "," + color.g + "," + color.b + ")";
|
||||||
|
for (let i = 0; i < this.stitches.length; i++) {
|
||||||
|
const currentStitch = this.stitches[i];
|
||||||
|
if (
|
||||||
|
currentStitch.flags === stitchTypes.jump ||
|
||||||
|
currentStitch.flags === stitchTypes.trim ||
|
||||||
|
currentStitch.flags === stitchTypes.stop
|
||||||
|
) {
|
||||||
|
ctx.stroke();
|
||||||
|
color = this.colors[currentStitch.color];
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.strokeStyle =
|
||||||
|
"rgb(" + color.r + "," + color.g + "," + color.b + ")";
|
||||||
|
ctx.moveTo(currentStitch.x, currentStitch.y);
|
||||||
|
}
|
||||||
|
ctx.lineTo(currentStitch.x, currentStitch.y);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Pattern, Color, stitchTypes };
|
140
src/lib/pesformat.js
Normal file
140
src/lib/pesformat.js
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import { Color, stitchTypes } from "./pattern";
|
||||||
|
|
||||||
|
const namedColors = [
|
||||||
|
new Color(0, 0, 0, "Unknown"),
|
||||||
|
new Color(14, 31, 124, "Prussian Blue"),
|
||||||
|
new Color(10, 85, 163, "Blue"),
|
||||||
|
new Color(0, 135, 119, "Teal Green"),
|
||||||
|
new Color(75, 107, 175, "Cornflower Blue"),
|
||||||
|
new Color(237, 23, 31, "Red"),
|
||||||
|
new Color(209, 92, 0, "Reddish Brown"),
|
||||||
|
new Color(145, 54, 151, "Magenta"),
|
||||||
|
new Color(228, 154, 203, "Light Lilac"),
|
||||||
|
new Color(145, 95, 172, "Lilac"),
|
||||||
|
new Color(158, 214, 125, "Mint Green"),
|
||||||
|
new Color(232, 169, 0, "Deep Gold"),
|
||||||
|
new Color(254, 186, 53, "Orange"),
|
||||||
|
new Color(255, 255, 0, "Yellow"),
|
||||||
|
new Color(112, 188, 31, "Lime Green"),
|
||||||
|
new Color(186, 152, 0, "Brass"),
|
||||||
|
new Color(168, 168, 168, "Silver"),
|
||||||
|
new Color(125, 111, 0, "Russet Brown"),
|
||||||
|
new Color(255, 255, 179, "Cream Brown"),
|
||||||
|
new Color(79, 85, 86, "Pewter"),
|
||||||
|
new Color(0, 0, 0, "Black"),
|
||||||
|
new Color(11, 61, 145, "Ultramarine"),
|
||||||
|
new Color(119, 1, 118, "Royal Purple"),
|
||||||
|
new Color(41, 49, 51, "Dark Gray"),
|
||||||
|
new Color(42, 19, 1, "Dark Brown"),
|
||||||
|
new Color(246, 74, 138, "Deep Rose"),
|
||||||
|
new Color(178, 118, 36, "Light Brown"),
|
||||||
|
new Color(252, 187, 197, "Salmon Pink"),
|
||||||
|
new Color(254, 55, 15, "Vermillion"),
|
||||||
|
new Color(240, 240, 240, "White"),
|
||||||
|
new Color(106, 28, 138, "Violet"),
|
||||||
|
new Color(168, 221, 196, "Seacrest"),
|
||||||
|
new Color(37, 132, 187, "Sky Blue"),
|
||||||
|
new Color(254, 179, 67, "Pumpkin"),
|
||||||
|
new Color(255, 243, 107, "Cream Yellow"),
|
||||||
|
new Color(208, 166, 96, "Khaki"),
|
||||||
|
new Color(209, 84, 0, "Clay Brown"),
|
||||||
|
new Color(102, 186, 73, "Leaf Green"),
|
||||||
|
new Color(19, 74, 70, "Peacock Blue"),
|
||||||
|
new Color(135, 135, 135, "Gray"),
|
||||||
|
new Color(216, 204, 198, "Warm Gray"),
|
||||||
|
new Color(67, 86, 7, "Dark Olive"),
|
||||||
|
new Color(253, 217, 222, "Flesh Pink"),
|
||||||
|
new Color(249, 147, 188, "Pink"),
|
||||||
|
new Color(0, 56, 34, "Deep Green"),
|
||||||
|
new Color(178, 175, 212, "Lavender"),
|
||||||
|
new Color(104, 106, 176, "Wisteria Violet"),
|
||||||
|
new Color(239, 227, 185, "Beige"),
|
||||||
|
new Color(247, 56, 102, "Carmine"),
|
||||||
|
new Color(181, 75, 100, "Amber Red"),
|
||||||
|
new Color(19, 43, 26, "Olive Green"),
|
||||||
|
new Color(199, 1, 86, "Dark Fuschia"),
|
||||||
|
new Color(254, 158, 50, "Tangerine"),
|
||||||
|
new Color(168, 222, 235, "Light Blue"),
|
||||||
|
new Color(0, 103, 62, "Emerald Green"),
|
||||||
|
new Color(78, 41, 144, "Purple"),
|
||||||
|
new Color(47, 126, 32, "Moss Green"),
|
||||||
|
new Color(255, 204, 204, "Flesh Pink"),
|
||||||
|
new Color(255, 217, 17, "Harvest Gold"),
|
||||||
|
new Color(9, 91, 166, "Electric Blue"),
|
||||||
|
new Color(240, 249, 112, "Lemon Yellow"),
|
||||||
|
new Color(227, 243, 91, "Fresh Green"),
|
||||||
|
new Color(255, 153, 0, "Orange"),
|
||||||
|
new Color(255, 240, 141, "Cream Yellow"),
|
||||||
|
new Color(255, 200, 200, "Applique"),
|
||||||
|
];
|
||||||
|
|
||||||
|
function readPecStitches(file, pattern) {
|
||||||
|
let stitchNumber = 0,
|
||||||
|
stitchType,
|
||||||
|
val1,
|
||||||
|
val2,
|
||||||
|
byteCount = file.byteLength;
|
||||||
|
while (file.tell() < byteCount) {
|
||||||
|
val1 = file.getUint8();
|
||||||
|
val2 = file.getUint8();
|
||||||
|
|
||||||
|
stitchType = stitchTypes.normal;
|
||||||
|
if (val1 === 0xff && val2 === 0x00) {
|
||||||
|
pattern.addStitchRel(0, 0, stitchTypes.end, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val1 === 0xfe && val2 === 0xb0) {
|
||||||
|
file.getInt8();
|
||||||
|
pattern.addStitchRel(0, 0, stitchTypes.stop, true);
|
||||||
|
stitchNumber += 1;
|
||||||
|
} else {
|
||||||
|
if (val1 & 0x80) {
|
||||||
|
if (val1 & 0x20) {
|
||||||
|
stitchType = stitchTypes.trim;
|
||||||
|
}
|
||||||
|
if (val1 & 0x10) {
|
||||||
|
stitchType = stitchTypes.jump;
|
||||||
|
}
|
||||||
|
val1 = ((val1 & 0x0f) << 8) + val2;
|
||||||
|
if (val1 & 0x800) {
|
||||||
|
val1 -= 0x1000;
|
||||||
|
}
|
||||||
|
val2 = file.getUint8();
|
||||||
|
} else if (val1 >= 0x40) {
|
||||||
|
val1 -= 0x80;
|
||||||
|
}
|
||||||
|
if (val2 & 0x80) {
|
||||||
|
if (val2 & 0x20) {
|
||||||
|
stitchType = stitchTypes.trim;
|
||||||
|
}
|
||||||
|
if (val2 & 0x10) {
|
||||||
|
stitchType = stitchTypes.jump;
|
||||||
|
}
|
||||||
|
val2 = ((val2 & 0x0f) << 8) + file.getUint8();
|
||||||
|
if (val2 & 0x800) {
|
||||||
|
val2 -= 0x1000;
|
||||||
|
}
|
||||||
|
} else if (val2 > 0x3f) {
|
||||||
|
val2 -= 0x80;
|
||||||
|
}
|
||||||
|
pattern.addStitchRel(val1, val2, stitchType, true);
|
||||||
|
stitchNumber += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pesRead(file, pattern) {
|
||||||
|
let x, numColors, pecstart;
|
||||||
|
pecstart = file.getInt32(8, true);
|
||||||
|
file.seek(pecstart + 48);
|
||||||
|
numColors = file.getInt8() + 1;
|
||||||
|
for (x = 0; x < numColors; x += 1) {
|
||||||
|
pattern.addColor(namedColors[file.getInt8()]);
|
||||||
|
}
|
||||||
|
file.seek(pecstart + 532);
|
||||||
|
readPecStitches(file, pattern);
|
||||||
|
pattern.addStitchRel(0, 0, stitchTypes.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pecReadStitches = readPecStitches;
|
||||||
|
export const pecColors = namedColors;
|
8
src/main.js
Normal file
8
src/main.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import './app.css'
|
||||||
|
import App from './App.svelte'
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
target: document.getElementById('app')
|
||||||
|
})
|
||||||
|
|
||||||
|
export default app
|
2
src/vite-env.d.ts
vendored
Normal file
2
src/vite-env.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/// <reference types="svelte" />
|
||||||
|
/// <reference types="vite/client" />
|
7
vite.config.js
Normal file
7
vite.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [svelte()]
|
||||||
|
})
|
Loading…
Reference in a new issue