| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | |
| <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]"> | |
| <meta name="Author" content="James Moody"> | |
| <title>SWT Color Model</title> | |
| <!-- saved from url=(0063)http://www.eclipsecorner.org/community/articleHTMLTemplate.html --> | |
| <link rel="stylesheet" href="../../default_style.css"> | |
| </head> | |
| <body> | |
| <div align="right"> <font face="Times New Roman, Times, serif" size="2">Copyright | |
| © 2001 Object Technology International, Inc.</font> </div> | |
| <table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="100%" > | |
| <tr> | |
| <td ALIGN=LEFT VALIGN=TOP COLSPAN="2" BGCOLOR="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF"> Eclipse | |
| Corner Article</font></font></b></td> | |
| </tr> | |
| </table> | |
| <h1> | |
| <img SRC="Idea.jpg" height=86 width=120 align=CENTER></h1> | |
| <center> | |
| <h1> | |
| SWT Color Model</h1></center> | |
| <blockquote><b>Summary</b> | |
| <br>The combination of platforms, display devices and color depth makes | |
| providing an easy to use yet powerful and portable color model an interesting | |
| challenge. In this article we will examine the color management models | |
| of Windows® and X/Motif and then dig into the makings of the SWT color model | |
| and its implications for client code. | |
| <p><b>By James Moody & Carolyn MacLeod OTI</b> | |
| <br><font size=-1>April 24, 2001</font></blockquote> | |
| <hr width="100%"> | |
| <h2> | |
| <br> | |
| Background</h2> | |
| <div class="MsoNormal">Before diving into the SWT color model, lets examine | |
| the color management support provided by some of the target platforms.</div> | |
| <h3> | |
| Windows</h3> | |
| <p>Color management on Windows depends on the depth | |
| of the display, which can be either low-color (usually 8 bits per pixel | |
| or less) or high-color (typically 15 bits per pixel or higher). | |
| On low-color displays, the concept of a <i>Palette</i> is important. A | |
| palette is simply a logical grouping of colors. When a color is requested, | |
| the system can either put the color in the palette, or, if the palette | |
| is full, do a closest match of the colors in the palette to find a reasonable | |
| facsimile.</p> | |
| <p>Windows allows the user to define and use one palette per graphics | |
| context (GC), or to use the default system palette that is on the display. | |
| The advantage of defining your own palette is space: it is initialized | |
| as empty, and you have the entire capacity to fill with your own colors. | |
| On the other hand, the system palette undoubtedly already has many colors | |
| in it, especially if other applications are using it; the user may not | |
| be able to use the entire capacity for his or her own application. Using | |
| the system palette has its advantages, however. For one, it is easier to | |
| use: simply use your colors normally, and the system will take care of | |
| mapping them to the system palette. Secondly, switching between two applications | |
| that are both using the system palette will be smooth. Switching between | |
| two applications that use different palettes will result in a visible flash | |
| as Windows maps the appropriate palette and takes colors away from the | |
| application that no longer has control.</p> | |
| <p>On high-color displays, colors are effectively free: one can simply | |
| use RGB values without any regard to palettes or color availability. | |
| <h3> | |
| X/Motif</h3> | |
| <div class="MsoNormal">On X, the color model also depends on whether the | |
| display is palette-based or high-color. X has a palette-based system similar | |
| to that of Windows, using the term colormap instead of palette. The primary | |
| difference between Windows and X, however, is that colors on X must be | |
| allocated with <b>XAllocColor</b> prior to use, and freed with <b>XFreeColor</b> | |
| when no longer required. As well, switching between two applications that | |
| define their own palettes (private colormaps) on X results in all other | |
| applications having their colors altered in such a way that the switch | |
| is visibly more noticeable than on Windows. For this reason, most X applications | |
| do not define a private colormap, but rather share the default colormap. | |
| A limitation of X as compared to Windows is that it will not perform a | |
| closest-match if a color cannot be allocated, but will answer black instead. | |
| Thus if a closest match is desired, it must be performed by your code. | |
| <p class="MsoNormal">On high-color displays, where the pixel value encodes | |
| the RGB value of the color, colors are free as they are on Windows. Although | |
| the surest way to use colors on a high-color display is still to use <b>XAllocColor</b>, | |
| one can simply encode the RGB values into pixel values and use the pixels | |
| directly, without having to allocate or free the colors. | |
| <h2> | |
| Options</h2> | |
| <div class="MsoNormal">After taking into account the above platform features | |
| and limitations, a variety of options presented themselves as possible | |
| solutions to SWT's color management story. | |
| <br> </div> | |
| <div class="MsoNormal"><i>1) expose <code>Palette</code> as a class to the SWT | |
| user:</i></div> | |
| <div class="MsoNormal" style="margin-left:.5in">Both Windows and X support the | |
| notion of palettes on low-color displays. One option is to expose <code>Palette</code> | |
| as a class to the SWT user, and allow the <i>Palette</i> to be set into a | |
| <i>GC</i>. One problem with this approach is that X's palette solution is | |
| undesirable due to its flashy behavior. This approach maps better to Windows | |
| due to the platforms improved palette switching capabilities. On X, however, | |
| given the above limitation, SWT would want to give the illusion of palettes | |
| to the developer, while mapping colors to the default colormap underneath. | |
| Another problem is that of managing the palettes of multiple <i>GC</i>s in | |
| the same window; on Windows, the colors from these palettes would need to | |
| be somehow combined into a single palette when the window is given focus. | |
| Providing user palettes would also require SWT to implement a default palette, | |
| which would add complexity to the palette management code. <br> | |
| </div> | |
| <div class="MsoNormal"><i>2) support only high-color displays:</i></div> | |
| <div class="MsoNormal" style="margin-left:.5in">Windows and X make it very | |
| easy to use high-color displays, and more difficult to use low-color displays. | |
| Another option is simply to support only high-color displays, and make | |
| colors free from the SWT user's perspective, meaning they do not need to | |
| be allocated or disposed. The obvious disadvantage of this approach is | |
| that many low-color displays exist and would be excluded from running SWT-based | |
| applications. (Of course, over time the number of systems that still run | |
| in low-color mode is decreasing, but there are still a significant number | |
| of real-world applications that require this.) | |
| <br> </div> | |
| <div class="MsoNormal"><i>3) allocate a color cube:</i></div> | |
| <div class="MsoNormal" style="margin-left:.5in">A common approach to color | |
| management is to allocate a fixed range of diverse colors, called a <i>color | |
| cube</i>, when the application starts. All requested colors are mapped | |
| to the closest color in the cube. This approach could be used in SWT for | |
| low-color displays, making it very easy for the user to manage colors. | |
| The advantage of this approach is that it is very simple for the user; | |
| the disadvantage is that the user is constrained to a very limited set | |
| of colors defined in the color cube, and will never be able to get an exact | |
| match of the color he or she desires, unless it happens to be in the color | |
| cube. This approach would not be ideal for high-color displays. Colors | |
| in SWT would not be resources in this approach, and thus would not need | |
| to be freed; SWT would take care of allocating the cube on startup and | |
| freeing it on shutdown. | |
| <br> </div> | |
| <div class="MsoNormal"><i>4) allocate colors:</i></div> | |
| <div class="MsoNormal" style="margin-left:.5in">The last option is to make | |
| the user allocate and free colors as if they were platform resources. (i.e. | |
| create with a constructor and free with <b>dispose</b>). This maps well | |
| to X, where colors are a resource, but not well to Windows, where colors | |
| are not a resource. This option is discussed in detail in the next section.</div> | |
| <h2> | |
| The SWT Color Model</h2> | |
| <h3> | |
| Goals</h3> | |
| <div class="MsoNormal">After examining the platform behavior and possible | |
| solutions, the following three goals for SWT's color model were decided | |
| upon:</div> | |
| <ol start=1 type=1> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l0 level1 lfo3;tab-stops:list .5in"> | |
| SWT must support both palette-based and direct color devices (high-color | |
| displays). Palette-based devices are usually those containing 8 bits per | |
| pixel or less, while direct color devices are typically 15 bits per pixel | |
| and higher. In palette-based devices, the OS maintains a mapping of RGB | |
| values to pixel values, while in direct color devices the RGB values are | |
| encoded into the pixel value.</li> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l0 level1 lfo3;tab-stops:list .5in"> | |
| The model must be portable. The color model supported by Windows, for example, | |
| is fundamentally different than the model supported by X. The SWT model | |
| must accommodate those differences in a way that is transparent to the | |
| SWT user.</li> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l0 level1 lfo3;tab-stops:list .5in"> | |
| It is important that, under normal circumstances, the user be given exactly | |
| the color that was requested. Any scheme that limits the available colors | |
| to those contained in a small, pre-allocated palette will fail to offer | |
| the user exact colors.</li> | |
| </ol> | |
| <div class="MsoNormal"> | |
| <h3> | |
| Decisions</h3> | |
| Our requirement of supporting palette-based displays rules out the second | |
| of the above options (support only high-color displays). The requirement | |
| to provide exact colors upon request means that allocating a color-cube | |
| and matching all requests to that cube (the third option allocate a | |
| color cube) is also not acceptable. | |
| <p>Providing the user with palettes that they can manage (as described in | |
| the first option expose palette as a class) sounds like a good solution, | |
| but in practice, it makes client code very complex and hard to manage. Given | |
| the simple color requirements of typical applications, this option was ruled | |
| out. | |
| <p>Thus, the only remaining option (the last one listed above), allocating | |
| and disposing of colors independently, forms the basis of SWT's color model. | |
| </div> | |
| <h3> | |
| Palette Per Display using Allocate & Dispose</h3> | |
| On palette-based displays under Windows, SWT creates and manages one palette | |
| per <i>Display</i>. Colors used in a <i>GC</i> are taken from this palette. | |
| When the user allocates a <i>Color</i>, SWT checks if the palette is full. | |
| If it is not, the color is added to the palette and the user will get the | |
| exact color requested. If it is, the <i>Color</i> is allocated to be the | |
| closest match in the palette. In both cases, the reference count for that | |
| color is incremented. When a <i>Color</i> is disposed on Windows, SWT decrements | |
| the reference count. When the reference count reaches zero, SWT will remove | |
| the color from the palette. As with other SWT resources, clients must allocate | |
| colors, and free them only when the color is no longer needed. | |
| <p>On palette-based displays under X, SWT does not create a private colormap | |
| (palette), but instead uses the default colormap to avoid flashing and | |
| undesirable behavior. When the user allocates a <i>Color</i>, SWT tries | |
| to allocate the color with <b>XAllocColor</b>. If this succeeds, the user | |
| gets exactly the color they asked for, and that color is remembered by | |
| the <i>Display</i>. If it does not succeed, SWT finds the closest available | |
| color and uses that instead. In both cases, the reference count for that | |
| <i>Color</i> | |
| is incremented. | |
| <p>When a <i>Color</i> is disposed on X, SWT will call <b>XFreeColor</b>, | |
| which decrements the reference count on the X Server. As well, SWT will | |
| decrement its internal reference count for that <i>Color</i>, and remove | |
| it from the <i>Display</i> if the reference count is zero. | |
| <p>On high-color displays on both Windows and X, the SWT display does not maintain | |
| a palette. <i>Color</i>s are still allocated and freed on X, but this operation | |
| simply calculates the pixel value and nothing else. On 24-bit and higher displays, | |
| the user is guaranteed to get exactly the color requested. On 16-bit displays, | |
| the user will get a very close approximation, but not necessarily the exact | |
| color, due to the fact that 16-bit pixel values cannot encode 8-bit red, green | |
| and blue values with 100% accuracy. Low-color displays that use a lot of colors | |
| may still flash. | |
| <h3> | |
| Standard Colors</h3> | |
| <p>SWT provides access to the standard colors through Display.getSystemColor(int). | |
| The following snipet returns the standard color for green.</p> | |
| <pre> display.getSystemColor(SWT.COLOR_GREEN)</pre> | |
| <p>The creator of an SWT Color is responsible for disposing of | |
| the color when it is no longer required. In the above snipet we did not actually | |
| create the color, consequently we must <b>not</b> dispose of the color. </p> | |
| <h3> | |
| Image Loading</h3> | |
| <p>When an SWT image is loaded, code similar to the following is usually used:</p> | |
| <pre> Image image = new Image(display, "filename");</pre> | |
| <p>Image loading is actually a two-step process. In the first | |
| step, SWT loads the image into a device-independent, format-independent | |
| object, called | |
| <i>ImageData</i>. The second step involves creating the | |
| actual device-dependent | |
| <i>Image</i> from the <i>ImageData</i>. Before | |
| this can happen, the colors that the image desires must be mapped to colors | |
| that are actually available on the device. On a true-color display (high-color | |
| display with at least 24-bit color), the colors are always available. | |
| <p>On a low-color display the RGB values contained in the <i>ImageData</i>'s | |
| palette are mapped to the closest match available in the SWT palette. The | |
| colors that are available depend on which colors the user has already allocated. | |
| If the user has not allocated many colors, then there may not be many colors | |
| in the SWT palette for SWT to do a closest match to. SWT does not allocate | |
| application colors. For this reason, it may be desirable to pre-allocate the | |
| colors needed for the image. In the example above, however, there is no place | |
| to allocate the colors; the user doesn't know what colors the image needs | |
| before it is created. In situations like these, code such as the following | |
| may be useful:</p> | |
| <pre> ImageDate imageData = new ImageData("filename"); | |
| rgbs = imageData.getRGBs(); | |
| colors = new Color[rgbs.length]; | |
| for (int i = 0; i < colors.length; i++) { | |
| colors[i] = new Color(display, rgbs[i]); | |
| } | |
| image = new Image(display, imageData); | |
| ... | |
| // dispose the image and colors when no longer needed | |
| </pre> | |
| <p>In this example, the two-step process is revealed to the user, giving | |
| an opportunity to construct colors before the image is created, resulting | |
| in a more realistic image. In practice, this is not needed, since most | |
| displays are high-color. | |
| <p>The way SWT does image loading presents one possible difficulty. What if | |
| the user allocates some colors, loads an image, and subsequently frees some | |
| colors? There is a possibility that the image has chosen some of the colors | |
| that the user freed. In this case, unpredictable results can occur after the | |
| colors have been freed. Fortunately, this is very easy to work around: always | |
| allocate your colors in a static fashion, and free them when you are finished | |
| with them. This model is described in the section "Tips for Color Management | |
| in SWT". | |
| <h2> | |
| Tips for Color Management in SWT</h2> | |
| <div class="MsoNormal">Color management in SWT is very simple from the | |
| user's perspective. There are 3 basic rules to help you manage your application's | |
| color needs:</div> | |
| <ol start=1 type=1> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l1 level1 lfo6;tab-stops:list .5in"> | |
| Colors contain OS resources that must be allocated and freed. For this | |
| reason, it is necessary to <b>dispose</b> every color that you have created.</li> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l1 level1 lfo6;tab-stops:list .5in"> | |
| On high-color displays (16 bpp and higher), every <i>Color</i> allocation | |
| is guaranteed to succeed. On low-color displays (8 bpp and lower), you | |
| will either receive a <i>Color</i> with the exact RGB values that you asked | |
| for or a reasonable facsimile (in other words, the closest match that could | |
| be made). In this case, if you query the new <i>Color</i>, it will report | |
| the actual RGB values, which are not necessarily the RGB values that you | |
| asked for.</li> | |
| <li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l1 level1 lfo6;tab-stops:list .5in"> The envisioned usage of the | |
| color model in SWT is fairly typical among plug-ins: a certain number of | |
| fixed colors are decided upon for usage in the plug-in. The user allocates | |
| these colors on plug-in startup, by creating <i>Color</i> objects. The plug-in | |
| runs, and on shutdown, the user will call the <b>dispose</b> method for | |
| these colors. This leads to a solution with minimal hassles in terms of | |
| palettes being full and other color contention problems associated with | |
| dynamically allocating and freeing colors while the plug-in is running.</li> | |
| </ol> | |
| <h2 class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l1 level1 lfo6;tab-stops:list .5in"> | |
| Summary</h2> | |
| <div class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto; | |
| mso-list:l1 level1 lfo6;tab-stops:list .5in">We | |
| have seen that SWT's portable color model supports a color palette per | |
| display. Clients of SWT must explicitly create their color resources and | |
| dispose of them when they are no longer required. SWT also provides access | |
| to standard colors through Display.getSystemColor(int).</div> | |
| </div> | |
| <p><small>Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both.</small></p> | |
| </body> | |
| </html> |