📄 iedraw.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "imgedit.h"
#include <string.h>
#include <math.h>
#include "iedraw.h"
#include "iemem.h"
#define MIN_DRAW_WIN_WIDTH 150
static WPI_POINT pointSize = {0, 0};
static short toolType;
static HWND hDrawArea = NULL;
static short currentMouseButton;
static void showGrid( HWND hwnd, WPI_PRES mempres );
/*
* GridEnumProc - used to grid all the children
*/
BOOL CALLBACK GridEnumProc( HWND hwnd, LONG lparam )
{
HWND frame;
lparam = lparam;
if ( _wpi_getowner(hwnd) ) {
return 1;
}
if ( _wpi_isiconic(hwnd) ) {
return 1;
} else {
InvalidateRect( _wpi_getclient(hwnd), NULL, FALSE );
}
frame = frame; // suppress compiler warnings
return 1;
} /* GridEnumProc */
/*
* CalculateDims - calculates the size of the "pixel" in the drawing
* area and establishes the device draw area size.
*/
void CalculateDims( short img_width, short img_height, short *area_width,
short *area_height )
{
int point_size1;
int point_size2;
int max_width;
int max_height;
WPI_RECT rcclient;
int x_adj;
int y_adj;
GetClientRect( ClientWindow, &rcclient );
x_adj = (short)(2*_wpi_getsystemmetrics(SM_CXFRAME));
y_adj = (short)(2*_wpi_getsystemmetrics(SM_CYFRAME) +
_wpi_getsystemmetrics(SM_CYCAPTION));
#if 0
max_width = _wpi_getwidthrect(rcclient) - x_adj - origin->x;
max_height = _wpi_getheightrect(rcclient) - y_adj - origin->y;
#else
max_width = _wpi_getwidthrect(rcclient) - x_adj;
max_height = _wpi_getheightrect(rcclient) - y_adj;
#endif
point_size1 = max (1, max_width / img_width);
point_size2 = max (1, max_height / img_height);
if( point_size1 < 1 ) {
point_size1 = 1;
}
if( point_size2 < 1 ) {
point_size2 = 1;
}
pointSize.x = min( point_size1, point_size2 );
while( (pointSize.x * img_width) < MIN_DRAW_WIN_WIDTH ) {
pointSize.x++;
}
pointSize.y = pointSize.x;
*area_width = (short)(pointSize.x * img_width);
*area_height = (short)(pointSize.y * img_height);
} /* CalculateDims */
/*
* BlowupImage - Stretches the view window into the window given by hwnd.
*/
void BlowupImage( HWND hmdiwnd, WPI_PRES pres )
{
HDC memdc;
WPI_PRES mempres;
WPI_RECT client;
HBITMAP oldbitmap;
HBITMAP newbitmap;
HWND hwnd;
img_node *node;
BOOL new_pres;
if( hmdiwnd ) {
hwnd = hmdiwnd;
} else {
node = GetCurrentNode();
if( !node ) {
return;
}
hwnd = node->hwnd;
}
newbitmap = EnlargeImage( hwnd );
if (!newbitmap) return;
new_pres = FALSE;
if( pres == (WPI_PRES)NULL ) {
pres = _wpi_getpres( hwnd );
new_pres = TRUE;
}
mempres = _wpi_createcompatiblepres( pres, Instance, &memdc );
oldbitmap = _wpi_selectobject( mempres, newbitmap );
if (ImgedConfigInfo.grid_on) {
showGrid( hwnd, mempres );
} else {
GetClientRect(hwnd, &client);
_wpi_bitblt( pres, 0, 0, _wpi_getwidthrect(client),
_wpi_getheightrect(client), mempres, 0, 0, SRCCOPY );
RedrawPrevClip(hwnd); // Redraws if there was a clip region specified.
}
_wpi_selectobject( mempres, oldbitmap );
_wpi_deletebitmap( newbitmap );
_wpi_deletecompatiblepres( mempres, memdc );
if( new_pres ) {
_wpi_releasepres( hwnd, pres );
}
} /* BlowupImage */
void IEInvalidateNode( img_node *node )
{
HWND hwnd;
if( node == NULL ) {
node = GetCurrentNode();
if( node == NULL ) {
return;
}
}
hwnd = node->hwnd;
InvalidateRect( hwnd, NULL, FALSE );
}
/*
* CheckBounds - checks the bounds vs the client rectangle.
*/
void CheckBounds( HWND hwnd, WPI_POINT *pt )
{
WPI_RECT client;
IMGED_DIM left;
IMGED_DIM right;
IMGED_DIM top;
IMGED_DIM bottom;
GetClientRect(hwnd, &client);
_wpi_getrectvalues( client, &left, &top, &right, &bottom );
if (pt->x >= right) {
pt->x = right-1;
} else if (pt->x < left) {
pt->x = left;
}
if (pt->y >= bottom) {
pt->y = bottom-1;
} else if (pt->y < top) {
pt->y = top;
}
} /* CheckBounds */
/*
* showGrid - Display the grid on the draw area.
*/
static void showGrid( HWND hwnd, WPI_PRES mempres )
{
short i;
short psx;
short psy;
WPI_RECT rcclient;
HPEN hblackpen;
HPEN holdpen;
img_node *node;
short width;
short height;
IMGED_DIM left;
IMGED_DIM right;
IMGED_DIM top;
IMGED_DIM bottom;
WPI_PRES pres;
WPI_POINT startpt;
WPI_POINT endpt;
node = SelectImage( hwnd );
_wpi_torgbmode( mempres );
GetClientRect( hwnd, &rcclient );
width = (short)( _wpi_getwidthrect(rcclient) );
height = (short)( _wpi_getheightrect(rcclient) );
if (((width / node->width) < POINTSIZE_MIN) ||
((height / node->height) < POINTSIZE_MIN)) {
psx = 0;
psy = 0;
} else {
psx = width / node->width;
psy = height / node->height;
hblackpen = _wpi_createpen( PS_SOLID, 0, BLACK );
holdpen = _wpi_selectobject( mempres, hblackpen );
_wpi_getrectvalues( rcclient, &left, &top, &right, &bottom );
for (i=0; i < width; i = i + psx) {
_wpi_setpoint( &startpt, i, top );
_wpi_setpoint( &endpt, i, bottom );
_wpi_movetoex( mempres, &startpt, NULL );
_wpi_lineto( mempres, &endpt );
}
for (i=0; i <= height; i = i + psy) {
_wpi_setpoint( &startpt, left, i );
_wpi_setpoint( &endpt, right, i );
_wpi_movetoex( mempres, &startpt, NULL );
_wpi_lineto( mempres, &endpt );
}
_wpi_selectobject( mempres, holdpen );
_wpi_deleteobject( hblackpen );
}
pres = _wpi_getpres( hwnd );
_wpi_bitblt( pres, 0, 0, width, height, mempres, 0, 0, SRCCOPY );
_wpi_releasepres( hwnd, pres );
RedrawPrevClip(hwnd); // Redraws if there was a clip region specified.
} /* showGrid */
/*
* DrawSinglePoint - needed for when the mouse button is initially pressed.
*/
void DrawSinglePoint( HWND hwnd, WPI_POINT *pt, short mousebutton )
{
HBRUSH colourbrush;
HBRUSH oldbrush;
HPEN colourpen;
HPEN oldpen;
COLORREF selected_colour;
COLORREF dithered;
short truncated_x;
short truncated_y;
short i;
short j;
WPI_POINT logical_pt;
WPI_RECT rcclient;
short width;
short height;
short wndwidth;
short wndheight;
wie_clrtype type;
WPI_PRES pres;
int brushsize;
BOOL gridvisible;
GetClientRect( hwnd, &rcclient );
wndwidth = _wpi_getwidthrect( rcclient );
wndheight = _wpi_getheightrect( rcclient );
brushsize = ImgedConfigInfo.brush_size;
CheckBounds( hwnd, pt );
gridvisible = ImgedConfigInfo.grid_on && (pointSize.x >= POINTSIZE_MIN &&
pointSize.y >= POINTSIZE_MIN);
if (gridvisible) {
if (toolType == IMGED_BRUSH) {
truncated_x = max(0, (pt->x/pointSize.x - brushsize/2)) * pointSize.x+1;
truncated_y = max(0, (pt->y/pointSize.y - brushsize/2)) * pointSize.y+1;
width = (short)(pointSize.x - 1);
height = (short)(pointSize.y - 1);
/*
* We just have to check that we don't spill over the image dimensions
*/
truncated_x = min(truncated_x, wndwidth-pointSize.x*brushsize+1);
truncated_y = min(truncated_y, wndheight-pointSize.y*brushsize+1);
} else {
truncated_x = ( pt->x / pointSize.x) * pointSize.x + 1;
truncated_y = ( pt->y / pointSize.y) * pointSize.y + 1;
width = (short)(pointSize.x - 1);
height = (short)(pointSize.y - 1);
}
} else {
if (toolType == IMGED_BRUSH) {
truncated_x = max(0, (pt->x / pointSize.x - brushsize/2)) * pointSize.x;
truncated_y = max(0, (pt->y / pointSize.y - brushsize/2)) * pointSize.y;
width = (short)(pointSize.x * brushsize);
height = (short)(pointSize.y * brushsize);
/*
* We just have to check that we don't spill over the image dimensions
*/
truncated_x = min( truncated_x, wndwidth-width );
truncated_y = min( truncated_y, wndheight-width );
} else {
truncated_x = ( pt->x / pointSize.x) * pointSize.x;
truncated_y = ( pt->y / pointSize.y) * pointSize.y;
width = (short)pointSize.x;
height = (short)pointSize.y;
}
}
logical_pt.x = truncated_x / pointSize.x;
logical_pt.y = truncated_y / pointSize.y;
pres = _wpi_getpres( hwnd );
_wpi_torgbmode( pres );
dithered = GetSelectedColour(mousebutton, &selected_colour, &type);
colourbrush = _wpi_createsolidbrush( selected_colour );
oldbrush = _wpi_selectobject( pres, colourbrush );
colourpen = _wpi_createpen( PS_SOLID, 0, selected_colour );
oldpen = _wpi_selectobject( pres, colourpen );
if (gridvisible && (toolType == IMGED_BRUSH)) {
for (i=0; i < brushsize; ++i) {
for (j=0; j < brushsize; ++j) {
_wpi_patblt(pres, truncated_x+i*pointSize.x,
truncated_y+j*pointSize.y,
width, height, PATCOPY);
}
}
} else {
_wpi_patblt(pres, truncated_x, truncated_y, width, height, PATCOPY);
}
_wpi_selectobject( pres, oldbrush );
_wpi_selectobject( pres, oldpen );
_wpi_releasepres( hwnd, pres );
_wpi_deleteobject( colourbrush );
_wpi_deleteobject( colourpen );
/*
* draws the points in the view window
*/
if (toolType == IMGED_BRUSH) {
if (type == SCREEN_CLR) {
BrushThePoints(selected_colour, BLACK, WHITE, &logical_pt,
brushsize);
} else if (type == INVERSE_CLR) {
BrushThePoints(selected_colour, WHITE, WHITE, &logical_pt,
brushsize);
} else {
BrushThePoints(selected_colour, selected_colour, BLACK,
&logical_pt, brushsize);
}
} else {
if (type == SCREEN_CLR) {
DrawThePoints(selected_colour, BLACK, WHITE, &logical_pt);
} else if (type == INVERSE_CLR) {
DrawThePoints(selected_colour, WHITE, WHITE, &logical_pt);
} else {
DrawThePoints(selected_colour, selected_colour, BLACK, &logical_pt);
}
}
} /* DrawSinglePoint */
/*
* drawPt - Actually draws the point on the drawing region. (uses LineDDA)
*/
void CALLBACK drawPt( int xpos, int ypos, WPI_PARAM2 lparam )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -