📄 grwin32.c
字号:
/*******************************************************************
*
* grwin32.c graphics driver for Win32 platform
*
* This is the driver for displaying inside a window under Win32,
* used by the graphics utility of the FreeType test suite.
*
* Written by Antoine Leca.
* Copyright 1999-2000, 2001, 2002 by Antoine Leca, David Turner
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Borrowing liberally from the other FreeType drivers.
*
* 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.
*
******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <grobjs.h>
#include <grdevice.h>
/* logging facility */
#include <stdarg.h>
#define DEBUGxxx
#ifdef DEBUG
#define LOG(x) LogMessage##x
#else
#define LOG(x) /* rien */
#endif
#ifdef DEBUG
static void LogMessage( const char* fmt, ... )
{
va_list ap;
va_start( ap, fmt );
vfprintf( stderr, fmt, ap );
va_end( ap );
}
#endif
/*-------------------*/
/* Size of the window. */
#define WIN_WIDTH 640u
#define WIN_HEIGHT 450u
/* These values can be changed, but WIN_WIDTH should remain for now a */
/* multiple of 32 to avoid padding issues. */
typedef struct _Translator
{
ULONG winkey;
grKey grkey;
} Translator;
static
Translator key_translators[] =
{
{ VK_BACK, grKeyBackSpace },
{ VK_TAB, grKeyTab },
{ VK_RETURN, grKeyReturn },
{ VK_ESCAPE, grKeyEsc },
{ VK_HOME, grKeyHome },
{ VK_LEFT, grKeyLeft },
{ VK_UP, grKeyUp },
{ VK_RIGHT, grKeyRight },
{ VK_DOWN, grKeyDown },
{ VK_PRIOR, grKeyPageUp },
{ VK_NEXT, grKeyPageDown },
{ VK_END, grKeyEnd },
{ VK_F1, grKeyF1 },
{ VK_F2, grKeyF2 },
{ VK_F3, grKeyF3 },
{ VK_F4, grKeyF4 },
{ VK_F5, grKeyF5 },
{ VK_F6, grKeyF6 },
{ VK_F7, grKeyF7 },
{ VK_F8, grKeyF8 },
{ VK_F9, grKeyF9 },
{ VK_F10, grKeyF10 },
{ VK_F11, grKeyF11 },
{ VK_F12, grKeyF12 }
};
static
Translator syskey_translators[] =
{
{ VK_F1, grKeyF1 }
};
static ATOM ourAtom;
typedef struct grWin32SurfaceRec_
{
grSurface root;
HWND window;
int window_width;
int window_height;
int title_set;
const char* the_title;
LPBITMAPINFO pbmi;
char bmi[ sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD) ];
HBITMAP hbm;
grEvent ourevent;
int eventToProcess;
} grWin32Surface;
/* destroys the surface*/
static void
gr_win32_surface_done( grWin32Surface* surface )
{
/* The graphical window has perhaps already destroyed itself */
if ( surface->window )
{
DestroyWindow ( surface->window );
PostMessage( surface->window, WM_QUIT, 0, 0 );
}
grDoneBitmap( &surface->root.bitmap );
}
static void
gr_win32_surface_refresh_rectangle(
grWin32Surface* surface,
int x,
int y,
int w,
int h )
{
HDC hDC;
int row_bytes, delta;
LPBITMAPINFO pbmi = surface->pbmi;
HANDLE window = surface->window;
LOG(( "gr_win32_surface_refresh_rectangle: ( %p, %d, %d, %d, %d )\n",
(long)surface, x, y, w, h ));
/* clip update rectangle */
if ( x < 0 )
{
w += x;
x = 0;
}
delta = x + w - surface->window_width;
if ( delta > 0 )
w -= delta;
if ( y < 0 )
{
h += y;
y = 0;
}
delta = y + h - surface->window_height;
if ( delta > 0 )
h -= delta;
if ( w <= 0 || h <= 0 )
return;
/* now, perform the blit */
row_bytes = surface->root.bitmap.pitch;
if (row_bytes < 0) row_bytes = -row_bytes;
if ( row_bytes*8 != pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount )
pbmi->bmiHeader.biWidth = row_bytes * 8 / pbmi->bmiHeader.biBitCount;
hDC = GetDC ( window );
SetDIBits ( hDC, surface->hbm,
0,
surface->root.bitmap.rows,
surface->root.bitmap.buffer,
pbmi,
DIB_RGB_COLORS );
ReleaseDC ( window, hDC );
ShowWindow( window, SW_SHOW );
InvalidateRect ( window, NULL, FALSE );
UpdateWindow ( window );
}
static void
gr_win32_surface_set_title( grWin32Surface* surface,
const char* title )
{
/* the title will be set on the next listen_event, just */
/* record it there.. */
surface->title_set = 1;
surface->the_title = title;
}
static void
gr_win32_surface_listen_event( grWin32Surface* surface,
int event_mask,
grEvent* grevent )
{
MSG msg;
HANDLE window = surface->window;
event_mask=event_mask; /* unused parameter */
if ( window && !surface->title_set )
{
SetWindowText( window, surface->the_title );
surface->title_set = 1;
}
surface->eventToProcess = 0;
while (GetMessage( &msg, 0, 0, 0 ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
if (surface->eventToProcess)
break;
}
*grevent = surface->ourevent;
}
/*
* set graphics mode
* and create the window class and the message handling.
*/
static grWin32Surface*
gr_win32_surface_init( grWin32Surface* surface,
grBitmap* bitmap )
{
static RGBQUAD black = { 0, 0, 0, 0 };
static RGBQUAD white = { 0xFF, 0xFF, 0xFF, 0 };
LPBITMAPINFO pbmi;
/* find some memory for the bitmap header */
surface->pbmi = pbmi = (LPBITMAPINFO) surface->bmi;
LOG(( "Win32: init_surface( %p, %p )\n", surface, bitmap ));
LOG(( " -- input bitmap =\n" ));
LOG(( " -- mode = %d\n", bitmap->mode ));
LOG(( " -- grays = %d\n", bitmap->grays ));
LOG(( " -- width = %d\n", bitmap->width ));
LOG(( " -- height = %d\n", bitmap->rows ));
/* create the bitmap - under Win32, we support all modes as the GDI */
/* handles all conversions automatically.. */
if ( grNewBitmap( bitmap->mode,
bitmap->grays,
bitmap->width,
bitmap->rows,
bitmap ) )
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -