iup-stack/iup/srccd/iup_cdutil.c

336 lines
9.1 KiB
C
Raw Normal View History

2023-02-20 16:44:45 +00:00
/** \file
* \brief cdiuputil. CD and IUP utilities for the IupControls
*
* See Copyright Notice in "iup.h"
*/
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>
#include <cd.h>
#include "iup.h"
#include "iup_attrib.h"
#include "iup_str.h"
#include "iup_drv.h"
#include "iup_image.h"
#include "iup_cdutil.h"
long cdIupConvertColor(const char *color)
{
unsigned char r, g, b;
if (iupStrToRGB(color, &r, &g, &b))
return cdEncodeColor(r, g, b);
else
return 0;
}
void cdIupCalcShadows(long bgcolor, long *light_shadow, long *mid_shadow, long *dark_shadow)
{
int r, bg_r = cdRed(bgcolor);
int g, bg_g = cdGreen(bgcolor);
int b, bg_b = cdBlue(bgcolor);
/* light_shadow */
int max = bg_r;
if (bg_g > max) max = bg_g;
if (bg_b > max) max = bg_b;
if (255-max < 64)
{
r = 255;
g = 255;
b = 255;
}
else
{
/* preserve some color information */
if (bg_r == max) r = 255;
else r = bg_r + (255-max);
if (bg_g == max) g = 255;
else g = bg_g + (255-max);
if (bg_b == max) b = 255;
else b = bg_b + (255-max);
}
if (light_shadow) *light_shadow = cdEncodeColor((unsigned char)r, (unsigned char)g, (unsigned char)b);
/* dark_shadow */
r = bg_r - 128;
g = bg_g - 128;
b = bg_b - 128;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
if (dark_shadow) *dark_shadow = cdEncodeColor((unsigned char)r, (unsigned char)g, (unsigned char)b);
/* mid_shadow = (dark_shadow+bgcolor)/2 */
if (mid_shadow) *mid_shadow = cdEncodeColor((unsigned char)((bg_r+r)/2), (unsigned char)((bg_g+g)/2), (unsigned char)((bg_b+b)/2));
}
void cdIupDrawSunkenRect(cdCanvas *canvas, int x1, int y1, int x2, int y2, long light_shadow, long mid_shadow, long dark_shadow)
{
cdCanvasForeground(canvas, mid_shadow);
cdCanvasLine(canvas, x1, y1+1, x1, y2);
cdCanvasLine(canvas, x1, y2, x2-1, y2);
cdCanvasForeground(canvas, dark_shadow);
cdCanvasLine(canvas, x1+1, y1+2, x1+1, y2-1);
cdCanvasLine(canvas, x1+1, y2-1, x2-2, y2-1);
cdCanvasForeground(canvas, light_shadow);
cdCanvasLine(canvas, x1, y1, x2, y1);
cdCanvasLine(canvas, x2, y1, x2, y2);
}
void cdIupDrawRaiseRect(cdCanvas *canvas, int x1, int y1, int x2, int y2, long light_shadow, long mid_shadow, long dark_shadow)
{
cdCanvasForeground(canvas, light_shadow);
cdCanvasLine(canvas, x1, y1+1, x1, y2);
cdCanvasLine(canvas, x1, y2, x2-1, y2);
cdCanvasForeground(canvas, dark_shadow);
cdCanvasLine(canvas, x1, y1, x2, y1);
cdCanvasLine(canvas, x2, y1, x2, y2);
cdCanvasForeground(canvas, mid_shadow);
cdCanvasLine(canvas, x1+1, y1+1, x2-1, y1+1);
cdCanvasLine(canvas, x2-1, y1+2, x2-1, y2-1);
}
void cdIupDrawVertSunkenMark(cdCanvas *canvas, int x, int y1, int y2, long light_shadow, long dark_shadow)
{
cdCanvasForeground(canvas, dark_shadow);
cdCanvasLine(canvas, x-1, y1, x-1, y2);
cdCanvasForeground(canvas, light_shadow);
cdCanvasLine(canvas, x, y1, x, y2);
}
void cdIupDrawHorizSunkenMark(cdCanvas *canvas, int x1, int x2, int y, long light_shadow, long dark_shadow)
{
cdCanvasForeground(canvas, dark_shadow);
cdCanvasLine(canvas, x1, y+1, x2, y+1);
cdCanvasForeground(canvas, light_shadow);
cdCanvasLine(canvas, x1, y, x2, y);
}
/************************************************************************/
static void iUtilInitPalette(Ihandle* image, long* palette, long bgcolor, int make_inactive)
{
int i;
unsigned char r, g, b, bg_r, bg_g, bg_b;
cdDecodeColor(bgcolor, &bg_r, &bg_g, &bg_b);
for(i = 0; i < 256; i++)
{
char* color = IupGetAttributeId(image, "", i);
r = bg_r; g = bg_g; b = bg_b;
iupStrToRGB(color, &r, &g, &b); /* no need to test for BGCOLOR, if this failed it will not set the parameters */
if (make_inactive)
iupImageColorMakeInactive(&r, &g, &b, bg_r, bg_g, bg_b);
palette[i] = cdEncodeColor(r, g, b);
}
}
static unsigned char* iUtilBuildImageBuffer(Ihandle *image, int width, int height, int depth, int make_inactive, long bgcolor)
{
int size, plane_size, i, j;
unsigned char bg_r, bg_g, bg_b;
unsigned char* image_buffer;
/* images from stock or resources are not supported */
unsigned char* data = (unsigned char*)IupGetAttribute(image, "WID");
if (!data)
return NULL;
plane_size = width*height;
size = plane_size*depth;
image_buffer = malloc(size);
if (!image_buffer)
return NULL;
cdDecodeColor(bgcolor, &bg_r, &bg_g, &bg_b);
/* IUP image is top-down, CD image is bottom up */
if (depth==1)
{
/* inactive will be set at the palette */
for (i=0; i<height; i++)
memcpy(image_buffer + i*width, data + (height-1 - i)*width, width);
}
else if (depth==3)
{
int pos;
unsigned char r, g, b;
unsigned char *dst_r = image_buffer + 0*plane_size;
unsigned char *dst_g = image_buffer + 1*plane_size;
unsigned char *dst_b = image_buffer + 2*plane_size;
for (i=0; i<height; i++)
{
int line_offset = i*width;
unsigned char *line_r = dst_r + line_offset;
unsigned char *line_g = dst_g + line_offset;
unsigned char *line_b = dst_b + line_offset;
unsigned char *src_rgb = data + (height-1 - i)*(3*width);
for (j=0; j<width; j++)
{
pos = j*3;
r = src_rgb[pos+0];
g = src_rgb[pos+1];
b = src_rgb[pos+2];
if (make_inactive)
iupImageColorMakeInactive(&r, &g, &b, bg_r, bg_g, bg_b);
line_r[j] = r;
line_g[j] = g;
line_b[j] = b;
}
}
}
else /* depth==4 */
{
int pos;
unsigned char r, g, b, a;
unsigned char *dst_r = image_buffer + 0*plane_size;
unsigned char *dst_g = image_buffer + 1*plane_size;
unsigned char *dst_b = image_buffer + 2*plane_size;
unsigned char *dst_a = image_buffer + 3*plane_size;
for (i=0; i<height; i++)
{
int line_offset = i*width;
unsigned char *line_r = dst_r + line_offset;
unsigned char *line_g = dst_g + line_offset;
unsigned char *line_b = dst_b + line_offset;
unsigned char *line_a = dst_a + line_offset;
unsigned char *src_rgba = data + (height-1 - i)*(4*width);
for (j=0; j<width; j++)
{
pos = j*4;
r = src_rgba[pos+0];
g = src_rgba[pos+1];
b = src_rgba[pos+2];
a = src_rgba[pos+3];
if (make_inactive)
iupImageColorMakeInactive(&r, &g, &b, bg_r, bg_g, bg_b);
line_r[j] = r;
line_g[j] = g;
line_b[j] = b;
line_a[j] = a;
}
}
}
return image_buffer;
}
void cdIupDrawImage(cdCanvas *canvas, Ihandle *image, int x, int y, int w, int h, int make_inactive, long bgcolor)
{
int plane_size, depth;
int width = IupGetInt(image, "WIDTH");
int height = IupGetInt(image, "HEIGHT");
int bpp = IupGetInt(image, "BPP");
unsigned char* image_buffer;
depth = 1;
if (bpp==24)
depth = 3;
else if (bpp==32)
depth = 4;
if (w == 0) w = width;
if (h == 0) h = height;
/* The buffer will be destroyed in IupImage unmap */
if (depth!=1 && make_inactive)
image_buffer = (unsigned char*)iupAttribGet(image, "_IUPIMAGE_BUFFER_INACTIVE");
else
image_buffer = (unsigned char*)iupAttribGet(image, "_IUPIMAGE_BUFFER");
if (!image_buffer)
{
image_buffer = iUtilBuildImageBuffer(image, width, height, depth, make_inactive, bgcolor);
if (depth!=1 && make_inactive)
iupAttribSet(image, "_IUPIMAGE_BUFFER_INACTIVE", (char*)image_buffer);
else
iupAttribSet(image, "_IUPIMAGE_BUFFER", (char*)image_buffer);
}
if (!image_buffer)
return;
plane_size = width*height;
if (depth==1)
{
long palette[256];
iUtilInitPalette(image, palette, bgcolor, make_inactive);
cdCanvasPutImageRectMap(canvas, width, height,
image_buffer, palette,
x, y, w, h, 0, 0, 0, 0);
}
else if (depth==3)
{
cdCanvasPutImageRectRGB(canvas, width, height,
image_buffer + 0*plane_size,
image_buffer + 1*plane_size,
image_buffer + 2*plane_size,
x, y, w, h, 0, 0, 0, 0);
}
else /* depth==4 */
{
cdCanvasPutImageRectRGBA(canvas, width, height,
image_buffer + 0*plane_size,
image_buffer + 1*plane_size,
image_buffer + 2*plane_size,
image_buffer + 3*plane_size,
x, y, w, h, 0, 0, 0, 0);
}
}
/************************************************************************/
void IupCdSetFont(Ihandle* ih, cdCanvas *canvas, const char* font)
{
char* lastfont = iupAttribGetStr(ih, "_IUPCD_LASTFONT");
if (!lastfont || !iupStrEqual(lastfont, font))
{
iupAttribSetStr(ih, "_IUPCD_LASTFONT", font);
cdCanvasNativeFont(canvas, font);
}
}
void cdIupDrawFocusRect(cdCanvas *canvas, int x1, int y1, int x2, int y2)
{
int style = cdCanvasLineStyle(canvas, CD_QUERY);
long foreground = cdCanvasForeground(canvas, CD_QUERY);
cdCanvasLineStyle(canvas, CD_DOTTED);
cdCanvasForeground(canvas, CD_BLACK);
cdCanvasRect(canvas, x1, x2, y1, y2);
cdCanvasLineStyle(canvas, style);
cdCanvasForeground(canvas, foreground);
}