📄 grx11.c
字号:
/*******************************************************************
*
* grx11.c graphics driver for X11.
*
* This is the driver for displaying inside a window under X11,
* used by the graphics utility of the FreeType test suite.
*
* Copyright 1999-2000, 2001, 2002, 2005 by Antoine Leca, David Turner
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
******************************************************************/
#ifdef __VMS
#include <vms_x_fix.h>
#endif
#include <grobjs.h>
#include <grdevice.h>
#define TEST
#ifdef TEST
#include "grfont.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#if defined( __cplusplus ) || defined( c_plusplus )
#define Class c_class
#else
#define Class class
#endif
/* old trick to determine 32-bit integer type */
#include <limits.h>
/* The number of bytes in an `int' type. */
#if UINT_MAX == 0xFFFFFFFFUL
#define GR_SIZEOF_INT 4
#elif UINT_MAX == 0xFFFFU
#define GR_SIZEOF_INT 2
#elif UINT_MAX > 0xFFFFFFFFU && UINT_MAX == 0xFFFFFFFFFFFFFFFFU
#define GR_SIZEOF_INT 8
#else
#error "Unsupported number of bytes in `int' type!"
#endif
/* The number of bytes in a `long' type. */
#if ULONG_MAX == 0xFFFFFFFFUL
#define GR_SIZEOF_LONG 4
#elif ULONG_MAX > 0xFFFFFFFFU && ULONG_MAX == 0xFFFFFFFFFFFFFFFFU
#define GR_SIZEOF_LONG 8
#else
#error "Unsupported number of bytes in `long' type!"
#endif
#if GR_SIZEOF_INT == 4
typedef int int32;
typedef unsigned int uint32;
#elif GR_SIZEOF_LONG == 4
typedef long int32;
typedef unsigned long uint32;
#else
#error "could not find a 32-bit integer type"
#endif
typedef struct Translator
{
KeySym xkey;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ XK_BackSpace, grKeyBackSpace },
{ XK_Tab, grKeyTab },
{ XK_Return, grKeyReturn },
{ XK_Escape, grKeyEsc },
{ XK_Home, grKeyHome },
{ XK_Left, grKeyLeft },
{ XK_Up, grKeyUp },
{ XK_Right, grKeyRight },
{ XK_Down, grKeyDown },
{ XK_Page_Up, grKeyPageUp },
{ XK_Page_Down, grKeyPageDown },
{ XK_End, grKeyEnd },
{ XK_Begin, grKeyHome },
{ XK_F1, grKeyF1 },
{ XK_F2, grKeyF2 },
{ XK_F3, grKeyF3 },
{ XK_F4, grKeyF4 },
{ XK_F5, grKeyF5 },
{ XK_F6, grKeyF6 },
{ XK_F7, grKeyF7 },
{ XK_F8, grKeyF8 },
{ XK_F9, grKeyF9 },
{ XK_F10, grKeyF10 },
{ XK_F11, grKeyF11 },
{ XK_F12, grKeyF12 }
};
typedef XPixmapFormatValues XDepth;
#ifdef TEST
#define grAlloc malloc
#endif
/************************************************************************/
/************************************************************************/
/***** *****/
/***** PIXEL BLITTING SUPPORT *****/
/***** *****/
/************************************************************************/
/************************************************************************/
typedef struct grX11Blitter_
{
unsigned char* src_line;
int src_pitch;
unsigned char* dst_line;
int dst_pitch;
int x;
int y;
int width;
int height;
} grX11Blitter;
/* setup blitter; returns 1 if no drawing happens */
static int
gr_x11_blitter_reset( grX11Blitter* blit,
grBitmap* source,
grBitmap* target,
int x,
int y,
int width,
int height )
{
long pitch;
int delta;
/* clip rectangle to source bitmap */
if ( x < 0 )
{
width += x;
x = 0;
}
delta = x + width - source->width;
if ( delta > 0 )
width -= delta;
if ( y < 0 )
{
height += y;
y = 0;
}
delta = y + height - source->rows;
if ( delta > 0 )
height -= delta;
/* clip rectangle to target bitmap */
delta = x + width - target->width;
if ( delta > 0 )
width -= delta;
delta = y + height - target->rows;
if ( delta > 0 )
height -= delta;
if ( width <= 0 || height <= 0 )
return 1;
/* now, setup the blitter */
pitch = blit->src_pitch = source->pitch;
blit->src_line = source->buffer + y * pitch;
if ( pitch < 0 )
blit->src_line -= ( source->rows - 1 ) * pitch;
pitch = blit->dst_pitch = target->pitch;
blit->dst_line = target->buffer + y * pitch;
if ( pitch < 0 )
blit->dst_line -= ( target->rows - 1 ) * pitch;
blit->x = x;
blit->y = y;
blit->width = width;
blit->height = height;
return 0;
}
typedef void (*grX11ConvertFunc)( grX11Blitter* blit );
typedef struct grX11FormatRec_
{
int x_depth;
int x_bits_per_pixel;
unsigned long x_red_mask;
unsigned long x_green_mask;
unsigned long x_blue_mask;
grX11ConvertFunc rgb_convert;
grX11ConvertFunc gray_convert;
} grX11Format;
/************************************************************************/
/************************************************************************/
/***** *****/
/***** BLITTING ROUTINES FOR RGB565 *****/
/***** *****/
/************************************************************************/
/************************************************************************/
static void
gr_x11_convert_rgb_to_rgb565( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x * 3;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read += 3, write++ )
{
unsigned int r = read[0];
unsigned int g = read[1];
unsigned int b = read[2];
write[0] = (unsigned short)( ( ( r << 8 ) & 0xF800U ) |
( ( g << 3 ) & 0x07E0 ) |
( ( b >> 3 ) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static void
gr_x11_convert_gray_to_rgb565( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read++, write++ )
{
unsigned int p = read[0];
write[0] = (unsigned short)( ( ( p << 8 ) & 0xF800U ) |
( ( p << 3 ) & 0x07E0 ) |
( ( p >> 3 ) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static const grX11Format gr_x11_format_rgb565 =
{
16, 16, 0xF800U, 0x07E0, 0x001F,
gr_x11_convert_rgb_to_rgb565,
gr_x11_convert_gray_to_rgb565
};
/************************************************************************/
/************************************************************************/
/***** *****/
/***** BLITTING ROUTINES FOR BGR565 *****/
/***** *****/
/************************************************************************/
/************************************************************************/
static void
gr_x11_convert_rgb_to_bgr565( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x * 3;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read += 3, write++ )
{
unsigned int r = read[0];
unsigned int g = read[1];
unsigned int b = read[2];
write[0] = (unsigned short)( ( ( b << 8 ) & 0xF800U ) |
( ( g << 3 ) & 0x07E0 ) |
( ( r >> 3 ) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static const grX11Format gr_x11_format_bgr565 =
{
16, 16, 0x001F, 0x7E00, 0xF800U,
gr_x11_convert_rgb_to_bgr565,
gr_x11_convert_gray_to_rgb565 /* the same for bgr565! */
};
/************************************************************************/
/************************************************************************/
/***** *****/
/***** BLITTING ROUTINES FOR RGB555 *****/
/***** *****/
/************************************************************************/
/************************************************************************/
static void
gr_x11_convert_rgb_to_rgb555( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x * 3;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read += 3, write++ )
{
unsigned int r = read[0];
unsigned int g = read[1];
unsigned int b = read[2];
write[0] = (unsigned short)( ( ( r << 7 ) & 0x7C00 ) |
( ( g << 2 ) & 0x03E0 ) |
( ( b >> 3 ) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static void
gr_x11_convert_gray_to_rgb555( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read++, write++ )
{
unsigned int p = read[0];
write[0] = (unsigned short)( ( ( p << 7 ) & 0x7C00 ) |
( ( p << 2 ) & 0x03E0 ) |
( ( p >> 3 ) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static const grX11Format gr_x11_format_rgb555 =
{
15, 16, 0x7C00, 0x3E00, 0x001F,
gr_x11_convert_rgb_to_rgb555,
gr_x11_convert_gray_to_rgb555
};
/************************************************************************/
/************************************************************************/
/***** *****/
/***** BLITTING ROUTINES FOR BGR555 *****/
/***** *****/
/************************************************************************/
/************************************************************************/
static void
gr_x11_convert_rgb_to_bgr555( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x * 3;
unsigned char* line_write = blit->dst_line + blit->x * 2;
int h = blit->height;
for ( ; h > 0; h-- )
{
unsigned char* read = line_read;
unsigned short* write = (unsigned short*)line_write;
int x = blit->width;
for ( ; x > 0; x--, read += 3, write++ )
{
unsigned int r = read[0];
unsigned int g = read[1];
unsigned int b = read[2];
write[0] = (unsigned short)( ( (b << 7) & 0x7C00 ) |
( (g << 2) & 0x03E0 ) |
( (r >> 3) & 0x001F ) );
}
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static const grX11Format gr_x11_format_bgr555 =
{
15, 16, 0x1F00, 0x3E00, 0x7C00,
gr_x11_convert_rgb_to_bgr555,
gr_x11_convert_gray_to_rgb555 /* the same for bgr555! */
};
/************************************************************************/
/************************************************************************/
/***** *****/
/***** BLITTING ROUTINES FOR RGB888 *****/
/***** *****/
/************************************************************************/
/************************************************************************/
static void
gr_x11_convert_rgb_to_rgb888( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x * 3;
unsigned char* line_write = blit->dst_line + blit->x * 3;
int h = blit->height;
for ( ; h > 0; h-- )
{
memcpy( line_write, line_read, blit->width * 3 );
line_read += blit->src_pitch;
line_write += blit->dst_pitch;
}
}
static void
gr_x11_convert_gray_to_rgb888( grX11Blitter* blit )
{
unsigned char* line_read = blit->src_line + blit->x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -