Lugaru's Epsilon
Programmer's
Editor

Context:
Epsilon User's Manual and Reference
   Primitives and EEL Subroutines
      Buffer Primitives
         Changing Buffer Contents
         Moving Text Between Buffers
         Getting Text from a Buffer
         . . .
         Listing Buffers
      Display Primitives
         . . .
         Other Display Primitives
         Highlighted Regions
         Character Coloring
         Code Coloring Internals
         Colors
      File Primitives
         File Reading Primitives
         File Writing Primitives
         Line Translation Primitives
         . . .
         Tagging Internals
      . . .

Previous   Up    Next
Highlighted Regions  Primitives and EEL Subroutines   Code Coloring Internals


Epsilon User's Manual and Reference > Primitives and EEL Subroutines > Display Primitives >

Character Coloring

You can set the color of individual characters using the set_character_color( ) primitive. At first glance, this feature may seem similar to Epsilon's mechanism for defining highlighted regions. Both let you specify a range of characters and a color to display them with. But each has its own advantages.

Region highlighting can highlight the text in different ways: as a rectangle, expanded to entire lines, and so forth, while character coloring has no similar options. You can define a highlighted region that moves around with the point, the mark, or any other spot. Character coloring always remains with the characters.

But when there are many colored regions, using character coloring is much faster than creating a corresponding set of highlighted regions. If you define more than a few dozen highlighted regions, Epsilon's screen refreshes will begin to slow down. Character coloring, on the other hand, is designed to be very fast, even when there are thousands of colored areas. Character coloring is also easier to use for many tasks, since it doesn't require the programmer to allocate spots to delimit the ends of the colored region, or delete them when the region is no longer needed.

One more difference is the way you remove the coloring. For highlighted regions, you can turn off the coloring temporarily by calling modify_region( ), or eliminate the region entirely by calling remove_region( ). To do either of these, you must supply the region's handle, a value returned when the region was first created. On the other hand, to remove character coloring, you can simply set the desired range of characters to the special color -1. A program using character coloring doesn't need to store a series of handles to remove or modify the coloring.

Epsilon's code coloring functions are built on top of the character coloring primitives described in this section. See the next section for information on the higher-level functions that make code coloring work.

set_character_color(int pos1, int pos2, int color)

The set_character_color( ) primitive makes Epsilon display characters between pos1 and pos2 using the specified color class. Epsilon discards any previous color settings of characters in that range.

A color class of -1 means the text will be "uncolored". To display uncolored text, Epsilon uses the standard color class text. When a buffer is first created, every character is uncolored.

When you insert text in a buffer, it takes on the color of the character immediately after it, or in the case of the last character in the buffer, the character immediately before it. Characters inserted in an empty buffer are initially uncolored. Copying text from one buffer to another does not automatically transfer the color; Epsilon treats the new characters the same as any other inserted text. You can use the buf_xfer_colors( ) subroutine to copy text from one buffer to another and retain its coloring. See Moving Text Between Buffers.

Epsilon maintains the character colors set by this primitive independently of the highlighted regions created by add_region( ). The modify_region( ) primitive will never change what get_character_color( ) returns, and similarly the set_character_color( ) primitive never changes the attributes of a region you create with add_region( ). When Epsilon displays text, it combines information from both sources to determine the final color of each character.

When displaying a buffer, Epsilon uses the following procedure when determining which color class to use for a character:

  • Make a list of all old-style highlighted regions that contain the character, and the color classes used for each.

  • Add the character's color as set by set_character_color( ) to this list.

  • Remove color classes of -1 from the list.

Next, Epsilon chooses a color class from the list:

  • If the list of color classes is empty, use the text color class.

  • Otherwise, if the list contains the highlight color class, use that.

  • Otherwise, use the color class from the old-style highlighted region with the highest region number. If there are no old-style highlighted regions in the list, the list must contain only one color class, so use that.

  • Finally, if we wound up selecting the text color class, and the text_color variable isn't equal to color_class text, use the color class in the text_color variable instead of the color_class text.

Notice that when a region using the highlight color class overlaps another region, the highlight color class takes precedence.

buf_set_character_color(int buf, int from, int to, int color)

The buf_set_character_color( ) subroutine is a convenience function. It simply runs set_character_color( ) in the specified buffer buf, passing it the remaining parameters.

short get_character_color(int pos, ?int *startp, ?int *endp)

The get_character_color( ) primitive returns the color class for the character at the specified buffer position, as set by set_character_color( ), or -1 if the character is uncolored, and will be displayed using the window's default color class.

You can also use the primitive to determine the extent of a range of characters all in the same color. If the optional pointer parameters startp and endp are non-null, Epsilon fills in the locations they point to with buffer positions. These specify the largest region of the buffer containing characters the same color as the one at pos, and including pos. For example, if the buffer contains a five-character word that has been colored blue, the buffer is otherwise uncolored, and pos refers to the second character in the word, then Epsilon will set *startp to pos - 1 and *endp to pos + 4.

set_tagged_region(char *tag, int from, int to, short val)
short get_tagged_region(char *tag, int pos, ?int *from, int *to)

The character coloring primitives above are actually built from a more general facility that allows you to associate a set of attributes with a buffer range.

Each set of attributes consists of a tag (a unique string like "my-tag") and, for each character in the buffer, a number that represents the attribute. Each buffer has its own set of tags, and each tag has its own list of attributes, one for each character. (Epsilon stores the numbers in a way that's efficient when many adjacent characters have the same number, but nothing prevents each character from having a different attribute.)

The set_tagged_region( ) primitive sets the attribute of the characters in the range from to to, for the specified tag.

The get_tagged_region( ) primitive gets the attribute of the character at position pos in the buffer. If you provide pointers from and to, Epsilon will fill these in to indicate the largest range of characters adjacent to pos that have the same attribute as pos. Characters whose attributes have never been set for a given tag will have the attribute -1.

Epsilon's character color primitives set_character_color( ) and get_character_color( ) use a built-in tagged region with a tag name of "colors".



Previous   Up    Next
Highlighted Regions  Primitives and EEL Subroutines   Code Coloring Internals


Lugaru Copyright (C) 1984, 2012 Lugaru Software Ltd. All Rights Reserved.