From 47e764132f97b34b43cb7820497eeccd2ec4d3fa Mon Sep 17 00:00:00 2001 From: Marc Date: Tue, 8 Feb 2022 13:35:49 +0100 Subject: [PATCH] refacto ts + ajout de dessin simple + ajout pinceau WIP lib graphique --- definitions.d.ts | 7 ++ package.json | 1 + rootfs overrides/chibrax/graphics.js | 24 ++++- rootfs overrides/etc/init.d/filesystem.js | 6 ++ rootfs overrides/usr/bin/framebuffer-demo.js | 49 +++++---- rootfs overrides/usr/bin/sheebr.js | 23 +++- rootfs overrides/usr/lib/dickPick.js | 13 +++ rootfs overrides/usr/lib/shapes.js | 101 ++++++++++++++++++ rootfs overrides/usr/lib/sheebr/aliases.js | 4 + .../usr/lib/sheebr/environment.js | 12 ++- rootfs overrides/usr/lib/sheebr/lexer.js | 75 +++++++------ rootfs overrides/usr/lib/sheebr/utils.js | 4 + .../chibrax/tsconfig.json => tsconfig.json | 2 +- 13 files changed, 255 insertions(+), 66 deletions(-) create mode 100644 definitions.d.ts create mode 100644 rootfs overrides/usr/lib/dickPick.js create mode 100644 rootfs overrides/usr/lib/shapes.js rename rootfs overrides/chibrax/tsconfig.json => tsconfig.json (84%) diff --git a/definitions.d.ts b/definitions.d.ts new file mode 100644 index 0000000..690cc66 --- /dev/null +++ b/definitions.d.ts @@ -0,0 +1,7 @@ +import { Bitmap } from '@jimp/core' + +declare global { + interface Pencil extends Bitmap { + color: number[], + } +} \ No newline at end of file diff --git a/package.json b/package.json index 2ed4678..416de9c 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "@types/jimp": "^0.2.28", "@types/node": "^17.0.14", "node-gyp": "^8.4.1" } diff --git a/rootfs overrides/chibrax/graphics.js b/rootfs overrides/chibrax/graphics.js index 2b15cbf..26a5b80 100644 --- a/rootfs overrides/chibrax/graphics.js +++ b/rootfs overrides/chibrax/graphics.js @@ -58,9 +58,9 @@ async function readImgFile(filepath) { /** * @param { number } x * @param { number } y - * @param { import('@jimp/core').Bitmap } bitmap + * @param { import('@jimp/core').Bitmap | Pencil } bitmap */ -function drawBitmap(x, y, bitmap) { +function drawBitmap(x, y, bitmap, handleTransparency = true) { for(let dy = 0; dy < bitmap.height; dy++) { let bitmapLineEnd = bitmap.width * screen.byteDepth * (dy + 1) let bitmapLineStart = bitmap.width * screen.byteDepth * dy @@ -94,7 +94,25 @@ function drawBitmap(x, y, bitmap) { const line = bitmap.data.subarray(bitmapLineStart, bitmapLineEnd) - buffer.set(Array.from(line), dx * screen.byteDepth + screen.width * (dy + y) * screen.byteDepth) + + const bufferPlacement = dx * screen.byteDepth + screen.width * (dy + y) * screen.byteDepth + + if(handleTransparency) { + const currentLine = buffer.subarray(bufferPlacement, bufferPlacement + line.length) + for(let i=0; i < line.length; i += 4) { + const transparency = line.readUInt8(i+3) / 255 + if(transparency < 1) { + /** @type { Uint8Array } */ + const newLine = new Uint8Array(3) + for(let j=0; j < 3; j++) { + newLine[j] = (currentLine.readUInt8(j+i)*1-transparency + line.readUInt8(j+i)*transparency) + } + line.set(newLine, i) + } + } + } + + buffer.set(Array.from(line), bufferPlacement) } } diff --git a/rootfs overrides/etc/init.d/filesystem.js b/rootfs overrides/etc/init.d/filesystem.js index 409b7a5..92a8fe8 100644 --- a/rootfs overrides/etc/init.d/filesystem.js +++ b/rootfs overrides/etc/init.d/filesystem.js @@ -10,7 +10,13 @@ async function init() { mount("dummy", "/tmp", "tmpfs", flags.MS_NODEV, "") } +/** + * @type { string[] } + */ const after = [] // list of init script to load before +/** + * @type { string[] } + */ const before = [] module.exports = { diff --git a/rootfs overrides/usr/bin/framebuffer-demo.js b/rootfs overrides/usr/bin/framebuffer-demo.js index 3535029..3e60be1 100644 --- a/rootfs overrides/usr/bin/framebuffer-demo.js +++ b/rootfs overrides/usr/bin/framebuffer-demo.js @@ -1,27 +1,36 @@ //@ts-check const graphics = require('../../chibrax/graphics') +const shapes = require('../lib/shapes') +const path = require('path') graphics.clear() drawChibrax() +const bitmap = shapes.createBitmap(400, 400) +const pencil = shapes.pencilFromBitmap(bitmap, [0,255, 0,255]) +shapes.drawCircle(pencil, 200, 200, 190) +graphics.drawBitmap(0, 0, pencil) + + graphics.flip() + function drawChibrax() { //LA LETTRE C for(let i = 0; i < 100; i++) { for(let j = 0; j < 10; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 0; i < 20; i++) { for(let j = 10; j < 110; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 0; i < 100; i++) { for(let j = 110; j < 120; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } @@ -29,106 +38,106 @@ function drawChibrax() { //LA LETTRE H for(let i = 110; i < 130; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 110; i < 210; i++) { for(let j = 50; j < 60; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 210; i < 230; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } //LA LETTRE I for(let i = 240; i < 260; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } //LA LETTRE B for(let i = 270; i < 280; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 380; i < 390; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 270; i < 390; i++) { for(let j = 0; j < 10; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 270; i < 390; i++) { for(let j = 50; j < 60; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 270; i < 390; i++) { for(let j = 90; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } //LA LETTRE R for(let i = 400; i < 410; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 510; i < 520; i++) { for(let j = 0; j < 100; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 400; i < 520; i++) { for(let j = 0; j < 10; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 400; i < 520; i++) { for(let j = 50; j < 60; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } //LA LETTRE E for(let i = 530; i < 630; i++) { for(let j = 0; j < 10; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 530; i < 550; i++) { for(let j = 10; j < 110; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 530; i < 630; i++) { for(let j = 50; j < 60; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } for(let i = 530; i < 630; i++) { for(let j = 110; j < 120; j++) { - graphics.setPixel(i,j, [0,0,255,0]) + graphics.setPixel(i,j, [0,0,255, 255]) } } diff --git a/rootfs overrides/usr/bin/sheebr.js b/rootfs overrides/usr/bin/sheebr.js index 5a712ee..ca2883f 100644 --- a/rootfs overrides/usr/bin/sheebr.js +++ b/rootfs overrides/usr/bin/sheebr.js @@ -7,6 +7,10 @@ let aliases = require("../lib/sheebr/aliases") let { spawn } = require('child_process') //utiliser ce code au lieux de execSync permet d'afficher le stdout au fur et a mesure ce qui fait qu'on a les logs quand une application throw une erreur +/** + * @param { string } cmd + * @param { import('child_process').SpawnOptionsWithoutStdio } [option] + */ async function spawnAndWait(cmd, option) { const child = spawn(cmd, option) @@ -36,6 +40,10 @@ async function start(){ } } +/** + * @param { string } input + * @returns + */ async function evaluate(input){ let lexer = new Lexer(input) let args = lexer.scanTokens() @@ -70,12 +78,13 @@ async function evaluate(input){ } - - +/** + * @param {string[]} args + */ async function evaluateProgram(args){ let found = false; - for(let path of environment.path){ + for(let path of environment.path.split(':')){ let tobreak = false; const files = fs.readdirSync(path); if(files.includes(`${args[0]}.js`)){ @@ -95,6 +104,10 @@ async function evaluateProgram(args){ } } +/** + * @param {string[]} args + * @returns + */ function evaluateEnvironmentVariables(args){ let newArgs = [] for(let arg of args){ @@ -111,6 +124,10 @@ function evaluateEnvironmentVariables(args){ return newArgs; } +/** + * @param { string[] } args + * @returns + */ function evaluateAliases(args){ if(args[0] in aliases){ return aliases[args[0]].concat(args.slice(1)) diff --git a/rootfs overrides/usr/lib/dickPick.js b/rootfs overrides/usr/lib/dickPick.js new file mode 100644 index 0000000..a548a94 --- /dev/null +++ b/rootfs overrides/usr/lib/dickPick.js @@ -0,0 +1,13 @@ +// Faire une lib en relatif + +// Faire une api a la xorg + +// Faire une api de changement de resolution + +// Faire des courbes de bézier + +// Géré la transparence + +// Objet de Forme => { stroke & fill } + +// fonts \ No newline at end of file diff --git a/rootfs overrides/usr/lib/shapes.js b/rootfs overrides/usr/lib/shapes.js new file mode 100644 index 0000000..9591f1b --- /dev/null +++ b/rootfs overrides/usr/lib/shapes.js @@ -0,0 +1,101 @@ +//@ts-check +/** + * DICKPICK is a image drawing library + */ + +const graphics = require('../../chibrax/graphics') + +/** + * @param { number } x + * @param { number } y + * @param { number } dx length on the x axis + * @param { number } dy length on the y axis + * @param { string } color + */ +function drawRect(x, y, dx, dy, color) { + const bitmap = { + data: Buffer.alloc(dx*dy*4, Buffer.from(graphics.parseHexColor(color))), + width: dx, + height: dy + } + + graphics.drawBitmap(x,y, bitmap) +} + +/** + * + * @param { import('@jimp/core').Bitmap } Bitmap + * @param { number[] } color + * @returns { Pencil } + */ +function pencilFromBitmap(Bitmap, color) { + return { ...Bitmap, color } +} + +/** + * @param { number } width + * @param { number } height + * @returns + */ +function createBitmap(width, height) { + const data = Buffer.alloc(width * height * 4, Buffer.from([0, 0, 0, 0])); + return { width, height, data } +} + +/** + * @param { Pencil } pencil + * @param { number } x + * @param { number } y + */ +function setPixel(pencil, x, y) { + pencil.data.set(pencil.color, y*pencil.width*4 + x*4) +} + + +/** + * + * @param { number } x + * @param { number } y + * @param { number } xc + * @param { number } yc + * @param { Pencil } pencil + */ +function symetrie8Axes(xc, yc, x, y, pencil) { + setPixel(pencil, x+xc, y+yc) + setPixel(pencil, x+xc,-y+yc) + setPixel(pencil, -x+xc,-y+yc) + setPixel(pencil, -x+xc,y+yc) + setPixel(pencil, y+xc,x+yc) + setPixel(pencil, y+xc,-x+yc) + setPixel(pencil, -y+xc,-x+yc) + setPixel(pencil, -y+xc,x+yc,) +} + +/** + * BresenhamCircle + * @param { Pencil } pencil + * @param { number } xc + * @param { number } yc + * @param { number } r + */ +function drawCircle(pencil, xc, yc, r) { + let x = 0 + let y = r + let d = 3 - (2 * r); + symetrie8Axes(xc, yc, x, y, pencil); + + while(x <= y) { + if(d <= 0) { + d = d + (4 * x) + 6; + } + else { + d = d + (4 * x) - (4 * y) + 10; + y = y - 1; + } + x = x + 1; + symetrie8Axes(xc, yc, x, y, pencil); + } +} + + +module.exports = { drawRect, setPixel, pencilFromBitmap, createBitmap, drawCircle } \ No newline at end of file diff --git a/rootfs overrides/usr/lib/sheebr/aliases.js b/rootfs overrides/usr/lib/sheebr/aliases.js index 1e6b442..0951632 100644 --- a/rootfs overrides/usr/lib/sheebr/aliases.js +++ b/rootfs overrides/usr/lib/sheebr/aliases.js @@ -1,3 +1,7 @@ +//@ts-check +/** + * @type {{ [key: string]: string[] }} + */ const aliases = { ls: ["ls", "--color"] } diff --git a/rootfs overrides/usr/lib/sheebr/environment.js b/rootfs overrides/usr/lib/sheebr/environment.js index 8e015fa..55dce3f 100644 --- a/rootfs overrides/usr/lib/sheebr/environment.js +++ b/rootfs overrides/usr/lib/sheebr/environment.js @@ -1,9 +1,13 @@ +//@ts-check +/** + * @type {{ [key: string]: string }} + */ let environment = { - path: ["/usr/bin", "/usr/sbin", "/usr/lib/sheebr", "/usr/local/bin", "/usr/local/sbin/"], + path: ["/usr/bin", "/usr/sbin", "/usr/lib/sheebr", "/usr/local/bin", "/usr/local/sbin/"].join(':'), ls_color: JSON.stringify({ - di: [01, 34], - ln: [01, 36], - ex: [01, 32] + di: [1, 34], + ln: [1, 36], + ex: [1, 32] }), node: "/usr/local/bin/node" } diff --git a/rootfs overrides/usr/lib/sheebr/lexer.js b/rootfs overrides/usr/lib/sheebr/lexer.js index 994ae4a..7a75d3c 100644 --- a/rootfs overrides/usr/lib/sheebr/lexer.js +++ b/rootfs overrides/usr/lib/sheebr/lexer.js @@ -1,54 +1,59 @@ +//@ts-check const { isAlpha } = require('./utils') class Lexer{ - constructor(source){ - this.tokens = []; - this.current = 0; - this.start = 0; - this.source = source - } + /** + * @param { string } source + */ + constructor(source){ + /** @type { string[] } */ + this.tokens = []; + this.current = 0; + this.start = 0; + this.source = source + } - scanTokens(){ - while(this.current < this.source.length){ - this.start = this.current - this.scanToken() - - } - return this.tokens; - } - - scanToken(){ - - if(this.source[this.current] == "\""){ - this.string() - } - else{ - let content = "" - while(this.source[this.current] != ' ' && this.source[this.current] != '\n' && this.current < this.source.length ){ - content += this.source[this.current]; - this.current++; - - } - this.tokens.push(content) - } - this.current++; + scanTokens(){ + while(this.current < this.source.length){ + this.start = this.current + this.scanToken() } + return this.tokens; + } - string(){ - this.current++; + scanToken(){ + + if(this.source[this.current] == "\""){ + this.string() + } + else{ let content = "" - while(this.source[this.current] != "\"" && this.current < this.source.length){ + while(this.source[this.current] != ' ' && this.source[this.current] != '\n' && this.current < this.source.length ){ content += this.source[this.current]; this.current++; + } this.tokens.push(content) } + this.current++; - addToken(tokenType, value=""){ - this.tokens.push(Token(tokenType, value)) + } + + string(){ + this.current++; + let content = "" + while(this.source[this.current] != "\"" && this.current < this.source.length){ + content += this.source[this.current]; + this.current++; } + this.tokens.push(content) + } + + //addToken(tokenType, value=""){ + // this.tokens.push(Token(tokenType, value)) + //} } diff --git a/rootfs overrides/usr/lib/sheebr/utils.js b/rootfs overrides/usr/lib/sheebr/utils.js index 15d5141..a8f24f5 100644 --- a/rootfs overrides/usr/lib/sheebr/utils.js +++ b/rootfs overrides/usr/lib/sheebr/utils.js @@ -24,6 +24,10 @@ async function getline(str) { }) } +/** + * @param { string } str + * @returns + */ function isAlpha(str){ return /^[a-zA-Z]*$/.test(str) } diff --git a/rootfs overrides/chibrax/tsconfig.json b/tsconfig.json similarity index 84% rename from rootfs overrides/chibrax/tsconfig.json rename to tsconfig.json index b90470c..bcb0316 100644 --- a/rootfs overrides/chibrax/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "include": ["./**/*"], + "include": ["./definitions.d.ts", "./rootfs overrides/**/*"], "compilerOptions": { // Tells TypeScript to read JS files, as // normally they are ignored as source files