Функция создает битовые карты из многоцветного изображения (xpm). Устанавливает контекст для каждой карты и рисует полигон используя каждый контекст по очереди.
| Код | void XFillPolygonByPixmap(Display *disp, Drawable d, GC gc, XPoint *polygon, int len, Pixmap pixmap, Pixmap mask) { const unsigned short MAX_PIXMAP_WHC = 50;
char data[MAX_PIXMAP_WHC*MAX_PIXMAP_WHC]; unsigned short indData = 0; unsigned short currColor = 0; char colorHex[6]; unsigned short ind; static signed short noneColor = -1; XpmImage xpmImage; // xpm color of line unsigned short indBuf = 0; unsigned char buf = 0; static Pixmap currBitmap[MAX_PIXMAP_WHC]; static Pixmap prevPixmap = NULL; static unsigned short indBitmap = 0; static unsigned long colorLong[MAX_PIXMAP_WHC]; static unsigned int ncolor = 0;
// Using tile if no mask in *.xpm if (!mask) { XSetFillStyle(disp, gc, FillTiled); XSetTile(disp, gc, pixmap); XFillPolygon(disp, d, gc, polygon, len, Complex, CoordModeOrigin); return; }
// Generate new data. Else - use previous if (pixmap != prevPixmap) { prevPixmap = pixmap; noneColor = -1; XpmCreateXpmImageFromPixmap(disp, pixmap, mask, &xpmImage, NULL); ncolor = xpmImage.ncolors;
// Take all colors for (ind = 0; ind < ncolor; ind++) { // for look and understand format of c_color use: // printf("%s\n", xpmImage.colorTable[ind].c_color); colorHex[0] = xpmImage.colorTable[ind].c_color[1]; colorHex[1] = xpmImage.colorTable[ind].c_color[2]; colorHex[2] = xpmImage.colorTable[ind].c_color[5]; colorHex[3] = xpmImage.colorTable[ind].c_color[6]; colorHex[4] = xpmImage.colorTable[ind].c_color[9]; colorHex[5] = xpmImage.colorTable[ind].c_color[10];
// Get index of None color in colorTable if (xpmImage.colorTable[ind].c_color[0] == 'N' && xpmImage.colorTable[ind].c_color[1] == 'o' && xpmImage.colorTable[ind].c_color[2] == 'n' && xpmImage.colorTable[ind].c_color[3] == 'e') noneColor = ind;
// Save all colors colorLong[ind] = strtol(colorHex, NULL, 16); }
for (ind = 0; ind < indBitmap; ind++) XFreePixmap(disp, currBitmap[ind]);
// Create bitmaps for each color for (currColor = 0, indBitmap = 0; currColor < ncolor; currColor++) { if (currColor == noneColor) continue;
// Filter all array on current color for (ind = 0, buf = 0, indBuf = 0, indData = 0; ind < xpmImage.width*xpmImage.height; ind++) { // If current pixel is equal current color - set high bit // else - bit is zero if (xpmImage.data[ind] == currColor) buf |= 0x80;
// if index is equal width - shift right on width-indBuf bits bool flagWidth = ((ind+1)%xpmImage.width == 0);
// If num of bits is 8 or flag is set, save data if (indBuf == 7 || flagWidth) { if (flagWidth) { while(indBuf < 7) { buf = buf >> 1; indBuf++; } } data[indData++] = buf; indBuf = 0; buf = 0; } else { indBuf++; buf = buf >> 1; } }
// Create bitmaps for each color currBitmap[indBitmap++] = XCreateBitmapFromData(disp, d, data, xpmImage.width, xpmImage.height); } }
// For each color set stipple by bitmap and fill polygon for (currColor = 0, ind = 0; currColor < ncolor, ind < indBitmap; currColor++) { if (currColor == noneColor) continue;
XSetFillStyle(disp, gc, FillStippled); XSetForeground(disp, gc, colorLong[currColor]); XSetStipple(disp, gc, currBitmap[ind++]); XFillPolygon(disp, d, gc, polygon, len, Complex, CoordModeOrigin); } return; }
|
|