This article was written to bring together scattered information about working with colors in the AutoCAD .NET API. It also covers some practical use cases beyond simply changing an entity’s color.
There are several types of colors in AutoCAD:
- Indexed (ACI) – specified using indices defined by AutoCAD’s internal color system. This includes the special colors "ByLayer" and "ByBlock".
- RGB – defined by three primary color components ranging from 0 to 255: red, green, and blue.
- Color book colors – essentially RGB colors that have been saved in a color book and assigned a name.
- Plot (pen) color – used during plotting and depends on the output device settings. This type of color will not be discussed in detail in this article.
In the .NET API, colors are represented by two similar classes:
- Color – describes the color itself and includes the ColorNameForDisplay property, which contains the localized name seen by the user. Instances of this class can be assigned to objects that inherit from Entity.
- EntityColor – describes the color applied to an object, along with additional metadata not directly related to the color itself, such as status flags. Objects of this class can only be retrieved from objects inheriting from Entity, or retrieved from a Color.
Both Color and EntityColor objects can determine whether a color is indexed, RGB, or a plot (pen) color. However, only the Color class can indicate whether a color comes from a color book. The following properties correspond to different color types:
- Indexed (ACI) – "IsByAci", as well as "IsByLayer" and "IsByBlock". These colors are set using the ColorIndex
- RGB – "IsByColor". Defined using the Red, Green, and Blue
- Plot (pen) colors – "IsByPen". Set using the PenIndex
- Color book colors – available only in the Color class: HasColorName and HasBookName. These are technically RGB colors, but have non-empty ColorName and BookName
The color type can also be determined using the ColorMethod enumeration, which is available in both Color and EntityColor.
Some additional details about indexed colors should be clarified. The index itself is represented as a short, but there are only 255 valid indexed colors. The values 0 and 256 correspond to "IsByBlock" and "IsByLayer", respectively. Any other invalid value will result in an error.
It’s important to note that for indexed colors, the Red, Green, and Blue properties are all set to zero. To retrieve the actual RGB values of an indexed color, you’ll need to perform some additional steps.
Retrieving RGB Values from an Indexed Color
To understand how to retrieve the RGB value from an indexed color, you first need to understand what TrueColor is.
TrueColor is a 24-bit RGB representation encoded within a 32-bit integer, where each color channel is allocated 8 bits. In the .NET API, you can obtain a TrueColor value from an EntityColor object in two ways:
- Via the TrueColor property;
- Using the static method EntityColor.LookUpRgb(byte index).
Regarding the second method, it should be noted that it accepts a color index as a parameter, but since the index is defined as a short, manual casting to byte is required.
This method returns the encoded RGB value. To decode it, the easiest approach is to use bitwise masks. Below is an example implementation of such decoding.
byte colorByte = (byte)color.ColorIndex;
int rgb = EntityColor.LookUpRgb(colorByte);
byte blue = (byte)(rgb & 0xffL);
byte green = (byte)((rgb & 0xff00L) >> 8);
byte red = (byte)(rgb >> 16);
Color Filters
Colors can be used to filter objects via DXF codes using the SelectionFilter. However, there are some nuances to consider:
There are three standard DXF codes related to colors:
- 62 – color index as a short integer, present on any object with "Color" and "EntityColor". It can have special values representing "ByBlock" (0) or "ByLayer" (256).
- 420 – number in TrueColor format, which carries meaningful information only when an RGB color is used.
- 430 – color name (if any) as a string.
Filtering can only be performed using the 62 code, but this may lead to situations where an RGB color shares the same index, resulting in incorrect filtering. To handle this, logical operators like "<OR OR>" can be used to filter by multiple conditions.
Code 430 can be used to distinguish color book colors, even if they exactly match one of the RGB colors used in the document.
It is also worth noting that the TrueColor value obtained from EntityColor.LookUpRgb or directly from EntityColor.TrueColor may return incorrect values for some colors. Therefore, you may need to encode RGB into TrueColor yourself. This can be done using bit shifting, assembling a hexadecimal string, or any other convenient method. Below is an example implementation of such encoding.
long redL = 15;
long greenL = 100;
long blueL = 26;
long trueColor = (redL << 16) | (greenL << 8) | blueL;