📄 gvpm.c
字号:
if ( (pbm->width == pbm->old_width) &&
(pbm->height == pbm->old_height) &&
(pbm->planes == pbm->old_planes) &&
(pbm->depth == pbm->old_depth) &&
(pbm->palsize == pbm->old_palsize) &&
(pbm->old_bmp == old_bmp) )
return FALSE;
/* bitmap has changed */
pbm->old_width = pbm->width;
pbm->old_height = pbm->height;
pbm->old_planes = pbm->planes;
pbm->old_depth = pbm->depth;
pbm->old_palsize = pbm->palsize;
pbm->old_bmp = old_bmp;
return TRUE;
}
/* copy bitmap to the clipboard */
void
copy_clipboard(void)
{
HBITMAP hbmp;
if (!image.open) {
gserror(0, "Cannot copy to clipboard:\nNo Bitmap displayed", MB_ICONEXCLAMATION, SOUND_ERROR);
return;
}
if ( text_index && (text_mark_first != -1) && (text_mark_last != -1)) {
/* copy text, not image */
int first, last, line;
int length;
int i;
LPSTR data;
PVOID mem;
first = text_mark_first;
last = text_mark_last;
if (first > last) {
first = text_mark_last;
last = text_mark_first;
}
line = text_index[first].line;
length = 1;
for (i=first; i<=last; i++) {
if (text_index[i].line != line) {
line = text_index[i].line;
length += 2;
}
length += strlen( text_words + text_index[i].word ) + 1;
}
if (DosAllocSharedMem(&mem, NULL, length, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE)) {
message_box("out of memory", 0);
return;
}
data = (LPSTR)mem;
line = text_index[first].line;
for (i=first; i<=last; i++) {
if (text_index[i].line != line) {
line = text_index[i].line;
strcpy(data, "\r\n");
data += strlen(data);
}
strcpy(data, text_words + text_index[i].word);
strcat(data, " ");
data += strlen(data);
}
if (WinOpenClipbrd(hab)) {
WinEmptyClipbrd(hab);
WinSetClipbrdData(hab, (ULONG)mem, CF_TEXT, CFI_POINTER);
WinCloseClipbrd(hab);
}
return;
}
if (WinOpenClipbrd(hab)) {
/* get bmp mutex to stop gs.exe changing bitmap while we copy it */
image_lock(&image);
if (image.open && scan_bitmap(&bitmap)) {
/* bitmap has changed */
update_scroll_bars();
}
hbmp = make_bitmap(&bitmap, 0, 0, bitmap.width, bitmap.height, bitmap.depth);
if (hbmp) {
WinEmptyClipbrd(hab);
WinSetClipbrdData(hab, (ULONG)hbmp, CF_BITMAP, CFI_HANDLE);
}
image_unlock(&image);
WinCloseClipbrd(hab);
}
}
HBITMAP
make_bitmap(BMAP *pbm, ULONG left, ULONG bottom, ULONG right, ULONG top, ULONG depth)
{
HDC hdcMem = DEV_ERROR;
HPS hps = GPI_ERROR;
HBITMAP hbmp = GPI_ERROR, hbmr = HBM_ERROR;
SIZEL sizePS;
BITMAPINFOHEADER2 bmih;
if ( (left == right) || (bottom == top) )
return (HBITMAP)NULL;
if ((int)right > pbm->width)
right = pbm->width;
if ((int)left > pbm->width)
left = 0;
if ((int)top > pbm->height)
top = pbm->height;
if ((int)bottom > pbm->height)
bottom = 0;
memset(&bmih, 0, sizeof(bmih));
bmih.cbFix = sizeof(BITMAPINFOHEADER2);
bmih.cx = right - left;
bmih.cy = top - bottom;
bmih.cPlanes = 1;
bmih.cBitCount = depth;
/* create memory DC compatible with screen */
hdcMem = DevOpenDC(hab, OD_MEMORY, (unsigned char *)"*", 0L, NULL, NULLHANDLE);
sizePS.cx = right - left;
sizePS.cy = top - bottom;
if (hdcMem != DEV_ERROR)
hps = GpiCreatePS(hab, hdcMem, &sizePS,
PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC );
if (hps != GPI_ERROR)
hbmp = GpiCreateBitmap(hps, &bmih, 0L, NULL, NULL);
if (hbmp != GPI_ERROR)
hbmr = GpiSetBitmap(hps, hbmp);
if (hbmr != HBM_ERROR) {
LONG rc;
ERRORID eid;
POINTL apts[4];
/* target is inclusive */
apts[0].x = 0;
apts[0].y = 0;
apts[1].x = right - left - 1;
apts[1].y = top - bottom - 1;
/* source is not inclusive of top & right borders */
apts[2].x = left;
apts[2].y = bottom;
apts[3].x = right;
apts[3].y = top;
rc = 0;
eid = WinGetLastError(hab);
if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists)
GpiSelectPalette(hps, display.hpal);
rc = GpiDrawBits(hps, pbm->bits, pbm->pbmi, 4, apts,
(bitmap.depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);
if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists)
GpiSelectPalette(hps, (HPAL)NULL);
if (rc==0) {
char buf[MAXSTR];
eid = WinGetLastError(hab);
sprintf(buf,"make_bitmap: GpiDrawBits rc = %08x, eid = %08x",(int)rc, (int)eid);
message_box(buf, 0);
}
}
if (hbmr != HBM_ERROR)
GpiSetBitmap(hps, (ULONG)0);
if (hps != GPI_ERROR)
GpiDestroyPS(hps);
if (hdcMem != DEV_ERROR)
DevCloseDC(hdcMem);
if ( (hbmr == HBM_ERROR) || (hdcMem == DEV_ERROR) ||
(hbmp == GPI_ERROR) || (hps == GPI_ERROR) ) {
if (hbmp != GPI_ERROR)
GpiDeleteBitmap(hbmp);
return 0;
}
return hbmp;
}
MRESULT
paint_bitmap(HPS ps, PRECTL prect, int scrollx, int scrolly)
{
POINTL apts[4];
RECTL rect;
int wx, wy;
HRGN hrgn, hrgnold;
HPOINTER hptr;
LONG background_colour = SYSCLR_DIALOGBACKGROUND;
if (WinIsRectEmpty(hab, prect))
return 0;
/* KLUDGE BEGIN */
/* remove pointer to cope with buggy display drivers */
hptr = WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, 0);
/* KLUDGE END */
/* source is not inclusive of top & right borders */
wx = prect->xRight - prect->xLeft; /* update width */
wy = prect->yTop - prect->yBottom; /* update height */
if (prect->xLeft < display.offset.x)
apts[2].x = 0;
else
apts[2].x = (prect->xLeft-display.offset.x) + scrollx;
if (prect->yBottom < display.offset.y)
apts[2].y = 0;
else
apts[2].y = (prect->yBottom-display.offset.y) + scrolly;
if (apts[2].x > bitmap.width)
apts[2].x = bitmap.width;
if (apts[2].x + wx > bitmap.width) {
wx = bitmap.width - apts[2].x;
}
apts[3].x = apts[2].x + wx;
if (apts[2].y > bitmap.height)
apts[2].y = bitmap.height;
if (apts[2].y + wy > bitmap.height) {
wy = bitmap.height - apts[2].y;
}
apts[3].y = apts[2].y + wy;
/* target is inclusive */
if (prect->xLeft < display.offset.x)
apts[0].x = display.offset.x;
else
apts[0].x = prect->xLeft;
if (prect->yBottom < display.offset.y)
apts[0].y = display.offset.y;
else
apts[0].y = prect->yBottom;
apts[1].x = apts[0].x + wx - 1;
apts[1].y = apts[0].y + wy - 1;
if ( (option.drawmethod == IDM_DRAWWIN) ||
((option.drawmethod == IDM_DRAWDEF) && (display.bitcount == 4)) ) /* standard VGA is buggy */
{
/* slow code to dodge OS/2 bugs */
/* this code double buffers the bitmap and works on a standard VGA
* but didn't work on an ATI Ultra Graphics Pro in 8514 emulation
*/
/* This won't work for OS/2 2.11, S3 or ATI GU, 8bit/pixel display, 8bit/pixel bitmap */
HBITMAP hbmp;
/* create a bitmap */
hbmp = make_bitmap(&bitmap, apts[2].x, apts[2].y, apts[3].x, apts[3].y, bitmap.depth);
/* Draw it to the display */
if (hbmp) {
WinDrawBitmap(ps, hbmp, NULL, &apts[0], CLR_BLACK, CLR_WHITE, DBM_NORMAL);
GpiDeleteBitmap(hbmp);
}
}
else { /* (option.drawmethod == IDM_DRAWGPI) || (default and non buggy display) */
/* fast code which doesn't always work */
/* This code works on the Trident SVGA and 8514 in 256 color mode,
* but GpiDrawBits fails with a SYS3175 on the standard VGA.
*/
/* This won't work for version 2.11, S3 or ATI GU, 8bit/pixel display, 1bit/pixel bitmap */
GpiDrawBits(ps, bitmap.bits, bitmap.pbmi, 4, apts,
(bitmap.depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);
}
if (fullscreen)
background_colour = CLR_BLACK;
/* Fill areas around page */
if (prect->yBottom < display.offset.y) { /* bottom centre */
rect.yBottom = prect->yBottom;
rect.yTop = display.offset.y;
rect.xLeft = apts[0].x;
rect.xRight = rect.xLeft + wx;
WinFillRect(ps, &rect, background_colour);
}
if (prect->yTop > bitmap.height + display.offset.y) { /* top centre */
rect.yBottom = bitmap.height + display.offset.y;
rect.yTop = prect->yTop;
rect.xLeft = apts[0].x;
rect.xRight = rect.xLeft + wx;
WinFillRect(ps, &rect, background_colour);
}
if (prect->xLeft < display.offset.x) { /* left */
rect.yBottom = prect->yBottom;
rect.yTop = prect->yTop;
rect.xLeft = prect->xLeft;
rect.xRight = display.offset.x;
WinFillRect(ps, &rect, background_colour);
}
if (prect->xRight > bitmap.width + display.offset.x) { /* right */
rect.yBottom = prect->yBottom;
rect.yTop = prect->yTop;
rect.xLeft = bitmap.width + display.offset.x;
rect.xRight = prect->xRight;
WinFillRect(ps, &rect, background_colour);
}
/* clip other drawing commands to update rectangle */
hrgn = GpiCreateRegion(ps, 1, prect);
GpiSetClipRegion(ps, hrgn, &hrgnold);
if (hrgnold)
GpiDestroyRegion(ps, hrgnold);
/* draw bounding box */
if ((psfile.dsc != (CDSC *)NULL) &&
(psfile.dsc->bbox != (CDSCBBOX *)NULL) &&
option.show_bbox) {
POINTL pt;
float x, y;
/* map bounding box to device coordinates */
x = psfile.dsc->bbox->llx;
y = psfile.dsc->bbox->lly;
map_pt_to_pixel(&x, &y);
rect.xLeft = (int)x;
rect.yBottom = (int)y;
x = psfile.dsc->bbox->urx;
y = psfile.dsc->bbox->ury;
map_pt_to_pixel(&x, &y);
rect.xRight = (int)x;
rect.yTop = (int)y;
/* draw it inverted */
GpiSetColor(ps, CLR_TRUE);
GpiSetLineType(ps, LINETYPE_SHORTDASH);
GpiSetMix(ps, FM_XOR);
pt.x = rect.xLeft; pt.y = rect.yBottom;
GpiMove(ps, &pt);
pt.x = rect.xRight; /* might be better to use GpiPolyLine */
GpiLine(ps, &pt);
pt.y = rect.yTop;
GpiLine(ps, &pt);
pt.x = rect.xLeft;
GpiLine(ps, &pt);
pt.y = rect.yBottom;
GpiLine(ps, &pt);
GpiSetLineType(ps, LINETYPE_DEFAULT);
GpiSetMix(ps, FM_DEFAULT);
GpiSetColor(ps, CLR_TRUE);
}
/* highlight found search word */
if (image.open && display.show_find) {
float x, y;
/* map bounding box to device coordinates */
x = psfile.text_bbox.llx;
y = psfile.text_bbox.lly;
map_pt_to_pixel(&x, &y);
rect.xLeft = (int)x;
rect.yBottom = (int)y;
x = psfile.text_bbox.urx;
y = psfile.text_bbox.ury;
map_pt_to_pixel(&x, &y);
rect.xRight = (int)x;
rect.yTop = (int)y;
if (rect.yTop < rect.yBottom) {
int temp = rect.yTop;
rect.yTop = rect.yBottom;
rect.yBottom = temp;
}
/* invert text */
WinInvertRect(ps, &rect);
}
/* highlight marked words */
highlight_words(ps, text_mark_first, text_mark_last);
/* GS 6.50 highlights links itself for PDF files */
if ((option.gsversion < 650) || !psfile.ispdf)
highlight_links(ps);
GpiSetClipRegion(ps, NULLHANDLE, &hrgnold);
if (hrgnold)
GpiDestroyRegion(ps, hrgnold);
/* KLUDGE BEGIN */
/* restore pointer after we removed it */
WinSetPointer(HWND_DESKTOP, hptr);
/* KLUDGE END */
return 0;
}
/* enable or disable a menu item */
void
enable_menu_item(int menuid, int itemid, BOOL enabled)
{
HWND hwndMenu;
MENUITEM mi;
hwndMenu = WinWindowFromID(hwnd_frame, FID_MENU);
WinSendMsg(hwndMenu, MM_QUERYITEM,
MPFROM2SHORT(menuid, TRUE), MPFROMP(&mi));
WinSendMsg(mi.hwndSubMenu, MM_SETITEMATTR, MPFROMLONG(itemid),
MPFROM2SHORT(MIA_DISABLED, enabled ? 0 : MIA_DISABLED));
}
void
init_menu(int menuid)
{
BOOL idle;
BOOL addeps;
idle = (gsdll.state != GS_BUSY);
switch (menuid) {
case IDM_FILEMENU:
enable_menu_item(IDM_FILEMENU, IDM_PRINT, idle);
enable_menu_item(IDM_FILEMENU, IDM_PRINTTOFILE, idle);
enable_menu_item(IDM_FILEMENU, IDM_EXTRACT, idle);
enable_menu_item(IDM_FILEMENU, IDM_PSTOEPS, idle);
/* recent files */
{ HWND hwndMenu;
MENUITEM mi;
MENUITEM mii;
char buf[MAXSTR];
int i;
hwndMenu = WinWindowFromID(hwnd_frame, FID_MENU);
WinSendMsg(hwndMenu, MM_QUERYITEM,
MPFROM2SHORT(IDM_FILEMENU, TRUE), MPFROMP(&mi));
WinSendMsg(mi.hwndSubMenu, MM_DELETEITEM,
MPFROM2SHORT(IDM_LASTFILE1, TRUE), (MPARAM)NULL);
WinSendMsg(mi.hwndSubMenu, MM_DELETEITEM,
MPFROM2SHORT(IDM_LASTFILE2, TRUE), (MPARAM)NULL);
WinSendMsg(mi.hwndSubMenu, MM_DELETEITEM,
MPFROM2SHORT(IDM_LASTFILE3, TRUE), (MPARAM)NULL);
WinSendMsg(mi.hwndSubMenu, MM_DELETEITEM,
MPFROM2SHORT(IDM_LASTFILE4, TRUE), (MPARAM)NULL);
mii.iPosition = 15;
mii.afStyle = MIS_TEXT;
mii.afAttribute = 0;
mii.hwndSubMenu = (HWND)NULL;
mii.hItem = 0;
for (i=last_files_count; i>0; i--) {
sprintf(buf, "~%d %s", i, last_files[i-1]);
if (strlen(buf)>36) {
int j;
for (j=strlen(buf); j>0; j--)
if ((buf[j] == '/') || (buf[j] == '\\'))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -