Properties in DWG and DXF: transparency, lineweights, dimension variables
Converts transparency, lineweights and dimension style settings between the drawing's values and the whole-number or text forms DWG and DXF keep.
How the precision is kept
The formats set the resolution here: transparency is kept as one byte of opacity and lineweights as whole hundredths of a millimeter, so both are rounded with Math.round on the way out. Real-valued dimension variables pass as 64-bit numbers; whole-number variables are rounded to integers. A hatch's pattern origin is written as number text that reads back to the same 64-bit value.
Calculations under this policy
9 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
The percentage is clamped to 0 to 90 and rounded to one of 256 opacity steps, about 0.39 percent each. The unsigned shift is applied to the assembled word, not to a measured value.
dwg-props.js
lines 36 to 42
CadCraft 0.8.2
/** CadCraft's tr (absent / null by layer, 'ByBlock', 0–90 %) → DXF 440 word, or undefined (by layer). */
export function trWord(tr) {
if (tr === 'ByBlock') return 0x01000000;
if (!Number.isFinite(tr)) return undefined;
const alpha = Math.round(255 * (1 - Math.max(0, Math.min(90, tr)) / 100));
return (0x02000000 | alpha) >>> 0;
}
Opacity byte to transparency
64-bit
Converts the file's opacity byte back to a transparency percentage.
p = Math.round((1 − alpha ÷ 255) × 100); p ≤ 0 → none; capped at 90
The result is a whole percent. A whole percent written by trWord reads back the same: the alpha rounding moves it by at most 0.5 ÷ 2.55 = 0.2 percent, which rounds back. A fractional percent comes back as a whole number.
Reads a transparency word or record: by block, by layer or an opacity byte.
The word is split with unsigned shifts into its kind (top byte) and its opacity (low byte); these are bit fields, not measurements. The byte goes through pct.
dwg-props.js
lines 43 to 56
CadCraft 0.8.2
/** A DXF 440 word or a cc-dwg transparency ({ byLayer } | { byBlock } | { alpha 0–255 } | the raw word) → tr or undefined. */
export function trFrom(v) {
if (v === undefined || v === null || v === '') return undefined;
if (typeof v === 'object') {
if (v.byBlock) return 'ByBlock';
if (Number.isFinite(v.alpha)) return pct(v.alpha);
return undefined;
}
const w = Number(v) >>> 0;
const kind = w >>> 24;
if (kind === 1) return 'ByBlock';
if (kind === 2 || kind === 3) return pct(w & 0xff);
return undefined;
}
Dimension lineweight to hundredths
64-bit
Converts a dimension line or extension line weight in millimeters to the file's whole number.
Math.round(v × 100) for v ≥ 0; −1, −2, −3 kept as codes
Rounded to 0.01 mm because the variable is a whole number of hundredths. Anything that is not a finite number of at least 0 becomes −2 (by block).
dwg-props.js
line 161
CadCraft 0.8.2
const lw100 = (v) => (v === -1 || v === -2 || v === -3 ? v : Number.isFinite(v) && v >= 0 ? Math.round(v * 100) : -2);
Style value to a dimension variable
64-bit
Converts one dimension style setting to the value its variable holds in the file.
real: the number (0 when not finite); int: Math.round; bool: 1 or 0; lineweight: lw100; separator: 44 or 46
Real variables (sizes, scales, round-off, tolerances) are passed as the 64-bit number unchanged. Whole-number variables such as the decimal places are rounded with Math.round.
dwg-props.js
lines 163 to 174
CadCraft 0.8.2
/** One st value → its variable's value (number or string). */
function out1(kind, v, key) {
switch (kind) {
case 'real': return Number.isFinite(+v) ? +v : 0;
case 'int': return Math.round(+v || 0);
case 'bool': return v ? 1 : 0;
case 'color': return typeof v === 'string' ? nearestAci(v) : aci(v);
case 'lw': return lw100(v);
case 'sep': return String(v) === ',' ? 44 : 46;
default: return v;
}
}
Dimension variable to a style value
64-bit
Converts one variable read from a file to the dimension style setting.
real: parseFloat; int: Math.round(parseFloat); lineweight: x ÷ 100 for 0 ≤ x ≤ 211
parseFloat reads decimal text to the nearest 64-bit number and passes a number through unchanged. A value that is not finite is left out, so the style keeps its previous setting. Lineweights outside 0 to 211 hundredths are left out.
dwg-props.js
lines 175 to 191
CadCraft 0.8.2
/** A variable's value → the st value (checked), or undefined. */
function in1(kind, raw) {
const n = typeof raw === 'object' && raw !== null ? (raw.rgb !== undefined ? '#' + (raw.rgb & 0xffffff).toString(16).padStart(6, '0') : raw.index) : raw;
switch (kind) {
case 'real': { const x = parseFloat(n); return Number.isFinite(x) ? x : undefined; }
case 'int': { const x = Math.round(parseFloat(n)); return Number.isFinite(x) ? x : undefined; }
case 'bool': return parseFloat(n) ? true : n === true ? true : false;
case 'color': {
if (typeof n === 'string' && /^#[0-9a-f]{6}$/i.test(n)) return n.toLowerCase();
const x = Math.round(parseFloat(n));
return x === 256 ? null : x === 0 ? 0 : x >= 1 && x <= 255 ? x : undefined;
}
case 'lw': { const x = Math.round(parseFloat(n)); return x === -1 || x === -2 || x === -3 ? x : x >= 0 && x <= 211 ? x / 100 : undefined; }
case 'sep': return Math.round(parseFloat(n)) === 44 ? ',' : '.';
default: return undefined;
}
}
Tolerance mode and text gap
64-bit
Works out the tolerance mode (symmetric, deviation, limits, basic) and the text gap from the file's variables.
symmetric when |tp − tm| < 1e-12; gap < 0 → basic and gap = −gap
The symmetric test is absolute at 1e-12. A negative gap marks a basic dimension in the file; its sign is removed and the magnitude kept unchanged.
dwg-props.js
lines 269 to 286
CadCraft 0.8.2
function specials(get, st) {
const tih = get('DIMTIH'), toh = get('DIMTOH');
if (tih !== undefined || toh !== undefined) st.tih = !!+(tih ?? 0) && !!+(toh ?? tih ?? 0);
const p = get('DIMPOST');
if (p !== undefined) { const [pre, suf] = post(p); if (pre) st.pre = pre; else delete st.pre; if (suf) st.suf = suf; else delete st.suf; }
const ap = get('DIMAPOST');
if (ap !== undefined) { const [pre, suf] = post(ap); if (pre) st.apre = pre; else delete st.apre; if (suf) st.asuf = suf; else delete st.asuf; }
const tol = get('DIMTOL'), lim = get('DIMLIM');
if (tol !== undefined || lim !== undefined || st.gap < 0) {
if (+lim) st.tol = 'lim';
else if (+tol) st.tol = Math.abs((st.tp || 0) - (st.tm || 0)) < 1e-12 ? 'sym' : 'dev';
else if (st.gap < 0) st.tol = 'basic';
else if (tol !== undefined || lim !== undefined) delete st.tol;
}
if (st.gap < 0) st.gap = -st.gap;
const unit = get('DIMUNIT');
if (unit !== undefined && st.lunit === undefined) { const u = Math.round(+unit); st.lunit = u === 6 ? 4 : u === 7 ? 5 : u; }
}
Dimension style as file variables
64-bit
Every variable of a dimension style, by name, for a DIMSTYLE record.
basic tolerance: DIMGAP = −|gap|
Each setting goes through out1. For a basic dimension the gap is written negative, the way the format marks it; a gap of 0 is written as −0.625.
dwg-props.js
lines 197 to 209
CadCraft 0.8.2
/** The style's variables, by name (a DIMSTYLE record's vars; DXF codes through dstyleItems). Every key, so nothing falls back to another program's defaults. */
export function varsOf(st) {
const s = { ...DEF, ...(st || {}) };
const v = {};
for (const [key, name, , kind] of DIMVARS) v[name] = out1(kind, s[key], key);
v.DIMTIH = s.tih ? 1 : 0; v.DIMTOH = s.tih ? 1 : 0;
v.DIMPOST = postOf(s.pre, s.suf); v.DIMAPOST = postOf(s.apre, s.asuf);
v.DIMTOL = s.tol === 'sym' || s.tol === 'dev' ? 1 : 0; v.DIMLIM = s.tol === 'lim' ? 1 : 0;
if (s.tol === 'basic') v.DIMGAP = -Math.abs(v.DIMGAP || 0.625);
v.DIMSAH = (s.blk1 || '') !== (s.blk2 || '') ? 1 : 0;
if (!(st && st.lunit)) delete v.DIMLUNIT; // absent = decimal; the style's own stays
return v;
}
Hatch pattern origin as text
64-bit
Writes a hatch's pattern origin into the file as two numbers in a text field.
text = CCHORG: followed by x, a comma and y
The numbers are turned into text by string concatenation, which gives the shortest decimal that reads back to the same 64-bit value; propsFromXdata reads them with Number. The origin survives a save and open unchanged.
64-bit numbers; alpha 0 to 255; lineweights 0 to 211 hundredths of a millimeter.
Tolerances
A tolerance is symmetric when |upper − lower| < 1e-12 (absolute).
Limits
Transparency is held to a whole percent between 0 and 90. Lineweights are held to 0.01 mm.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.