Click here to Skip to main content
15,886,519 members
Articles / Desktop Programming / X11
Tip/Trick

Understand X11 graphics context functions by samples

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
22 Sep 2016CPOL2 min read 10.4K  
This tip shall help to select the desired GCFunction for fill operations.

Introduction

I always have to think over which X11 graphics context GCFunction is the right to coose and i almost every time choose the wrong one at the first try. This tip shall show the differences and help you to prevent wrong choose.

Background

The X11 graphics context supports 16 different functions to merge current drawing request (e. g. XFillRectangle()) - called the src - with window (widgets) current display - called the dst. These functions apply logical operations to the bit level of the color values of src and dst.

Here is one sample:

                src  01010101 01010101 01010101     55 55 55     gray
                dst  11110000 00000000 11110000     F0 00 FO     violet
OR operation result  11110101 01010101 11110101     F5 55 F5     light violet

See XGCValues structure description for details.

To demonstrate the different effects of the foreground color i have choosen a linear gradient rectangle and a 50% overlapping of a XFillRectangle() with three different shades of gray.


color="#141414"
XGCFunction=GXor

color="#555555"
XGCFunction=GXor

color="#BDBDBD"
XGCFunction=GXor

To demonstrate the different effects of the graphics context GCFunction i have choosen the same linear gradient rectangle as above and the sam 50% overlapping of a XFillRectangle() as above with always the same foreground color #555555.

First the OR graphics context GCFunctions:


XGCFunction=GXxor
src XOR dst
ID=06

XGCFunction=GXor
src OR dst
ID=07

XGCFunction=GXnor
(NOT src) AND (NOT dst)
ID=08

XGCFunction=GXorReverse
src OR (NOT dst)
ID=0B

XGCFunction=GXorInverted
(NOT src) OR dst
ID=0D

Second the AND and COPY graphics context GCFunctions:


XGCFunction=GXand
src AND dst
ID=01

XGCFunction=GXandReverse
src AND NOT dst
ID=02

XGCFunction=GXandInverted
(NOT src) AND dst
ID=04

XGCFunction=GXnand
(NOT src) OR (NOT dst)
ID=0E

XGCFunction=GXcopy
src
ID=03

XGCFunction=GXcopyInverted
NOT src
ID=0C

Finally the remaining graphics context GCFunctions:


XGCFunction=GXclear
0
ID=00

XGCFunction=GXnoop
dst
ID=05

XGCFunction=GXequiv
(NOT src) XOR dst
ID=09

XGCFunction=GXinvert
NOT dst
ID=0A

XGCFunction=GXset
1
ID=0F
 

This is the code i used for my samples:

C#
XSetForeground (display, gc, XAllocClosestNamedColor (display, colormap, "#555555"));
XSetFunction(display, gc, GXor);
XFillRectangle (display, drawable, gc, clipRectangle);
XSetFunction(display, gc, XGCFunction.GXcopy);

There is no way to brighten or to darken a dst with graphics context GCFunctions. To achieve this, it would require something like:

darken:   dst >> 1 or dst >> 2 or dst >> 3 or dst >> 4
brighten: (dst >> 2) OR #404040 or (dst >> 1) OR #808080 or (dst >> 2) OR #B0B0B0 or (dst >> 4) OR #F0F0F0

But shift operators are not avalable from graphics context GCFunctions.

Instead there are 2 approaches to brighten or to darken:

  1. Grab the dst as a pixmap, execute the appropriate operation and write back the result. This approach is slow (two pixmap transfers, calculation at the client) but has a smooth result.
  2. Overlay the dst with a stippled pixmap. This approach is fast (calculation at the server) but grainy.

I will give a closer look at approach 2:

stipple bits=(byte)0x22, (byte)0x88 …
brighten=25%
stipple bits= (byte)0x55, (byte)0xAA
brighten=50%
stipple bits= (byte)0x5A, (byte)0xA5
brighten=50%
stipple bits= (byte)0xEE, (byte)0xBB
brighten=75%

This is the code i used for my samples:

C#
// 25%
//static byte[] stippleBits = {(byte)0x22, (byte)0x88, (byte)0x22, (byte)0x88,
//                             (byte)0x22, (byte)0x88, (byte)0x22, (byte)0x88};
// 50%
// static byte[] stippleBits = {(byte)0x55, (byte)0xAA, (byte)0x55, (byte)0xAA,
//                              (byte)0x55, (byte)0xAA, (byte)0x55, (byte)0xAA};
// 75%
static byte[] stippleBits = {(byte)0xEE, (byte)0xBB, (byte)0xEE, (byte)0xBB,
                             (byte)0xEE, (byte)0xBB, (byte)0xEE, (byte)0xBB};

static System.IntPtr opacityTile = System.IntPtr.Zero;

...

if (opacityTile == System.IntPtr.Zero)
{
    opacityTile = XCreatePixmapFromBitmapData (display, drawable, stippleBits,
        8, 8, XAllocClosestNamedColor (display, colormap, "#FFFFFF"),
        XAllocClosestNamedColor (display, colormap, "#000000"), depth);
}

...

if (opacityTile != System.IntPtr.Zero)
{
    XSetFunction(display, gc, XGCFunction.GXor);
    XSetFillStyle  (display, gc, XGCFillStyle.FillTiled);
    XSetTile       (display, gc, opacityTile);
    XFillRectangle (display, drawable, gc, clipRectangle);
    XSetFunction(display, gc, XGCFunction.GXcopy);
}

The stipple bits (byte)0x55, (byte)0x55 ... produce a very flickering display. The next best choice is (byte)0x5A, (byte)0xA5 ...

Points of Interest

I have always been bothered by the fact that there is no illustrated description of the X11 graphics context GCFunction on the web. Now there is one...

History

The first version of this article is from 23. September 2016.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Celonis SA
Germany Germany
I am currently the CEO of Symbioworld GmbH and as such responsible for personnel management, information security, data protection and certifications. Furthermore, as a senior programmer, I am responsible for the automatic layout engine, the simulation (Activity Based Costing), the automatic creation of Word/RTF reports and the data transformation in complex migration projects.

The main focus of my work as a programmer is the development of Microsoft Azure Services using C# and Visual Studio.

Privately, I am interested in C++ and Linux in addition to C#. I like the approach of open source software and like to support OSS with own contributions.

Comments and Discussions

 
-- There are no messages in this forum --