Colors in VectorWorks 2008+
A discussion on working with the new color palettes, by Charles
In previous versions of VectorWorks, there were a number of problems with colors:
- Specifying colors by RGB values was not reliable, because VW had only 256 colors, and would pick the closest match from the existing color palette, instead of using the specified RGB values.
- Specifying colors by index was not reliable if the user had edited the document color palette.
- There was no support for CMYK color definitions, which are necessary to get accurate printed colors.
- For more information on problems with colors in previous versions of VW, see Colours by Joel Sciamma.
To get past these problems, a new color system has been implemented in VW 2008.
To see a movie describing the user interface for this new system, see UnlimitedColorChoices.mov.
First, VW now supports an unlimited number of colors. These colors can be organized in an unlimited number of color palettes.
Second, color definitions are now CMYK-based. For any given set of RGB values, there are an indeterminate number of CMYK values that could produce the same color onscreen. The difference among these CMYK values is that they will all print a little bit differently, depending on the printer, and specifying colors by CMYK values is the only way to get printed colors to exactly match onscreen colors. On Windows, there is currently no way to specify colors by CMYK values, but this capability is present on the Macintosh. So some Mac users are going to start specifying colors by CMYK values, and they will expect their printed colors to match their onscreen colors. If the user defines the color using RGB controls, the best-guess CMYK color is stored, while if the (Mac) user defines the color using CMYK controls, those values will stick (not the RGB-to-CMYK best-guess values).
There are a number of implications to the VectorScript programmer when working with the new color system.
Note that you might not NEED to change your code. NNA did a lot of work to make sure that existing code, and existing objects, would migrate seamlessly into 2008. Creating colors by index values in the range of 0~255 will continue to work, producing the same (somewhat unreliable) results as it always has. You will note that in VW 2008, if you open a new blank document, there will only be two colors already defined in the document: black and white. Nevertheless, if you create an object and assign a color by index (such as "7" or "123"), you'll get the color that you would have gotten in previous releases. This color will be the factory default color for that index, if no color at that index exists.
After creating a color, by whatever means, if you get the RGB of that color, and then get the color index from the RGB (using RGBToColorIndex), you'll get an index that is in the range of 257~32767. This is true even if there are only two colors in the document. It is also true even if you set the color using an index in the range of 0~255. Regardless of how or when the color was created, the returned index will always be in the range of 257~32767. This means that if you are doing tests based on color indexes, you'll have to change your code. For example, if your code is counting all of the objects with a color index of "7", this code will no longer find anything, even if objects in the drawing were programmatically assigned that color index.
Color indexes for the same color will typically vary from one document to the next. For example, if you create an object, assign it a color, and then get the index value of that color, it might be "345". If you paste that object into another document and get the index of its color, it might be "456". This is because VW now creates color indexes on an as-needed basis, starting at 257. VW actually stores just the color index with the object, and then it stores the CMYK in the document's color table. When an existing object is pasted into a new document, VW will:
- Look up the CMYK values in the color table from the source document.
- See if those CMYK values already exist in the target document.
- If so, the object will be re-assigned the index of the existing color in the target document.
- If not, a new color will be created, using the CMYK values from the source document, and the new index will be re-assigned to the object.
So VW automatically migrates color information from the source document to the target document, changing the color indexes as needed to keep the colors the same.
But suppose you have a plug-in object that is capable of displaying a dialog in which the user selects the color for a sub-component of the PIO. In the OK event of that dialog, you use GetColorChoice to find the index of the selected color. Then you store that index in a PIO parameter. Then, in the reset event of the object, you read that color index from the parameter, and assign that color index to geometry and/or text created within the PIO. The problem in 2008 is that if this object is pasted into a different document, the stored color index will probably refer to a totally different color. While using color indexes in a cross-document environment was somewhat unreliable in the past, because the color palette might change from one document to the next, this is now very unreliable, because color indexes will probably change from one document to the next.
One solution for working with colors in any sort of cross-document environment is to stop storing color indexes, and start storing RGB values instead. RGB values work better in VW 2008, because VW no longer picks the closest color within the existing 256 colors in the document — it uses the exact RGB values that you specify.
The only problem with converting to RGB values is that you might lose the CMYK variation that the user might have specified.
There are no calls in VectorScript for getting or setting CMYK values. If you need to store color definitions in a text file, you have no choice but to store RGB values, and to lose any CMYK variation that the user may have specified.
But if you're just working with a plug-in object, as in the scenario described above, there is a way to store CMYK values and successfully retrieve them later. With a new pair of calls, it is possible to store color indexes in a special container associated with plug-in objects, and to retrieve them later, without any loss of CMYK information. Use SetCustomObjectColor to store color indexes, and GetCustomObjectColor to retrieve them during object regeneration.
FUNCTION SetCustomObjectColor(objectHand :HANDLE; inTagID, inColoIndex :INTEGER) :BOOLEAN;
- objectHand is the handle of the object to which you want to attach a color definition.
- inTagID specifies which slot you want to reference. If you need to store 5 different colors, you'll call SetCustomObjectColor 5 times, and increment inTagID to distinguish among them.
- inColoIndex is the index of the color that you want to store, in the range of 257~32767. This is the same index that you retrieve from a color control in a dialog, using GetColorChoice in the OK handler of your dialog.
Then, in your reset event, you use the complementary call:
FUNCTION GetCustomObjectColor(objectHand :HANDLE; inTagID :INTEGER; VAR outColorIndex :INTEGER) :BOOLEAN;
Here, outColorIndex is the color index that was stored previously in the slot specified by inTagID. You can then use this index to assign the color to entities that you are creating within your object.
So far, you're probably wondering what is the difference between this and just storing the index in one of your PIO parameters. The difference is that when an instance of a PIO is pasted into a new document, VW does not know to give any special treatment to any of your PIO parameters, and if you stored the number "456" in a parameter named "Trim Color", VW doesn't care. But VW does know that it has to give special treatment to numbers in the CustomObjectColor slots. So it will look up the CMYK values in the color table of the source document, and compare them to CMYK values in the target document. If it finds the same exact color in the target document, it will set the CustomObjectColor to that index, else it will create the color, and set the CustomObjectColor to the new index. When your reset code finally gets run at the end of the paste operation, the CustomObjectColor index no longer refers to a color in the source document's color table — it refers to a color in the target document — and it's the correct color, with the same exact CMYK. Hence the complete color description has been preserved.
You may not care about CMYK (you never had it before in VW), and you might not think that your users will care whether or not the colors print exactly as they appear on the screen. But it's hard to estimate what users care about and what they don't, and this mechanism is easy enough to use that it makes sense to use it, even if you don't think you need it. So this is the recommended mechanism for storing and retrieving color choices in PIOs.