diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f833627..e285ef9 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -56,7 +56,8 @@ jobs:
- name: Compressing UNIX theme
run: |
tar -cvzf GoogleDot-Blue.tar.gz themes/GoogleDot-Blue
- tar -cvzf GoogleDot-Black.tar.gz themes/GoogleDot-Blue
+ tar -cvzf GoogleDot-Black.tar.gz themes/GoogleDot-Black
+ tar -cvzf GoogleDot-White.tar.gz themes/GoogleDot-White
- name: Uploading `bitmaps` artifact
uses: actions/upload-artifact@v2
@@ -76,6 +77,12 @@ jobs:
name: GoogleDot-Black
path: GoogleDot-Black.tar.gz
+ - name: Uploading `GoogleDot-White` UNIX Theme artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: GoogleDot-White
+ path: GoogleDot-White.tar.gz
+
- name: Uploading `GoogleDot-Blue` Windows Theme artifact
uses: actions/upload-artifact@v2
with:
@@ -87,3 +94,9 @@ jobs:
with:
name: GoogleDot-Black-Windows
path: themes/GoogleDot-Black-Windows/*
+
+ - name: Uploading `GoogleDot-White` Windows Theme artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: GoogleDot-White-Windows
+ path: themes/GoogleDot-White-Windows/*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6141280..b13fd76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [unreleased]
+## [v1.1.1] - 29 Mar 2021
+
+### Added
+
+- **GoogleDot White** version added
+- Clean `builder` cache on every build (supported in `Makefile`)
+- Dynamic build using **Make variables** inside `builder/Makefile`
+- **2-Space** format for `bitmapper`
+- Sphinx `reST` docstring in `builder/gbpkg`
+
+### Changed
+
+- GoogleDot logo updated with white split
+- Preview section updated in **[README.md](./README.md)**
+- gbpkg supports **clickgen v1.1.9**
+- Install `gbpkg` builder python package as user
+- Removed python3 `virtualenv` commands from `builder/Makefile`
+
## [v1.1.0] - 08 Mar 2021
### Added
@@ -49,7 +67,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Logo and badges
- CI/CD Pipelines
-[unreleased]: https://github.com/ful1e5/Google_Cursor/compare/v1.1.0...main
+[unreleased]: https://github.com/ful1e5/Google_Cursor/compare/v1.1.1...main
+[v1.1.1]: https://github.com/ful1e5/Google_Cursor/compare/v1.1.0...v1.1.1
[v1.1.0]: https://github.com/ful1e5/Google_Cursor/compare/v1.0.1...v1.1.0
[v1.0.1]: https://github.com/ful1e5/Google_Cursor/compare/v1.0.0...v1.0.1
[v1.0.0]: https://github.com/ful1e5/Google_Cursor/tree/v1.0.0
diff --git a/Makefile b/Makefile
index 2d64842..fef206b 100644
--- a/Makefile
+++ b/Makefile
@@ -10,10 +10,10 @@ root_dest := $(root)/$(theme)
all: clean render build
unix: clean render bitmaps
- @cd builder && make build_unix
+ @cd builder && make build_unix clean
windows: clean render bitmaps
- @cd builder && make build_windows
+ @cd builder && make build_windows clean
.PHONY: all
@@ -24,7 +24,7 @@ render: bitmapper svg
@cd bitmapper && $(MAKE)
build: bitmaps
- @cd builder && $(MAKE)
+ @cd builder && make build clean
.ONESHELL:
SHELL:=/bin/bash
diff --git a/README.md b/README.md
index e2881ab..9fbd48f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
@@ -114,7 +114,13 @@ Cursor theme inspired on **google material design** for `Windows` and `Linux` wi
- BlackBlue GoogleDot Cursors 🍭
+ Black GoogleDot Cursors 🍭
+
+
+
+
+
+ White GoogleDot Cursors 🍭
### Manual Install
diff --git a/bitmapper/package.json b/bitmapper/package.json
index 6df6d10..82e3dbd 100644
--- a/bitmapper/package.json
+++ b/bitmapper/package.json
@@ -1,32 +1,32 @@
{
- "name": "google_cursor",
- "version": "1.1.0",
- "description": "🍭 Cursor theme inspired on Google",
- "main": "index.js",
- "repository": "git@github.com:ful1e5/Google_Cursor.git",
- "author": "Kaiz Khatri",
- "license": "GPL-3.0",
- "private": true,
- "scripts": {
- "clean": "rm -rf bitmaps themes",
- "dev": "nodemon src/index.ts",
- "watch": "nodemon --inspect src/index.ts",
- "py_install": "pip install -r requirements.txt",
- "render": "npx ts-node src/index.ts",
- "build": "python build.py",
- "compile": "yarn clean && yarn render && yarn build"
- },
- "devDependencies": {
- "@types/pixelmatch": "^5.2.2",
- "@types/pngjs": "^3.4.2",
- "@types/puppeteer": "^5.4.2",
- "nodemon": "^2.0.7",
- "ts-node": "^9.1.1",
- "typescript": "^4.1.3"
- },
- "dependencies": {
- "pixelmatch": "^5.2.1",
- "pngjs": "^6.0.0",
- "puppeteer": "^5.5.0"
- }
+ "name": "google_cursor",
+ "version": "1.1.1",
+ "description": "🍭 Cursor theme inspired on Google",
+ "main": "index.js",
+ "repository": "git@github.com:ful1e5/Google_Cursor.git",
+ "author": "Kaiz Khatri",
+ "license": "GPL-3.0",
+ "private": true,
+ "scripts": {
+ "clean": "rm -rf bitmaps themes",
+ "dev": "nodemon src/index.ts",
+ "watch": "nodemon --inspect src/index.ts",
+ "py_install": "pip install -r requirements.txt",
+ "render": "npx ts-node src/index.ts",
+ "build": "python build.py",
+ "compile": "yarn clean && yarn render && yarn build"
+ },
+ "devDependencies": {
+ "@types/pixelmatch": "^5.2.2",
+ "@types/pngjs": "^3.4.2",
+ "@types/puppeteer": "^5.4.2",
+ "nodemon": "^2.0.7",
+ "ts-node": "^9.1.1",
+ "typescript": "^4.1.3"
+ },
+ "dependencies": {
+ "pixelmatch": "^5.2.1",
+ "pngjs": "^6.0.0",
+ "puppeteer": "^5.5.0"
+ }
}
diff --git a/bitmapper/src/config.ts b/bitmapper/src/config.ts
index e56a352..ef89ae4 100644
--- a/bitmapper/src/config.ts
+++ b/bitmapper/src/config.ts
@@ -1,8 +1,8 @@
import { Colors } from "./core/types";
interface Config {
- themeName: string;
- color: Colors;
+ themeName: string;
+ color: Colors;
}
const black = "#000000";
@@ -10,20 +10,27 @@ const blue = "#4285F4";
const white = "#FFFFFF";
const config: Config[] = [
- {
- themeName: "GoogleDot-Blue",
- color: {
- base: blue,
- outline: white,
- },
- },
- {
- themeName: "GoogleDot-Black",
- color: {
- base: black,
- outline: white,
- },
- },
+ {
+ themeName: "GoogleDot-Blue",
+ color: {
+ base: blue,
+ outline: white,
+ },
+ },
+ {
+ themeName: "GoogleDot-Black",
+ color: {
+ base: black,
+ outline: white,
+ },
+ },
+ {
+ themeName: "GoogleDot-White",
+ color: {
+ base: white,
+ outline: black,
+ },
+ },
];
export { config };
diff --git a/bitmapper/src/core/BitmapsGenerator.ts b/bitmapper/src/core/BitmapsGenerator.ts
index 7a017ba..c9017a0 100644
--- a/bitmapper/src/core/BitmapsGenerator.ts
+++ b/bitmapper/src/core/BitmapsGenerator.ts
@@ -8,148 +8,148 @@ import { matchImages } from "./util/matchImages";
import { toHTML } from "./util/toHTML";
class BitmapsGenerator {
- /**
- * Generate Png files from svg code.
- * @param themeName Give name, So all bitmaps files are organized in one directory.
- * @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store.
- */
- constructor(private bitmapsDir: string) {
- this.bitmapsDir = path.resolve(bitmapsDir);
- this.createDir(this.bitmapsDir);
- }
-
- /**
- * Create directory if it doesn't exists.
- * @param dirPath directory `absolute` path.
- */
- private createDir(dirPath: string) {
- if (!fs.existsSync(dirPath)) {
- fs.mkdirSync(dirPath, { recursive: true });
- }
- }
-
- /**
- * Prepare headless browser.
- */
- public async getBrowser(): Promise {
- return await puppeteer.launch({
- ignoreDefaultArgs: ["--no-sandbox"],
- headless: true,
- });
- }
-
- private async getSvgElement(
- page: Page,
- content: string
- ): Promise> {
- if (!content) {
- throw new Error(`${content} File Read error`);
- }
-
- const html = toHTML(content);
- await page.setContent(html, { timeout: 0 });
-
- const svg = await page.$("#container svg");
-
- if (!svg) {
- throw new Error("svg element not found!");
- }
- return svg;
- }
-
- public async generateStatic(browser: Browser, content: string, key: string) {
- const page = await browser.newPage();
- const svg = await this.getSvgElement(page, content);
-
- const out = path.resolve(this.bitmapsDir, `${key}.png`);
-
- await svg.screenshot({ omitBackground: true, path: out });
- await page.close();
- }
-
- private async screenshot(
- element: ElementHandle
- ): Promise {
- const buffer = await element.screenshot({
- encoding: "binary",
- omitBackground: true,
- });
-
- if (!buffer) {
- throw new Error("SVG element screenshot not working");
- }
- return buffer;
- }
-
- private async stopAnimation(page: Page) {
- const client = await page.target().createCDPSession();
- await client.send("Animation.setPlaybackRate", {
- playbackRate: 0,
- });
- }
-
- private async resumeAnimation(page: Page, playbackRate: number) {
- const client = await page.target().createCDPSession();
- await client.send("Animation.setPlaybackRate", {
- playbackRate,
- });
- }
-
- private async saveFrameImage(key: string, frame: Buffer | string) {
- const out_path = path.resolve(this.bitmapsDir, key);
- fs.writeFileSync(out_path, frame);
- }
-
- public async generateAnimated(
- browser: Browser,
- content: string,
- key: string,
- options?: {
- playbackRate?: number;
- diff?: number;
- frameLimit?: number;
- framePadding?: number;
- }
- ) {
- const opt = Object.assign(
- { playbackRate: 0.1, diff: 0, frameLimit: 300, framePadding: 4 },
- options
- );
-
- const page = await browser.newPage();
- const svg = await this.getSvgElement(page, content);
- await this.stopAnimation(page);
-
- let index = 1;
- let breakRendering = false;
- let prevImg: Buffer | string;
-
- // Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
- while (!breakRendering) {
- if (index > opt.frameLimit) {
- throw new Error("Reached the frame limit.");
- }
-
- await this.resumeAnimation(page, opt.playbackRate);
- const img: string | Buffer = await this.screenshot(svg);
- await this.stopAnimation(page);
-
- if (index > 1) {
- // @ts-ignore
- const diff = matchImages(prevImg, img);
- if (diff <= opt.diff) {
- breakRendering = !breakRendering;
- }
- }
- const number = frameNumber(index, opt.framePadding);
- const frame = `${key}-${number}.png`;
-
- this.saveFrameImage(frame, img);
-
- prevImg = img;
- ++index;
- }
- await page.close();
- }
+ /**
+ * Generate Png files from svg code.
+ * @param themeName Give name, So all bitmaps files are organized in one directory.
+ * @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store.
+ */
+ constructor(private bitmapsDir: string) {
+ this.bitmapsDir = path.resolve(bitmapsDir);
+ this.createDir(this.bitmapsDir);
+ }
+
+ /**
+ * Create directory if it doesn't exists.
+ * @param dirPath directory `absolute` path.
+ */
+ private createDir(dirPath: string) {
+ if (!fs.existsSync(dirPath)) {
+ fs.mkdirSync(dirPath, { recursive: true });
+ }
+ }
+
+ /**
+ * Prepare headless browser.
+ */
+ public async getBrowser(): Promise {
+ return await puppeteer.launch({
+ ignoreDefaultArgs: ["--no-sandbox"],
+ headless: true,
+ });
+ }
+
+ private async getSvgElement(
+ page: Page,
+ content: string
+ ): Promise> {
+ if (!content) {
+ throw new Error(`${content} File Read error`);
+ }
+
+ const html = toHTML(content);
+ await page.setContent(html, { timeout: 0 });
+
+ const svg = await page.$("#container svg");
+
+ if (!svg) {
+ throw new Error("svg element not found!");
+ }
+ return svg;
+ }
+
+ public async generateStatic(browser: Browser, content: string, key: string) {
+ const page = await browser.newPage();
+ const svg = await this.getSvgElement(page, content);
+
+ const out = path.resolve(this.bitmapsDir, `${key}.png`);
+
+ await svg.screenshot({ omitBackground: true, path: out });
+ await page.close();
+ }
+
+ private async screenshot(
+ element: ElementHandle
+ ): Promise {
+ const buffer = await element.screenshot({
+ encoding: "binary",
+ omitBackground: true,
+ });
+
+ if (!buffer) {
+ throw new Error("SVG element screenshot not working");
+ }
+ return buffer;
+ }
+
+ private async stopAnimation(page: Page) {
+ const client = await page.target().createCDPSession();
+ await client.send("Animation.setPlaybackRate", {
+ playbackRate: 0,
+ });
+ }
+
+ private async resumeAnimation(page: Page, playbackRate: number) {
+ const client = await page.target().createCDPSession();
+ await client.send("Animation.setPlaybackRate", {
+ playbackRate,
+ });
+ }
+
+ private async saveFrameImage(key: string, frame: Buffer | string) {
+ const out_path = path.resolve(this.bitmapsDir, key);
+ fs.writeFileSync(out_path, frame);
+ }
+
+ public async generateAnimated(
+ browser: Browser,
+ content: string,
+ key: string,
+ options?: {
+ playbackRate?: number;
+ diff?: number;
+ frameLimit?: number;
+ framePadding?: number;
+ }
+ ) {
+ const opt = Object.assign(
+ { playbackRate: 0.1, diff: 0, frameLimit: 300, framePadding: 4 },
+ options
+ );
+
+ const page = await browser.newPage();
+ const svg = await this.getSvgElement(page, content);
+ await this.stopAnimation(page);
+
+ let index = 1;
+ let breakRendering = false;
+ let prevImg: Buffer | string;
+
+ // Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
+ while (!breakRendering) {
+ if (index > opt.frameLimit) {
+ throw new Error("Reached the frame limit.");
+ }
+
+ await this.resumeAnimation(page, opt.playbackRate);
+ const img: string | Buffer = await this.screenshot(svg);
+ await this.stopAnimation(page);
+
+ if (index > 1) {
+ // @ts-ignore
+ const diff = matchImages(prevImg, img);
+ if (diff <= opt.diff) {
+ breakRendering = !breakRendering;
+ }
+ }
+ const number = frameNumber(index, opt.framePadding);
+ const frame = `${key}-${number}.png`;
+
+ this.saveFrameImage(frame, img);
+
+ prevImg = img;
+ ++index;
+ }
+ await page.close();
+ }
}
export { BitmapsGenerator };
diff --git a/bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts b/bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts
index 65756da..516c69b 100644
--- a/bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts
+++ b/bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts
@@ -2,76 +2,76 @@ import fs from "fs";
import path from "path";
interface Svg {
- key: string;
- content: string;
+ key: string;
+ content: string;
}
class SvgDirectoryParser {
- /**
- * Manage and Parse SVG file path in `absolute` fashion.
- * This Parser look svg files as below fashion:
- * `
- * <@svgDir>/static
- * <@svgDir>/animated
- * `
- * @param svgDir is relative/absolute path, Where `SVG` files are stored.
- */
- semiAnimated: boolean = false;
- constructor(private svgDir: string) {
- if (!fs.existsSync(this.svgDir)) {
- throw new Error(`SVG files not found in ${this.svgDir}`);
- }
- }
+ /**
+ * Manage and Parse SVG file path in `absolute` fashion.
+ * This Parser look svg files as below fashion:
+ * `
+ * <@svgDir>/static
+ * <@svgDir>/animated
+ * `
+ * @param svgDir is relative/absolute path, Where `SVG` files are stored.
+ */
+ semiAnimated: boolean = false;
+ constructor(private svgDir: string) {
+ if (!fs.existsSync(this.svgDir)) {
+ throw new Error(`SVG files not found in ${this.svgDir}`);
+ }
+ }
- private readData(f: string): Svg {
- const content = fs.readFileSync(f, "utf-8");
- const key = path.basename(f, ".svg");
- return { content, key };
- }
+ private readData(f: string): Svg {
+ const content = fs.readFileSync(f, "utf-8");
+ const key = path.basename(f, ".svg");
+ return { content, key };
+ }
- /**
- * Return absolute paths array of SVG files data located inside '@svgDir/static'
- */
- public getStatic(): Svg[] {
- const staticDir = path.resolve(this.svgDir, "static");
+ /**
+ * Return absolute paths array of SVG files data located inside '@svgDir/static'
+ */
+ public getStatic(): Svg[] {
+ const staticDir = path.resolve(this.svgDir, "static");
- if (!fs.existsSync(staticDir)) {
- console.log(`${this.svgDir} contains semi-animated .svg files`);
- this.semiAnimated = true;
- return [];
- } else {
- const svgs = fs
- .readdirSync(staticDir)
- .map((f) => this.readData(path.resolve(staticDir, f)));
+ if (!fs.existsSync(staticDir)) {
+ console.log(`${this.svgDir} contains semi-animated .svg files`);
+ this.semiAnimated = true;
+ return [];
+ } else {
+ const svgs = fs
+ .readdirSync(staticDir)
+ .map((f) => this.readData(path.resolve(staticDir, f)));
- if (svgs.length == 0) {
- throw new Error("Static Cursors directory is empty");
- }
- return svgs;
- }
- }
- /**
- * Return absolute paths array of SVG files data located inside '@svgDir/animated'
- */
- public getAnimated(): Svg[] {
- const animatedDir = path.resolve(this.svgDir, "animated");
+ if (svgs.length == 0) {
+ throw new Error("Static Cursors directory is empty");
+ }
+ return svgs;
+ }
+ }
+ /**
+ * Return absolute paths array of SVG files data located inside '@svgDir/animated'
+ */
+ public getAnimated(): Svg[] {
+ const animatedDir = path.resolve(this.svgDir, "animated");
- if (!fs.existsSync(animatedDir)) {
- throw new Error("Animated Cursors directory not found");
- }
+ if (!fs.existsSync(animatedDir)) {
+ throw new Error("Animated Cursors directory not found");
+ }
- const svgs = fs
- .readdirSync(animatedDir)
- .map((f) => this.readData(path.resolve(animatedDir, f)));
+ const svgs = fs
+ .readdirSync(animatedDir)
+ .map((f) => this.readData(path.resolve(animatedDir, f)));
- if (svgs.length == 0 && this.semiAnimated) {
- throw new Error(
- `Can't parse svg directory ${this.svgDir} as semi-animated theme`
- );
- }
+ if (svgs.length == 0 && this.semiAnimated) {
+ throw new Error(
+ `Can't parse svg directory ${this.svgDir} as semi-animated theme`
+ );
+ }
- return svgs;
- }
+ return svgs;
+ }
}
export { SvgDirectoryParser };
diff --git a/bitmapper/src/core/SVGHandler/colorSvg.ts b/bitmapper/src/core/SVGHandler/colorSvg.ts
index 148dcd2..49a0b50 100644
--- a/bitmapper/src/core/SVGHandler/colorSvg.ts
+++ b/bitmapper/src/core/SVGHandler/colorSvg.ts
@@ -7,11 +7,11 @@ import { Colors } from "../types";
* watch.background="#FF0000" (Red)
* */
const defaultKeyColors: Colors = {
- base: "#00FF00",
- outline: "#0000FF",
- watch: {
- background: "#FF0000",
- },
+ base: "#00FF00",
+ outline: "#0000FF",
+ watch: {
+ background: "#FF0000",
+ },
};
/**
@@ -22,31 +22,31 @@ const defaultKeyColors: Colors = {
* @returns {string} SVG code with colors.
*/
const colorSvg = (
- content: string,
- colors: Colors,
- keys: Colors = defaultKeyColors
+ content: string,
+ colors: Colors,
+ keys: Colors = defaultKeyColors
): string => {
- content = content
- .replace(new RegExp(keys.base, "ig"), colors.base)
- .replace(new RegExp(keys.outline, "ig"), colors.outline);
+ content = content
+ .replace(new RegExp(keys.base, "ig"), colors.base)
+ .replace(new RegExp(keys.outline, "ig"), colors.outline);
- try {
- // === trying to replace `watch` color ===
+ try {
+ // === trying to replace `watch` color ===
- if (!colors.watch?.background) {
- throw new Error("");
- }
- const { background: b } = colors.watch;
- content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background
- } catch (error) {
- // === on error => replace `watch` color as `base` ===
+ if (!colors.watch?.background) {
+ throw new Error("");
+ }
+ const { background: b } = colors.watch;
+ content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background
+ } catch (error) {
+ // === on error => replace `watch` color as `base` ===
- content = content.replace(
- new RegExp(keys.watch!.background, "ig"),
- colors.base
- );
- }
- return content;
+ content = content.replace(
+ new RegExp(keys.watch!.background, "ig"),
+ colors.base
+ );
+ }
+ return content;
};
export { colorSvg };
diff --git a/bitmapper/src/core/types.ts b/bitmapper/src/core/types.ts
index cd5ddb3..da9fb1c 100644
--- a/bitmapper/src/core/types.ts
+++ b/bitmapper/src/core/types.ts
@@ -10,11 +10,11 @@ type HexColor = string;
* @default background is `base` color.
*/
type Colors = {
- base: HexColor;
- outline: HexColor;
- watch?: {
- background: HexColor;
- };
+ base: HexColor;
+ outline: HexColor;
+ watch?: {
+ background: HexColor;
+ };
};
export { Colors };
diff --git a/bitmapper/src/core/util/matchImages.ts b/bitmapper/src/core/util/matchImages.ts
index 625d2bd..6d09a95 100644
--- a/bitmapper/src/core/util/matchImages.ts
+++ b/bitmapper/src/core/util/matchImages.ts
@@ -2,10 +2,10 @@ import Pixelmatch from "pixelmatch";
import { PNG } from "pngjs";
export const matchImages = (img1: Buffer, img2: Buffer): number => {
- const { data: img1Data, width, height } = PNG.sync.read(img1);
- const { data: imgNData } = PNG.sync.read(img2);
+ const { data: img1Data, width, height } = PNG.sync.read(img1);
+ const { data: imgNData } = PNG.sync.read(img2);
- return Pixelmatch(img1Data, imgNData, null, width, height, {
- threshold: 0.1,
- });
+ return Pixelmatch(img1Data, imgNData, null, width, height, {
+ threshold: 0.1,
+ });
};
diff --git a/bitmapper/src/core/util/toHTML.ts b/bitmapper/src/core/util/toHTML.ts
index aecb3d7..36fbbf4 100644
--- a/bitmapper/src/core/util/toHTML.ts
+++ b/bitmapper/src/core/util/toHTML.ts
@@ -16,4 +16,4 @@ export const template = `
`;
export const toHTML = (svgData: string): string =>
- template.replace("", svgData);
+ template.replace("", svgData);
diff --git a/bitmapper/src/index.ts b/bitmapper/src/index.ts
index 75dbfdc..7873c9e 100644
--- a/bitmapper/src/index.ts
+++ b/bitmapper/src/index.ts
@@ -7,31 +7,31 @@ const root = path.resolve(__dirname, "../../");
const svgDir = path.resolve(root, "svg");
const main = async () => {
- for (const { themeName, color } of config) {
- console.log("=>", themeName);
+ for (const { themeName, color } of config) {
+ console.log("=>", themeName);
- const bitmapsDir = path.resolve(root, "bitmaps", themeName);
- const svg = new SVGHandler.SvgDirectoryParser(svgDir);
+ const bitmapsDir = path.resolve(root, "bitmaps", themeName);
+ const svg = new SVGHandler.SvgDirectoryParser(svgDir);
- const png = new BitmapsGenerator(bitmapsDir);
- const browser = await png.getBrowser();
+ const png = new BitmapsGenerator(bitmapsDir);
+ const browser = await png.getBrowser();
- for (let { key, content } of svg.getStatic()) {
- console.log(" -> Saving", key, "...");
+ for (let { key, content } of svg.getStatic()) {
+ console.log(" -> Saving", key, "...");
- content = SVGHandler.colorSvg(content, color);
- await png.generateStatic(browser, content, key);
- }
+ content = SVGHandler.colorSvg(content, color);
+ await png.generateStatic(browser, content, key);
+ }
- for (let { key, content } of svg.getAnimated()) {
- console.log(" -> Saving", key, "...");
+ for (let { key, content } of svg.getAnimated()) {
+ console.log(" -> Saving", key, "...");
- content = SVGHandler.colorSvg(content, color);
- await png.generateAnimated(browser, content, key);
- }
+ content = SVGHandler.colorSvg(content, color);
+ await png.generateAnimated(browser, content, key);
+ }
- await browser.close();
- }
+ await browser.close();
+ }
};
main();
diff --git a/bitmapper/yarn.lock b/bitmapper/yarn.lock
index df97966..da4af69 100644
--- a/bitmapper/yarn.lock
+++ b/bitmapper/yarn.lock
@@ -15,9 +15,9 @@
defer-to-connect "^1.0.1"
"@types/node@*":
- version "14.14.22"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18"
- integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
+ version "14.14.37"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e"
+ integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==
"@types/pixelmatch@^5.2.2":
version "5.2.2"
@@ -34,9 +34,9 @@
"@types/node" "*"
"@types/puppeteer@^5.4.2":
- version "5.4.2"
- resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.2.tgz#80f3a1f54dedbbf750779716de81401549062072"
- integrity sha512-yjbHoKjZFOGqA6bIEI2dfBE5UPqU0YGWzP+ipDVP1iGzmlhksVKTBVZfT3Aj3wnvmcJ2PQ9zcncwOwyavmafBw==
+ version "5.4.3"
+ resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.3.tgz#cdca84aa7751d77448d8a477dbfa0af1f11485f2"
+ integrity sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==
dependencies:
"@types/node" "*"
@@ -110,9 +110,9 @@ binary-extensions@^2.0.0:
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bl@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489"
- integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+ integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
@@ -393,9 +393,9 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fsevents@~2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f"
- integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
get-stream@^4.1.0:
version "4.1.0"
@@ -412,9 +412,9 @@ get-stream@^5.1.0:
pump "^3.0.0"
glob-parent@~5.1.0:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
- integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
@@ -455,9 +455,9 @@ got@^9.6.0:
url-parse-lax "^3.0.0"
graceful-fs@^4.1.2:
- version "4.2.4"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
- integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
+ version "4.2.6"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
+ integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
has-flag@^3.0.0:
version "3.0.0"
@@ -590,9 +590,9 @@ is-obj@^2.0.0:
integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
is-path-inside@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017"
- integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
is-typedarray@^1.0.0:
version "1.0.0"
@@ -969,9 +969,9 @@ string-width@^3.0.0:
strip-ansi "^5.1.0"
string-width@^4.0.0, string-width@^4.1.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
- integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
+ integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
@@ -1092,9 +1092,9 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0"
typescript@^4.1.3:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
- integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
+ integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
unbzip2-stream@^1.3.3:
version "1.4.3"
@@ -1172,9 +1172,9 @@ write-file-atomic@^3.0.0:
typedarray-to-buffer "^3.1.5"
ws@^7.2.3:
- version "7.4.2"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
- integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
+ version "7.4.4"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
+ integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
xdg-basedir@^4.0.0:
version "4.0.0"
diff --git a/builder/Makefile b/builder/Makefile
index 11b0def..f4cd129 100644
--- a/builder/Makefile
+++ b/builder/Makefile
@@ -7,6 +7,7 @@ all: clean setup build
.ONESHELL:
SHELL:=/bin/bash
+THEMES = Blue Black White
X_SIZES ?=22 24 28 32 40 48 56 64 72 80 88 96
WIN_CANVAS_SIZE ?= 32
WIN_SIZE ?= 24
@@ -22,18 +23,13 @@ clean:
@fi
setup: setup.py
- @test -d venv || python3 -m venv venv
- @. venv/bin/activate; python3 setup.py install --record files.txt
+ @python3 setup.py install --user --record files.txt
build: setup build.py
- @. venv/bin/activate; python3 build.py -p "$(bitmaps_dir)/GoogleDot-Blue" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE)
- @. venv/bin/activate; python3 build.py -p "$(bitmaps_dir)/GoogleDot-Black" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE)
+ @$(foreach theme,$(THEMES), python3 build.py -p "$(bitmaps_dir)/GoogleDot-$(theme)" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);)
build_unix: setup build.py
- @. venv/bin/activate; python3 build.py unix -p "$(bitmaps_dir)/GoogleDot-Blue" --xsizes $(X_SIZES)
- @. venv/bin/activate; python3 build.py unix -p "$(bitmaps_dir)/GoogleDot-Black" --xsizes $(X_SIZES)
+ @$(foreach theme,$(THEMES), python3 build.py unix -p "$(bitmaps_dir)/GoogleDot-$(theme)" --xsizes $(X_SIZES);)
build_windows: setup build.py
- @. venv/bin/activate; python3 build.py windows -p "$(bitmaps_dir)/GoogleDot-Blue" --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE)
- @. venv/bin/activate; python3 build.py windows -p "$(bitmaps_dir)/GoogleDot-Black" --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE)
-
+ @$(foreach theme,$(THEMES), python3 build.py windows -p "$(bitmaps_dir)/GoogleDot-$(theme)" --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);)
diff --git a/builder/gbpkg/configure.py b/builder/gbpkg/configure.py
index 0e7309d..5dfe5ee 100644
--- a/builder/gbpkg/configure.py
+++ b/builder/gbpkg/configure.py
@@ -16,31 +16,25 @@ def to_tuple(x: X) -> Tuple[X, X]:
def get_config(bitmaps_dir, **kwargs) -> Dict[str, Any]:
"""Return configuration of `GoogleDot` pointers.
- ```
- Args:
-
- :bitmaps_dir: (str | Path) Path to .png file's directory.
-
- Keywords Args:
+ :param bitmaps_dir: Path to .png file's directory.
+ :type bitmaps_dir: Union[str, Path]
- :x_sizes: (List[int]) List of pixel-sizes for xcursors.
+ :param \**kwargs:
+ See below
- :win_canvas_size: (int) Windows cursor's canvas pixel-size.
-
- :win_size: (int) Pixel-size for Windows cursor.
-
- ```
+ :Keyword Arguments:
+ * *x_sizes* (``List[int]``) --
+ List of pixel-sizes for xcursors.
+ * *win_canvas_size* (``int``) --
+ Windows cursor's canvas pixel-size.
+ * *win_size* (``int``) --
+ Pixel-size for Windows cursor.
Example:
```python
- get_config(
- "./bitmaps",
- x_sizes=[(24, 24), (32, 32)],
- win_canvas_size=(32, 32),
- win_size=(24, 24),
- )
+ get_config("./bitmaps", x_sizes=[24, 32], win_canvas_size=32, win_size=24)
```
"""
diff --git a/builder/gbpkg/generator.py b/builder/gbpkg/generator.py
index c82830d..3820762 100644
--- a/builder/gbpkg/generator.py
+++ b/builder/gbpkg/generator.py
@@ -19,14 +19,16 @@ class Info(NamedTuple):
def xbuild(config: Dict[str, Dict[str, Any]], x_out_dir: Path, info: Info) -> None:
"""Build `GoogleDot` cursor theme for only `X11`(UNIX) platform.
- ```
- :config: (Dict) `GoogleDot` configuration.
-
- :x_out_dir: (Path) Path to the output directory,
- Where the `X11` cursor theme package will generate.
- It also creates a directory if not exists.
- :info: (Dict) Content theme name & comment
- ```
+ :param config: `GoogleDot` configuration.
+ :type config: Dict
+
+ :param x_out_dir: Path to the output directory,\
+ Where the `X11` cursor theme package will generate.\
+ It also creates a directory if not exists.
+ :type x_out_dir: Path
+
+ :param info: Content theme name & comment
+ :type info: Info
"""
for _, item in config.items():
@@ -47,14 +49,16 @@ def xbuild(config: Dict[str, Dict[str, Any]], x_out_dir: Path, info: Info) -> No
def wbuild(config: Dict[str, Dict[str, Any]], win_out_dir: Path, info: Info) -> None:
"""Build `GoogleDot` cursor theme for only `Windows` platforms.
- ```
- :config: (Dict) `GoogleDot` configuration.
+ :param config: `GoogleDot` configuration.
+ :type config: Dict
- :win_out_dir: (Path) Path to the output directory,
- Where the `Windows` cursor theme package will generate.
- It also creates a directory if not exists.
- :info: (Dict) Content theme name & comment
- ```
+ :param win_out_dir: Path to the output directory,\
+ Where the `Windows` cursor theme package will generate.\
+ It also creates a directory if not exists.
+ :type win_out_dir: Path
+
+ :param info: Content theme name & comment
+ :type info: Info
"""
for _, item in config.items():
@@ -87,18 +91,21 @@ def build(
) -> None:
"""Build `GoogleDot` cursor theme for `X11` & `Windows` platforms.
- ```
- :config: (Dict) `GoogleDot` configuration.
+ :param config: `GoogleDot` configuration.
+ :type config: Dict
+
+ :param x_out_dir: Path to the output directory,\
+ Where the `X11` cursor theme package will generate.\
+ It also creates a directory if not exists.
+ :type x_out_dir: Path
- :x_out_dir: (Path) Path to the output directory,
- Where the `X11` cursor theme package will generate.
- It also creates a directory if not exists.
+ :param win_out_dir: Path to the output directory,\
+ Where the `Windows` cursor theme package will generate.\
+ It also creates a directory if not exists.
+ :type win_out_dir: Path
- :win_out_dir: (Path) Path to the output directory,
- Where the `Windows` cursor theme package will generate.
- It also creates a directory if not exists.
- :info: (Dict) Content theme name & comment
- ```
+ :param info: Content theme name & comment
+ :type info: Info
"""
def win_build(item: Dict[str, Any], alias: CursorAlias) -> None:
diff --git a/builder/gbpkg/symlinks.py b/builder/gbpkg/symlinks.py
index b745d69..d80480d 100644
--- a/builder/gbpkg/symlinks.py
+++ b/builder/gbpkg/symlinks.py
@@ -10,7 +10,8 @@
def add_missing_xcursor(directory) -> None:
"""Add missing `XCursor` to the Unix cursor package.
- :directory: (Path|str) directory where XCursors are available.
+ :param directory: directory where XCursors are available.
+ :type directory: Union[str, Path]
"""
symlinks: List[Dict[str, Union[str, List[str]]]] = [
@@ -181,7 +182,7 @@ def add_missing_xcursor(directory) -> None:
with chdir(directory):
for item in symlinks:
- src = item.get("src")
+ src = str(item["src"])
for link in item.get("links"):
print(f"Creating symlink {src} -> {link}")
os.symlink(src, link)
diff --git a/builder/setup.py b/builder/setup.py
index b0e6efb..2168891 100644
--- a/builder/setup.py
+++ b/builder/setup.py
@@ -5,14 +5,14 @@
setup(
name="gbpkg",
- version="1.1.0",
+ version="1.1.1",
description="Generate 'GoogleDot' cursor theme from PNGs file",
url="https://github.com/ful1e5/Google_Cursor",
packages=["gbpkg"],
package_dir={"gbpkg": "gbpkg"},
author="Kaiz Khatri",
author_email="kaizmandhu@gamil.com",
- install_requires=["clickgen==1.1.8"],
+ install_requires=["clickgen==1.1.9"],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",