Task 161: .DXF File Format
Task 161: .DXF File Format
File Format Specifications for the .DXF File Format
The .DXF (Drawing Exchange Format) is a CAD data file format developed by Autodesk to facilitate interoperability between AutoCAD and other applications. It supports both ASCII (text-based) and binary variants, though the ASCII version is more common. The format represents drawing data using tagged groups, where each group consists of an integer code followed by a value. The structure is organized into sections, each beginning with group code 0 and "SECTION", followed by group code 2 with the section name, and ending with 0 and "ENDSEC". Key sections include HEADER (drawing settings), CLASSES (application-defined classes), TABLES (symbol tables like layers and styles), BLOCKS (block definitions), ENTITIES (graphical objects), OBJECTS (non-graphical objects), THUMBNAILIMAGE (preview image, optional), and EOF (end of file marker).
Official specifications are documented in Autodesk's DXF Reference, available in versions corresponding to AutoCAD releases. For example, the AutoCAD 2012 DXF Reference PDF provides detailed group codes, entity types, and section structures. More recent versions, such as for AutoCAD 2025, are accessible via Autodesk's online developer help.
1. List of All Properties of the .DXF File Format Intrinsic to Its File System
Based on the specifications, the properties intrinsic to the .DXF format are the header variables stored in the HEADER section. These variables define drawing settings and are represented as system variables prefixed with "$". Each variable is associated with a group code and a value, capturing aspects such as version, units, dimensions, and display options. The following table lists all identified header variables, their associated group codes (where specified in references), and descriptions. Note that group codes may vary by context, but typical codes are provided for reference.
Variable Name | Group Code | Description |
---|---|---|
$ACADVER | 1 | The AutoCAD drawing database version number (e.g., AC1006 = R10, AC1009 = R11 and R12). |
$ANGBASE | 50 | Angle 0 direction. |
$ANGDIR | 70 | 1 = clockwise angles, 0 = counterclockwise. |
$ATTDIA | 70 | Attribute entry dialogs, 1 = on, 0 = off. |
$ATTMODE | 70 | Attribute visibility: 0 = none, 1 = normal, 2 = all. |
$ATTREQ | 70 | Attribute prompting during INSERT, 1 = on, 0 = off. |
$AUNITS | 70 | Units format for angles. |
$AUPREC | 70 | Units precision for angles. |
$AXISMODE | 70 | Axis on if nonzero (not functional in Release 12). |
$AXISUNIT | 10, 20 | Axis X and Y tick spacing (not functional in Release 12). |
$BLIPMODE | 70 | Blip mode on if nonzero. |
$CECOLOR | 62 | Entity color number; 0 = BYBLOCK, 256 = BYLAYER. |
$CELTYPE | 6 | Entity linetype name, or BYBLOCK or BYLAYER. |
$CHAMFERA | 40 | First chamfer distance. |
$CHAMFERB | 40 | Second chamfer distance. |
$CLAYER | 8 | Current layer name. |
$COORDS | 70 | 0 = static coordinate display, 1 = continuous update, 2 = “d<a” format. |
$DIMALT | 70 | Alternate unit dimensioning performed if nonzero. |
$DIMALTD | 70 | Alternate unit decimal places. |
$DIMALTF | 40 | Alternate unit scale factor. |
$DIMAPOST | 1 | Alternate dimensioning suffix. |
$DIMASO | 70 | 1 = create associative dimensioning, 0 = draw individual entities. |
$DIMASZ | 40 | Dimensioning arrow size. |
$DIMBLK | 1 | Arrow block name. |
$DIMBLK1 | 1 | First arrow block name. |
$DIMBLK2 | 1 | Second arrow block name. |
$DIMCEN | 40 | Size of center mark/lines. |
$DIMCLRD | 70 | Dimension line color, range is 0 = BYBLOCK, 256 = BYLAYER. |
$DIMCLRE | 70 | Dimension extension line color, range is 0 = BYBLOCK, 256 = BYLAYER. |
$DIMCLRT | 70 | Dimension text color, range is 0 = BYBLOCK, 256 = BYLAYER. |
$DIMDLE | 40 | Dimension line extension. |
$DIMDLI | 40 | Dimension line increment. |
$DIMEXE | 40 | Extension line extension. |
$DIMEXO | 40 | Extension line offset. |
$DIMGAP | 40 | Dimension line gap. |
$DIMLFAC | 40 | Linear measurements scale factor. |
$DIMLIM | 70 | Dimension limits generated if nonzero. |
$DIMPOST | 1 | General dimensioning suffix. |
$DIMRND | 40 | Rounding value for dimension distances. |
$DIMSAH | 70 | Use separate arrow blocks if nonzero. |
$DIMSCALE | 40 | Overall dimensioning scale factor. |
$DIMSE1 | 70 | First extension line suppressed if nonzero. |
$DIMSE2 | 70 | Second extension line suppressed if nonzero. |
$DIMSHO | 70 | 1 = Recompute dimensions while dragging, 0 = drag original image. |
$DIMSOXD | 70 | Suppress outside-extensions dimension lines if nonzero. |
$DIMSTYLE | 2 | Dimension style name. |
$DIMTAD | 70 | Text above dimension line if nonzero. |
$DIMTFAC | 40 | Dimension tolerance display scale factor. |
$DIMTIH | 70 | Text inside horizontal if nonzero. |
$DIMTIX | 70 | Force text inside extensions if nonzero. |
$DIMTM | 40 | Minus tolerance. |
$DIMTOFL | 70 | If text outside extensions, force line extensions between extensions if nonzero. |
$DIMTOH | 70 | Text outside horizontal if nonzero. |
$DIMTOL | 70 | Dimension tolerances generated if nonzero. |
$DIMTP | 40 | Plus tolerance. |
$DIMTSZ | 40 | Dimensioning tick size: 0 = no ticks. |
$DIMTVP | 40 | Text vertical position. |
This list is derived from established references and represents properties extractable from the file's HEADER section.
2. Two Direct Download Links for .DXF Files
- https://raw.githubusercontent.com/jscad/sample-files/master/dxf/dxf-parser/splines.dxf (Sample DXF file containing splines for testing).
- https://www.sample-videos.com/dxf/SampleDXF1.dxf (Sample DXF file for general testing purposes).
3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .DXF File Processing
The following is a standalone HTML page with embedded JavaScript that can be embedded in a Ghost blog post or used independently. It allows users to drag and drop a .DXF file, parses the HEADER section to extract the properties (header variables), and displays them on the screen in a structured list.
Drag and Drop .DXF File to View Header Properties
4. Python Class for .DXF File Handling
The following Python class can open a .DXF file, decode and read the header properties, print them to the console, and write the file (with optional modifications to properties).
import os
class DXFHandler:
def __init__(self, filepath):
self.filepath = filepath
self.properties = {}
self.content = None
def read(self):
with open(self.filepath, 'r') as f:
self.content = f.read()
lines = self.content.split('\n')
in_header = False
current_var = None
i = 0
while i < len(lines):
line = lines[i].strip()
if line == '0' and i+1 < len(lines) and lines[i+1].strip() == 'SECTION' and \
i+3 < len(lines) and lines[i+3].strip() == 'HEADER':
in_header = True
i += 4
continue
if in_header and line == '0' and i+1 < len(lines) and lines[i+1].strip() == 'ENDSEC':
break
if in_header and line == '9':
if i+1 < len(lines):
current_var = lines[i+1].strip()
i += 2
elif current_var:
if i < len(lines):
self.properties[current_var] = lines[i].strip()
current_var = None
i += 1
else:
i += 1
def print_properties(self):
if not self.properties:
print("No properties found. Call read() first.")
return
for key, value in self.properties.items():
print(f"{key}: {value}")
def write(self, output_path=None, modify=None):
if not self.content:
print("No content to write. Call read() first.")
return
if output_path is None:
output_path = self.filepath
content_lines = self.content.split('\n')
if modify:
for key, new_value in modify.items():
if key in self.properties:
self.properties[key] = new_value
# Update in content (simple replace for demo; full parser for production)
for i in range(len(content_lines)):
if content_lines[i].strip() == '9' and i+1 < len(content_lines) and content_lines[i+1].strip() == key:
# Next is code, then value
i += 2
if i+1 < len(content_lines):
content_lines[i+1] = str(new_value)
with open(output_path, 'w') as f:
f.write('\n'.join(content_lines))
# Example usage:
# handler = DXFHandler('sample.dxf')
# handler.read()
# handler.print_properties()
# handler.write('output.dxf', modify={'$ACADVER': 'AC1027'})
5. Java Class for .DXF File Handling
The following Java class can open a .DXF file, decode and read the header properties, print them to the console, and write the file (with optional modifications).
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class DXFHandler {
private String filepath;
private Map<String, String> properties = new HashMap<>();
private String content;
public DXFHandler(String filepath) {
this.filepath = filepath;
}
public void read() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(filepath));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
content = sb.toString();
reader.close();
String[] lines = content.split("\n");
boolean inHeader = false;
String currentVar = null;
for (int i = 0; i < lines.length; i++) {
String trimmed = lines[i].trim();
if (trimmed.equals("0") && i + 3 < lines.length && lines[i + 3].trim().equals("HEADER")) {
inHeader = true;
i += 3;
continue;
}
if (inHeader && trimmed.equals("0") && i + 1 < lines.length && lines[i + 1].trim().equals("ENDSEC")) {
break;
}
if (inHeader && trimmed.equals("9")) {
if (i + 1 < lines.length) {
currentVar = lines[i + 1].trim();
}
i++;
} else if (currentVar != null) {
if (i + 1 < lines.length) {
properties.put(currentVar, lines[i + 1].trim());
}
currentVar = null;
i++;
}
}
}
public void printProperties() {
if (properties.isEmpty()) {
System.out.println("No properties found. Call read() first.");
return;
}
for (Map.Entry<String, String> entry : properties.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
public void write(String outputPath, Map<String, String> modify) throws IOException {
if (content == null) {
System.out.println("No content to write. Call read() first.");
return;
}
if (outputPath == null) {
outputPath = filepath;
}
String[] lines = content.split("\n");
if (modify != null) {
for (Map.Entry<String, String> mod : modify.entrySet()) {
String key = mod.getKey();
String newValue = mod.getValue();
if (properties.containsKey(key)) {
properties.put(key, newValue);
for (int i = 0; i < lines.length; i++) {
if (lines[i].trim().equals("9") && i + 1 < lines.length && lines[i + 1].trim().equals(key)) {
i += 2;
if (i + 1 < lines.length) {
lines[i + 1] = newValue;
}
}
}
}
}
}
BufferedWriter writer = new BufferedWriter(new FileWriter(outputPath));
for (String l : lines) {
writer.write(l + "\n");
}
writer.close();
}
// Example usage:
// public static void main(String[] args) throws IOException {
// DXFHandler handler = new DXFHandler("sample.dxf");
// handler.read();
// handler.printProperties();
// Map<String, String> modify = new HashMap<>();
// modify.put("$ACADVER", "AC1027");
// handler.write("output.dxf", modify);
// }
}
6. JavaScript Class for .DXF File Handling
The following JavaScript class (Node.js compatible, requiring 'fs' module) can open a .DXF file, decode and read the header properties, print them to the console, and write the file (with optional modifications).
const fs = require('fs');
class DXFHandler {
constructor(filepath) {
this.filepath = filepath;
this.properties = {};
this.content = null;
}
read() {
this.content = fs.readFileSync(this.filepath, 'utf8');
const lines = this.content.split('\n').map(line => line.trim());
let inHeader = false;
let currentVar = null;
for (let i = 0; i < lines.length; i++) {
if (lines[i] === '0' && lines[i+1] === 'SECTION' && lines[i+3] === 'HEADER') {
inHeader = true;
i += 3;
continue;
}
if (inHeader && lines[i] === '0' && lines[i+1] === 'ENDSEC') {
break;
}
if (inHeader && lines[i] === '9') {
currentVar = lines[i+1];
i++;
} else if (currentVar) {
this.properties[currentVar] = lines[i+1] || 'undefined';
currentVar = null;
i++;
}
}
}
printProperties() {
if (Object.keys(this.properties).length === 0) {
console.log('No properties found. Call read() first.');
return;
}
for (const [key, value] of Object.entries(this.properties)) {
console.log(`${key}: ${value}`);
}
}
write(outputPath = null, modify = null) {
if (!this.content) {
console.log('No content to write. Call read() first.');
return;
}
if (!outputPath) {
outputPath = this.filepath;
}
let lines = this.content.split('\n');
if (modify) {
for (const [key, newValue] of Object.entries(modify)) {
if (key in this.properties) {
this.properties[key] = newValue;
for (let i = 0; i < lines.length; i++) {
if (lines[i].trim() === '9' && lines[i+1].trim() === key) {
i += 2;
if (i+1 < lines.length) {
lines[i+1] = newValue;
}
}
}
}
}
}
fs.writeFileSync(outputPath, lines.join('\n'));
}
}
// Example usage:
// const handler = new DXFHandler('sample.dxf');
// handler.read();
// handler.printProperties();
// handler.write('output.dxf', { '$ACADVER': 'AC1027' });
7. C++ Class for .DXF File Handling
The following C++ class can open a .DXF file, decode and read the header properties, print them to the console, and write the file (with optional modifications). Compile with a C++ compiler (e.g., g++).
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
class DXFHandler {
private:
std::string filepath;
std::map<std::string, std::string> properties;
std::string content;
public:
DXFHandler(const std::string& fp) : filepath(fp) {}
void read() {
std::ifstream file(filepath);
if (!file.is_open()) {
std::cerr << "Error opening file." << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {
content += line + "\n";
}
file.close();
std::vector<std::string> lines;
size_t pos = 0;
std::string token;
while ((pos = content.find("\n")) != std::string::npos) {
token = content.substr(0, pos);
lines.push_back(token.erase(token.find_last_not_of("\r\n") + 1));
content.erase(0, pos + 1);
}
bool inHeader = false;
std::string currentVar;
for (size_t i = 0; i < lines.size(); ++i) {
std::string trimmed = lines[i];
trimmed.erase(std::remove_if(trimmed.begin(), trimmed.end(), isspace), trimmed.end());
if (trimmed == "0" && i + 3 < lines.size() && lines[i + 3] == "HEADER") {
inHeader = true;
i += 3;
continue;
}
if (inHeader && trimmed == "0" && i + 1 < lines.size() && lines[i + 1] == "ENDSEC") {
break;
}
if (inHeader && trimmed == "9") {
if (i + 1 < lines.size()) {
currentVar = lines[i + 1];
currentVar.erase(std::remove_if(currentVar.begin(), currentVar.end(), isspace), currentVar.end());
}
++i;
} else if (!currentVar.empty()) {
if (i + 1 < lines.size()) {
std::string value = lines[i + 1];
value.erase(std::remove_if(value.begin(), value.end(), isspace), value.end());
properties[currentVar] = value;
}
currentVar.clear();
++i;
}
}
}
void printProperties() const {
if (properties.empty()) {
std::cout << "No properties found. Call read() first." << std::endl;
return;
}
for (const auto& pair : properties) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
}
void write(const std::string& outputPath = "", const std::map<std::string, std::string>& modify = {}) {
std::string out = outputPath.empty() ? filepath : outputPath;
if (content.empty()) {
std::cout << "No content to write. Call read() first." << std::endl;
return;
}
std::vector<std::string> lines;
std::string tempContent = content;
size_t pos;
while ((pos = tempContent.find("\n")) != std::string::npos) {
lines.push_back(tempContent.substr(0, pos));
tempContent.erase(0, pos + 1);
}
for (const auto& mod : modify) {
std::string key = mod.first;
std::string newValue = mod.second;
if (properties.find(key) != properties.end()) {
properties[key] = newValue;
for (size_t i = 0; i < lines.size(); ++i) {
std::string trimmed = lines[i];
trimmed.erase(std::remove_if(trimmed.begin(), trimmed.end(), isspace), trimmed.end());
if (trimmed == "9" && i + 1 < lines.size() && lines[i + 1] == key) {
i += 2;
if (i + 1 < lines.size()) {
lines[i + 1] = newValue;
}
}
}
}
}
std::ofstream outfile(out);
if (!outfile.is_open()) {
std::cerr << "Error writing file." << std::endl;
return;
}
for (const auto& l : lines) {
outfile << l << "\n";
}
outfile.close();
}
};
// Example usage:
// int main() {
// DXFHandler handler("sample.dxf");
// handler.read();
// handler.printProperties();
// std::map<std::string, std::string> modify = {{"$ACADVER", "AC1027"}};
// handler.write("output.dxf", modify);
// return 0;
// }