UNPKG

@mlightcad/common

Version:

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://img.shields.io/npm/v/@mlightcad/common.svg)](https://www.npmjs.com/package/@mlightcad/common)

580 lines 21 kB
var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import { AcCmColorMethod } from './AcCmColorMethod'; import { AcCmColorUtil } from './AcCmColorUtil'; /** * Represents an AutoCAD color. This class supports color methods: * - ByColor: explicit RGB * - ByACI: AutoCAD Color Index (0-256) * - ByLayer: color inherited from layer * - ByBlock: color inherited from block */ var AcCmColor = /** @class */ (function () { /** * Constructs a new AcCmColor. * @param method Initial color method (defaults to `ByColor`) * @param value Internal packed value */ function AcCmColor(method, value) { if (method === void 0) { method = AcCmColorMethod.ByLayer; } this._colorMethod = method; if (this._colorMethod == AcCmColorMethod.ByColor && value == null) { this._value = 0xffffff; } else if (this._colorMethod == AcCmColorMethod.ByACI) { if (value == null) { this._value = 8; } else if (value === 0) { this._colorMethod = AcCmColorMethod.ByBlock; } else if (value === 256) { this._colorMethod = AcCmColorMethod.ByLayer; } else { this._value = Math.max(0, Math.min(value, 256)); } } else { this._value = value; } } Object.defineProperty(AcCmColor.prototype, "colorMethod", { // --------------------------------------------------------------------- // Color method // --------------------------------------------------------------------- /** Gets the current color method. */ get: function () { return this._colorMethod; }, /** * Sets the color method. * * Note: Changing the method does not modify `_value`. */ set: function (method) { this._colorMethod = method; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "red", { // --------------------------------------------------------------------- // RGB accessors (ByColor) // --------------------------------------------------------------------- /** Gets the red component (0–255). */ get: function () { var rgb = this.RGB; return rgb != null ? (rgb >> 16) & 0xff : undefined; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "green", { /** Gets the green component (0–255). */ get: function () { var rgb = this.RGB; return rgb != null ? (rgb >> 8) & 0xff : undefined; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "blue", { /** Gets the blue component (0–255). */ get: function () { var rgb = this.RGB; return rgb != null ? rgb & 0xff : undefined; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "RGB", { /** * Gets the packed RGB value (0xRRGGBB). * * - For `ByColor`, returns `_value` directly * - For `ByACI`, converts index to RGB via `AcCmColorUtil` * - For `ByLayer` or `ByBlock`, returns `_value` directly */ get: function () { switch (this._colorMethod) { case AcCmColorMethod.ByColor: case AcCmColorMethod.ByBlock: case AcCmColorMethod.ByLayer: return this._value; case AcCmColorMethod.ByACI: return this._value ? AcCmColorUtil.getColorByIndex(this._value) : this._value; default: return undefined; } }, enumerable: false, configurable: true }); /** * Sets the RGB color. * * @param r Red component (0–255) * @param g Green component (0–255) * @param b Blue component (0–255) * @returns The current instance for chaining */ AcCmColor.prototype.setRGB = function (r, g, b) { var red = Math.max(0, Math.min(255, Math.round(r))); var green = Math.max(0, Math.min(255, Math.round(g))); var blue = Math.max(0, Math.min(255, Math.round(b))); this._value = (red << 16) | (green << 8) | blue; this._colorMethod = AcCmColorMethod.ByColor; return this; }; /** * Sets the RGB color by a single packed number (0xRRGGBB). * * @param value Packed RGB number */ AcCmColor.prototype.setRGBValue = function (value) { if (value == null || !Number.isFinite(value)) { console.warn('Invalid RGB value:', value); return this; } this._value = value & 0xffffff; this._colorMethod = AcCmColorMethod.ByColor; return this; }; /** * Sets the RGB color from a CSS color string. * * Examples: * - "#FF00FF" * - "#F0F" * - "rgb(255,0,255)" * - "rgba(255,0,255,0.5)" * - "red" (named colors) * * @param cssString CSS color string * @returns The current instance for chaining */ AcCmColor.prototype.setRGBFromCss = function (cssString) { if (!cssString) return this; var s = cssString.trim().toLowerCase(); // Hex: #RRGGBB or #RGB if (s.startsWith('#')) { var r = 0, g = 0, b = 0; if (s.length === 7) { r = parseInt(s.substr(1, 2), 16); g = parseInt(s.substr(3, 2), 16); b = parseInt(s.substr(5, 2), 16); } else if (s.length === 4) { r = parseInt(s[1] + s[1], 16); g = parseInt(s[2] + s[2], 16); b = parseInt(s[3] + s[3], 16); } else { console.warn('Invalid hex color:', cssString); return this; } return this.setRGB(r, g, b); } // rgb() or rgba() var rgbMatch = s.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/); if (rgbMatch) { var r = parseInt(rgbMatch[1], 10); var g = parseInt(rgbMatch[2], 10); var b = parseInt(rgbMatch[3], 10); return this.setRGB(r, g, b); } // Named color var namedColor = AcCmColorUtil.getColorByName(cssString); if (namedColor !== undefined) { return this.setRGBValue(namedColor); } console.warn('Unknown CSS color string:', cssString); return this; }; /** * Sets the color as a scalar grayscale value. * * @param scalar Scalar value (0–255) * @returns The current instance for chaining */ AcCmColor.prototype.setScalar = function (scalar) { return this.setRGB(scalar, scalar, scalar); }; Object.defineProperty(AcCmColor.prototype, "hexColor", { /** * Gets the hexadecimal representation of the color (e.g., "0xFF00FF"). */ get: function () { var rgb = this.RGB; if (rgb == null) return undefined; // Convert to hex and ensure always 6 digits var hex = rgb.toString(16).padStart(6, '0').toUpperCase(); return '0x' + hex; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "cssColor", { /** * Gets the CSS RGB color string (e.g., "rgb(255,0,255)"). */ get: function () { var rgb = this.RGB; if (rgb == null) return undefined; return "rgb(".concat((rgb >> 16) & 0xff, ",").concat((rgb >> 8) & 0xff, ",").concat(rgb & 0xff, ")"); }, enumerable: false, configurable: true }); /** * Returns a CSS rgba() color string with the specified alpha value. * @param alpha - Opacity value between 0 (transparent) and 1 (opaque) */ AcCmColor.prototype.cssColorAlpha = function (alpha) { var rgb = this.RGB; if (rgb == null) return undefined; return "rgba(".concat((rgb >> 16) & 0xff, ",").concat((rgb >> 8) & 0xff, ",").concat(rgb & 0xff, ",").concat(alpha, ")"); }; Object.defineProperty(AcCmColor.prototype, "colorIndex", { // --------------------------------------------------------------------- // ACI accessors (ByACI) // --------------------------------------------------------------------- /** Gets the AutoCAD Color Index (ACI), or undefined if not ByACI, ByBlock, or ByLayer. */ get: function () { if (this._colorMethod === AcCmColorMethod.ByACI) return this._value; else if (this._colorMethod === AcCmColorMethod.ByLayer) return 256; else if (this._colorMethod === AcCmColorMethod.ByBlock) return 0; else return undefined; }, /** * Sets the AutoCAD Color Index (0–256). * * - 0 sets the color method to `ByBlock` * - 256 sets the color method to `ByLayer` * - 1–255 sets the color method to `ByACI` * * @param index ACI index */ set: function (index) { if (index == null) return; var clamped = Math.max(0, Math.min(256, Math.round(index))); if (clamped === 0) { this._colorMethod = AcCmColorMethod.ByBlock; this._value = undefined; } else if (clamped === 256) { this._colorMethod = AcCmColorMethod.ByLayer; this._value = undefined; } else { this._colorMethod = AcCmColorMethod.ByACI; this._value = clamped; } }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "isByColor", { /** * Returns true if the color method is ByColor (explicit RGB). */ get: function () { return this._colorMethod === AcCmColorMethod.ByColor; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "isByACI", { /** * Returns true if the color method is ByACI. */ get: function () { return this._colorMethod === AcCmColorMethod.ByACI; }, enumerable: false, configurable: true }); Object.defineProperty(AcCmColor.prototype, "isForeground", { /** * Returns true if the color method is ByACI and ACI value is 7 * * Notes: * In AutoCAD, ACI Color 7 (Color Index 7) is officially named "Black" or "White" depending on * the context, but it is functionally defined as the "Contrasting Color" or "Auto-Contrast Color." * Here is the technical explanation of its behavior: * - If the background is dark: Color 7 displays as White. * - If the background is light: Color 7 displays as Black. */ get: function () { return this._colorMethod === AcCmColorMethod.ByACI && this._value === 7; }, enumerable: false, configurable: true }); /** * Sets the color to ACI value 7. */ AcCmColor.prototype.setForeground = function () { this._colorMethod = AcCmColorMethod.ByACI; this._value = 7; return this; }; Object.defineProperty(AcCmColor.prototype, "isByLayer", { // --------------------------------------------------------------------- // Layer / Block helpers // --------------------------------------------------------------------- /** Returns true if the color method is ByLayer. */ get: function () { return this._colorMethod === AcCmColorMethod.ByLayer; }, enumerable: false, configurable: true }); /** * Sets the color to ByLayer. * @param value - Option layer color value */ AcCmColor.prototype.setByLayer = function (value) { this._colorMethod = AcCmColorMethod.ByLayer; if (value == null) { this._value = 256; } else { this._value = value; } return this; }; Object.defineProperty(AcCmColor.prototype, "isByBlock", { /** Returns true if the color method is ByBlock. */ get: function () { return this._colorMethod === AcCmColorMethod.ByBlock; }, enumerable: false, configurable: true }); /** * Sets the color to ByBlock. * @param value - Option layer color value */ AcCmColor.prototype.setByBlock = function (value) { this._colorMethod = AcCmColorMethod.ByBlock; if (value == null) { this._value = 0; } else { this._value = value; } return this; }; Object.defineProperty(AcCmColor.prototype, "colorName", { // --------------------------------------------------------------------- // Color name (dynamic) // --------------------------------------------------------------------- /** * Gets the color name. * * For `ByColor` or `ByACI`, resolves the name via `AcCmColorUtil`. * For `ByLayer` or `ByBlock`, returns the corresponding string. */ get: function () { switch (this._colorMethod) { case AcCmColorMethod.ByLayer: return 'ByLayer'; case AcCmColorMethod.ByBlock: return 'ByBlock'; case AcCmColorMethod.ByColor: return this._value ? AcCmColorUtil.getNameByColor(this._value) : ''; case AcCmColorMethod.ByACI: return this._value ? AcCmColorUtil.getNameByIndex(this._value) : ''; default: return undefined; } }, /** * Sets the color by name. * * Resolves the name to an RGB value via `AcCmColorUtil`. * * @param name Color name */ set: function (name) { if (!name) return; var color = AcCmColorUtil.getColorByName(name); if (color !== undefined) { this._value = color; this._colorMethod = AcCmColorMethod.ByColor; } else { console.warn('Unknown color name:', name); } }, enumerable: false, configurable: true }); // --------------------------------------------------------------------- // Clone / Copy / Equals // --------------------------------------------------------------------- /** * Creates a clone of this color instance. * * @returns A new AcCmColor instance with the same method and value */ AcCmColor.prototype.clone = function () { var c = new AcCmColor(); c._colorMethod = this._colorMethod; c._value = this._value; return c; }; /** * Copies color values from another AcCmColor instance. * * @param other The source color * @returns The current instance */ AcCmColor.prototype.copy = function (other) { this._colorMethod = other._colorMethod; this._value = other._value; return this; }; /** * Checks equality with another color. * * @param other The color to compare * @returns True if color method and value are identical */ AcCmColor.prototype.equals = function (other) { return (this._colorMethod === other._colorMethod && this._value === other._value); }; // --------------------------------------------------------------------- // String representation // --------------------------------------------------------------------- /** * Returns a string representation of the color. * * - "None" for None colors * - "ByLayer" for ByLayer colors * - "ByBlock" for ByBlock colors * - One number for color index * - RGB format "RGB:R,G,B" for RGB colors */ AcCmColor.prototype.toString = function () { switch (this._colorMethod) { case AcCmColorMethod.None: return 'None'; case AcCmColorMethod.ByLayer: return 'ByLayer'; case AcCmColorMethod.ByBlock: return 'ByBlock'; case AcCmColorMethod.ByACI: // ACI index as number string: "30" return this._value !== undefined ? String(this._value) : ''; case AcCmColorMethod.ByColor: if (!this._value) return ''; return "RGB:".concat(this.red, ",").concat(this.green, ",").concat(this.blue); default: return ''; } }; /** * Creates one AcCmColor from one string */ AcCmColor.fromString = function (name) { if (!name) return undefined; var n = name.trim(); // ------------------------------------------------- // 1. None / ByLayer / ByBlock // ------------------------------------------------- if (/^none$/i.test(n)) { return new AcCmColor(AcCmColorMethod.None); } if (/^bylayer$/i.test(n)) { return new AcCmColor(AcCmColorMethod.ByLayer); } if (/^byblock$/i.test(n)) { return new AcCmColor(AcCmColorMethod.ByBlock); } // ------------------------------------------------- // 2. RGB with prefix: "RGB:255,0,0" (case-insensitive) // ------------------------------------------------- var rgbPrefixedMatch = n.match(/^rgb\s*:\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})$/i); if (rgbPrefixedMatch) { var r = Number(rgbPrefixedMatch[1]); var g = Number(rgbPrefixedMatch[2]); var b = Number(rgbPrefixedMatch[3]); var color = new AcCmColor(AcCmColorMethod.ByColor); color.setRGB(r, g, b); return color; } // ------------------------------------------------- // 3. RGB without prefix: "255,0,0" // ------------------------------------------------- if (/^\d{1,3},\d{1,3},\d{1,3}$/.test(n)) { var _a = __read(n.split(',').map(Number), 3), r = _a[0], g = _a[1], b = _a[2]; var color = new AcCmColor(AcCmColorMethod.ByColor); color.setRGB(r, g, b); return color; } // ------------------------------------------------- // 4. ACI index: "1" – "255" // ------------------------------------------------- if (/^\d+$/.test(n)) { var index = parseInt(n, 10); return new AcCmColor(AcCmColorMethod.ByACI, index); } // ------------------------------------------------- // 5. Color book entry: "Book$Name" (case-insensitive prefix) // ------------------------------------------------- if (/^book\$/i.test(n)) { // Preserve original name after "Book$" var bookName = n.substring(n.indexOf('$') + 1); // Let util decide how to resolve book colors var colorVal_1 = AcCmColorUtil.getColorByName(bookName); if (colorVal_1 != null) { return new AcCmColor(AcCmColorMethod.ByColor, colorVal_1); } console.warn('Unknown color book entry:', name); return undefined; } // ------------------------------------------------- // 6. Named colors // ------------------------------------------------- var colorVal = AcCmColorUtil.getColorByName(n); if (colorVal != null) { return new AcCmColor(AcCmColorMethod.ByColor, colorVal); } console.warn('Unknown color name:', name); return undefined; }; return AcCmColor; }()); export { AcCmColor }; //# sourceMappingURL=AcCmColor.js.map