⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvpm.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:

    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 + -