Let's build browser engine! in typescript vol2 Display Command
Murahashi [Matt] Kenichi
Posted on April 26, 2019
// node_modules/.bin/ts-node example/display-command.ts | display
import * as Jimp from "jimp";
import { Rect } from "../src/layout";
import { Canvas, DisplayCommand } from "../src/painting";
import { Color } from "../src/css";
const black = new Color(0, 0, 0, 255);
const canvas = Canvas.Create(200, 100);
canvas.paintItem(new DisplayCommand.SolidColor(black, new Rect(10, 20, 30, 30)));
Jimp.create(canvas.width, canvas.height)
.then((value: Jimp) => {
let buffer = value.bitmap.data;
for (let i = 0; i < canvas.pixels.length; i++) {
buffer[i * 4] = canvas.pixels[i].r;
buffer[i * 4 + 1] = canvas.pixels[i].g;
buffer[i * 4 + 2] = canvas.pixels[i].b;
buffer[i * 4 + 3] = canvas.pixels[i].a;
}
return value.getBufferAsync(Jimp.MIME_PNG);
})
.then((value: Buffer) => {
process.stdout.write(value);
})
.catch((error: Error) => {
console.error(error);
});
import { Rect } from "../src/layout";
test("rect", () => {
expect(new Rect(1, 2, 3, 4).height).toBe(4);
});
export class Rect {
x: number;
y: number;
width: number;
height: number;
constructor(x: number, y: number, width: number, height: number) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
import { Canvas, DisplayCommand } from "../src/painting";
import { Color } from "../src/css";
import { Rect } from "../src/layout";
const white = new Color(255, 255, 255, 255);
const black = new Color(0, 0, 0, 255);
test("solid color", () => {
expect(new DisplayCommand.SolidColor(white, new Rect(0, 0, 0, 0)).format).toEqual(
DisplayCommand.Format.SolidColor
);
});
test("canvas paint item", () => {
const canvas = Canvas.Create(2, 3);
canvas.paintItem(new DisplayCommand.SolidColor(black, new Rect(0, 0, 1, 1)));
expect(canvas.pixels).toEqual([black, white, white, white, white, white]);
});
import { Color } from "./css";
import { Rect } from "./layout";
const mathClamp = require("math-clamp");
export class Canvas {
// snip
paintItem(item: DisplayCommand) {
switch (item.format) {
case DisplayCommand.Format.SolidColor:
const rect = item.rect;
const color = item.color;
let x0 = mathClamp(rect.x, 0.0, this.width);
let y0 = mathClamp(rect.y, 0.0, this.height);
let x1 = mathClamp(rect.x + rect.width, 0.0, this.width);
let y1 = mathClamp(rect.y + rect.height, 0.0, this.height);
for (let y = y0; y < y1; y++) {
for (let x = x0; x < x1; x++) {
// TODO: alpha compositing with existing pixel
this.pixels[x + y * this.width] = color;
}
}
}
}
}
export namespace DisplayCommand {
export enum Format {
SolidColor
}
export class SolidColor {
readonly format = Format.SolidColor;
color: Color;
rect: Rect;
constructor(color: Color, rect: Rect) {
this.color = color;
this.rect = rect;
}
}
}
export type DisplayCommand = DisplayCommand.SolidColor;
It works!
references
- Let's build a browser engine! Part 1: Getting started
- mbrubeck/robinson
- sanemat/js-toy-engine
- sanemat/ts-toy-engine
series
- Let's build browser engine! in typescript vol0 Toy browser engine
- Let's build browser engine! in typescript vol1 Canvas with Color
- Let's build browser engine! in typescript vol2 Display Command
- Let's build browser engine! in typescript vol3 Layout Box, Dimensions
- Let's build browser engine! in typescript vol4 Layout Tree to Display List
💖 💪 🙅 🚩
Murahashi [Matt] Kenichi
Posted on April 26, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
webdev Understanding HTTP, Cookies, Email Protocols, and DNS: A Guide to Key Internet Technologies
November 30, 2024
react Axios NPM Package: A Beginner's Guide to Installing and Making HTTP Requests
November 30, 2024
webdev Guide to Cookies, Local Storage, Session Storage, and Other Web Storage Mechanisms
November 30, 2024