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

📄 gvx.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 4 页
字号:
	else {
	    x = (int)(event->x);
	    y = (int)(event->y);
	    state = (GdkModifierType)event->state;
	}
	gs_addmessf("motion_notify_event: motion %d %d\n", x, y);
#endif
	in_img_window = TRUE;
	if (draghand) {
	    GtkAdjustment *hadjust = gtk_scrolled_window_get_hadjustment(
		GTK_SCROLLED_WINDOW(scroll_window));
	    GtkAdjustment *vadjust = gtk_scrolled_window_get_vadjustment(
		GTK_SCROLLED_WINDOW(scroll_window));
	    int dx = (int)event->x - draghand_x;
	    int dy = (int)event->y - draghand_y;
	    set_scroll(hadjust->value - dx, vadjust->value - dy);
	}
    }

    if (get_cursorpos(&x, &y)) {
	PDFLINK link;
	int iword;
	info_link();
	if (is_link(x, y, &link)) {
	    /* should change cursor to a hand */
/* not implemented */
	}
	if (text_marking) {
	    if ( (iword = word_find((int)x, (int)y)) >= 0 ) {
		if (iword != text_mark_last) {
		    int first, last;
		    if ((text_mark_last-text_mark_first >= 0) != (iword-text_mark_first >= 0)) {
			/* changing direction */
			/* clear everything */
			highlight_words(text_mark_first, text_mark_last, FALSE);
			/* reinstate first word */
			text_mark_last = text_mark_first;
			highlight_words(text_mark_first, text_mark_last, TRUE);
		    }
		    if (iword != text_mark_last) {
		      if (iword >= text_mark_first) {
			if (iword > text_mark_last)
			    first=text_mark_last+1, last=iword;
			else
			    first=iword+1, last=text_mark_last;
		      }
		      else {
			if (iword > text_mark_last)
			    first=text_mark_last, last=iword-1;
			else
			    first=iword, last=text_mark_last-1;
		      }
		      highlight_words(first, last, TRUE);
		      text_mark_last = iword;
		    }
		}
	    }
	}
	measure_paint(x, y);
    }

    statuscoord_update();

    return TRUE; 
}

gint
configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data)
{
    return TRUE; 
}

gint
size_event(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data)
{
    gint x, y;
    /* remember image size and location */
    if (window->window) {
	gdk_window_get_position(window->window, &x, &y);
	option.img_origin.x = x;
	option.img_origin.y = y;
    }
    option.img_size.x = window->allocation.width;
    option.img_size.y = window->allocation.height;
    return TRUE; 
}

static void
window_draw(GtkWidget *widget, int x, int y, int width, int height)
{
    if (image.open && image.image) {
        int color = image.format & DISPLAY_COLORS_MASK;
	int depth = image.format & DISPLAY_DEPTH_MASK;
	switch (color) {
	    case DISPLAY_COLORS_NATIVE:
		if (depth == DISPLAY_DEPTH_8) {
		    gdk_draw_indexed_image(widget->window, 
			widget->style->fg_gc[GTK_STATE_NORMAL],
			x, y, width, height, GDK_RGB_DITHER_MAX, 
			image.image + x + y*image.raster, 
			image.raster, image.cmap);
		}
	  	else if ((depth == DISPLAY_DEPTH_16) && image.rgbbuf) {
		    gdk_draw_rgb_image(widget->window, 
			widget->style->fg_gc[GTK_STATE_NORMAL],
			x, y, width, height, GDK_RGB_DITHER_MAX, 
			image.rgbbuf + x*3 + image.width*3*y, 
			image.width * 3);
		}
		break;
	    case DISPLAY_COLORS_GRAY:
		if (depth == DISPLAY_DEPTH_8)
		    gdk_draw_gray_image(widget->window, 
			widget->style->fg_gc[GTK_STATE_NORMAL],
			x, y, width, height, GDK_RGB_DITHER_MAX, 
			image.image + x + y*image.raster, 
		        image.raster);
		else if (depth == DISPLAY_DEPTH_1) {
		    /* FIX */
		    gs_addmess("1 bit/pixel drawing not implemented\n");
		}
		break;
	    case DISPLAY_COLORS_RGB:
		if (depth == DISPLAY_DEPTH_8) {
		    if (image.rgbbuf) {
			gdk_draw_rgb_image(widget->window, 
			    widget->style->fg_gc[GTK_STATE_NORMAL],
			    x, y, width, height, GDK_RGB_DITHER_MAX, 
			    image.rgbbuf + x*3 + image.width*3*y, 
			    image.width * 3);
		    }
		    else {
			gdk_draw_rgb_image(widget->window, 
			    widget->style->fg_gc[GTK_STATE_NORMAL],
			    x, y, width, height, GDK_RGB_DITHER_MAX, 
			    image.image + x*3 + y*image.raster, 
			    image.raster);
		    }
		}
		break;
	    case DISPLAY_COLORS_CMYK:
		if ((depth == DISPLAY_DEPTH_8) && image.rgbbuf)
		    gdk_draw_rgb_image(widget->window, 
			widget->style->fg_gc[GTK_STATE_NORMAL],
			x, y, width, height, GDK_RGB_DITHER_MAX, 
			image.rgbbuf + x*3 + image.width*3*y, 
			image.width * 3);
		break;
	}
    }
}


gint
expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
    GdkGC *gcdash;
    GdkGC *gcinvert;
    GdkColor black = {0, 0, 0, 0};
    image_lock(view.img);
    if (image.open && image.image) {
	int x = event->area.x;
	int y = event->area.y;
	int width = event->area.width;
	int height = event->area.height;
	if ((x>=0) && (y>=0) && (x <= image.width) && (y <= image.height)) {
	    /* drawing area intersects the bitmap, so draw it */
	    if (x + width > image.width)
		width = image.width - x;
	    if (y + height > image.height)
		height = image.height - y;
	    window_draw(img, x, y, width, height);
	}
    }

    if (option.show_bbox && (psfile.dsc != (CDSC *)NULL) &&
	(psfile.dsc->bbox != (CDSCBBOX *)NULL)) {
	int left, right, top, bottom;
	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);
	left   = (int)x;
	bottom = (int)y;
	x = psfile.dsc->bbox->urx;
	y = psfile.dsc->bbox->ury;
	map_pt_to_pixel(&x, &y);
	right  = (int)x;
	top    = (int)y;
	if (left > right) {
	    int temp = left;
	    left = right;
	    right = temp;
	}
	if (bottom < top) {
	    int temp = top;
	    top = bottom;
	    bottom = temp;
	}
	gcdash = gdk_gc_new(img->window);
#ifdef NOTUSED
/* DOUBLE_DASH didn't seem to work.  Always ended up with solid black */
	GdkColor white = {1, 65535, 65535, 65535};
	gdk_gc_set_fill(gcdash, GDK_SOLID);
	gdk_gc_set_background(gcdash, &white);
	gdk_gc_set_line_attributes(gcdash, 1, GDK_LINE_DOUBLE_DASH,
		GDK_CAP_BUTT, GDK_JOIN_MITER);
#endif
	gdk_gc_set_foreground(gcdash, &black);
	gdk_gc_set_line_attributes(gcdash, 1, GDK_LINE_ON_OFF_DASH,
		GDK_CAP_BUTT, GDK_JOIN_MITER);
        gdk_draw_rectangle(img->window, gcdash, FALSE,
	    left, top, right-left, bottom-top);
	gdk_gc_unref(gcdash);
    }


    /* highlight found search word */
    if (image.open && display.show_find) {
	float x, y;
	int left, top, bottom, right;
	/* map bounding box to device coordinates */
	x = psfile.text_bbox.llx;
	y = psfile.text_bbox.lly;
	map_pt_to_pixel(&x, &y);
	left   = (int)x;
	bottom = (int)y;
	x = psfile.text_bbox.urx;
	y = psfile.text_bbox.ury;
	map_pt_to_pixel(&x, &y);
	right  = (int)x;
	top    = (int)y;
	if (top > bottom) {
	    int temp = top;
	    top = bottom;
	    bottom = temp;
	}
	if (left > right) {
	    int temp = right;
	    right = left;
	    left = temp;
	}

	if (image.open) {
	    /* redraw rectangle we about to invert */
            window_draw(img, left, top, right-left, bottom-top);
	}
	/* invert text */
	gcinvert = gdk_gc_new(img->window);
	gdk_gc_set_function(gcinvert, GDK_INVERT);
	gdk_draw_rectangle(img->window, gcinvert,
		TRUE, left, top, right-left, bottom-top);
	gdk_gc_unref(gcinvert);
    }

    /* highlight marked words */
    highlight_words(text_mark_first, text_mark_last, TRUE);

    /* GS 6.50 highlights links itself for PDF files */
    if ((option.gsversion < 650) || !psfile.ispdf)
	highlight_links();

    image_unlock(view.img);

    return FALSE; 
}


/* map from a coordinate in points, to a coordinate in pixels */
/* This is the opposite of the transform part of get_cursorpos */
/* Used when showing bbox */
void
map_pt_to_pixel(float *x, float *y)
{
    if (zoom) {
	/* WARNING - this doesn't cope with EPS Clip */
	*x = (*x - display.zoom_xoffset) * option.zoom_xdpi / 72.0;
	*y = (*y - display.zoom_yoffset) * option.zoom_ydpi / 72.0;
	*x = (*x * 72.0 / option.xdpi);
	*y = (*y * 72.0 / option.ydpi);
	itransform_point(x, y);
	*x = (*x * option.xdpi / 72.0) + display.offset.x;
	*y = -(*y * option.ydpi / 72.0) + (image.height - 1) 
		+ display.offset.y;
    }
    else {
	int xoffset = display.xoffset / display.xdpi * 72.0 + 0.5;
	int yoffset = display.yoffset / display.ydpi * 72.0 + 0.5;
	*x = *x - xoffset;
	*y = *y - yoffset;
	itransform_point(x, y);
	*x = *x * option.xdpi/72.0 + display.offset.x;
	*y = -(*y * option.ydpi/72.0)
	      + (image.height - 1) + display.offset.y;
    }
}

BOOL
get_cursorpos(float *x, float *y)
{
    int ix=0, iy=0;
    GdkModifierType state;
    if (!in_img_window)
	return FALSE;
    gdk_window_get_pointer(img->window, &ix, &iy, &state);
    *x = ix;
    *y = image.height - 1 - iy;
    transform_cursorpos(x, y);
    return TRUE;
}


void
statuscoord_update(void)
{
float x, y;
char buf[64];
char fmt[32];
int digits = option.unitfine ? 2 : 0;
    if ((psfile.name[0] != '\0') && gsdll.hmodule) {
	/* show coordinate */
	if (get_cursorpos(&x, &y)) {
	    switch(option.unit) {
	       case IDM_UNITPT:   
		  sprintf(fmt, "%%.%df, %%.%dfpt", digits, digits);
		  sprintf(buf, fmt, x, y);
		  break;
	       case IDM_UNITMM:   
		  sprintf(fmt, "%%.%df, %%.%dfmm", digits, digits);
		  sprintf(buf, fmt, x/72*25.4, y/72*25.4);
		  break;
	       case IDM_UNITINCH:   
		  digits += 1;
		  sprintf(fmt, "%%.%df, %%.%dfin", digits, digits);
		  sprintf(buf, fmt, x/72, y/72);
		  break;
	    }
	    
	    /* measure_paint(x, y); not implemented */
	}
	else {
	    buf[0] = '\0';
	}
    }
    else {
	buf[0] = '\0';
    }

    if (strcmp(coord_text, buf) != 0) {
	gtk_label_set_text(GTK_LABEL(statuscoord), buf);
	strncpy(coord_text, buf, sizeof(coord_text)-1);
	while (g_main_iteration(FALSE)); /* flush display */
    }
}


/* update the status bar */
void
statusbar_update(void) 
{
    CDSC *dsc = psfile.dsc;
    int i;
    char buf[256];
    char fmt[256];
    char coord[64];
    coord[0] = '\0';
    if (psfile.name[0] != '\0') {
	char *p;
	p = strrchr(psfile.name, '/');
	if (p == NULL)
	    p = psfile.name;
	else
	    p++;
	i = load_string(IDS_FILE, buf, sizeof(buf));
        strncpy(buf+i, p, sizeof(buf)-i-1);
	gtk_label_set_text(GTK_LABEL(statusfile), buf);

	if (szWait[0] != '\0') {
	    sprintf(buf, szWait, percent_done);
	    gtk_label_set_text(GTK_LABEL(statuspage), buf);
	}
	else {
	  if (psfile.dsc!=(CDSC *)NULL) {
	    int n = map_page(psfile.pagenum - 1);
	    load_string(IDS_PAGEINFO, fmt, sizeof(fmt));
	    if (on_link) {
		if ((on_link_page == 0) && on_link_action[0]) {
		    strncpy(buf, on_link_action, sizeof(buf)-1);
		}
		else
		{
		    load_string(IDS_LINKPAGE, fmt, sizeof(fmt));
		    sprintf(buf, fmt, on_link_page);
		}
	    }
	    else {
		if (psfile.dsc->page_count)
		    sprintf(buf, fmt, dsc->page[n].label ? 
			dsc->page[n].label : " ", psfile.pagenum,  
			dsc->page_count);
		else
		    sprintf(buf, fmt, " " ,psfile.pagenum,  dsc->page_count);
	    }
	    if (zoom)
		load_string(IDS_ZOOMED, buf+strlen(buf), sizeof(buf)-strlen(buf));
	    gtk_label_set_text(GTK_LABEL(statuspage), buf);
	  }
	  else {
	    if ((gsdll.state == GS_IDLE) || (gsdll.state == GS_UNINIT))
		load_string(IDS_NOMORE, buf, sizeof(buf));
	    else {
		load_string(IDS_PAGE, buf, sizeof(buf));
		sprintf(buf+i, "%d", psfile.pagenum);
	    }
	    gtk_label_set_text(GTK_LABEL(statuspage), buf);
	  }
	}
    }
    else {
	load_string(IDS_NOFILE, buf, sizeof(buf));
	gtk_label_set_text(GTK_LABEL(statusfile), buf);
	if (szWait[0] != '\0') {
	    sprintf(buf, szWait, percent_done);
	    gtk_label_set_text(GTK_LABEL(statuspage), buf);
	}
	else {
	    gtk_label_set_text(GTK_LABEL(statuspage), "");
	}
    }
    /* show coordinate */
    statuscoord_update();

    while (g_main_iteration(FALSE)); /* flush display */
}

void gsview_fullscreen_end(void)
{
/*
    gs_addmess("gsview_fullscreen_end: not implemented\n");
*/
}

void gsview_fullscreen(void)
{
    gs_addmess("gsview_fullscreen: not implemented\n");
}


/* Set the current resolution to fill the window.
 * If neither width nor height match, fit whole page
 * into window.  If either width or height match
 * the window size, fit the height or width respectively.
 */
void 
gsview_fitwin(void) 
{
int window_width, window_height;
int width, height;
float dpi, xdpi, ydpi, xdpi2, ydpi2;
    if (psfile.ispdf) {
/* TESTING TESTING TESTING */
/* This also need to be copied to gvwin.cpp and gvpm.cpp */
	CDSCBBOX *mediabox = NULL;
	CDSCBBOX *cropbox = NULL;
        int page = psfile.pagenum;
	if ((page > 0) && (page <= (int)psfile.dsc->page_count))  {
	    if (psfile.dsc->page[page-1].media)
		mediabox = psfile.dsc->page[page-1].media->mediabox;
	    cropbox = psfile.dsc->page[page-1].bbox;
	}
	if (option.epsf_clip && (cropbox != (CDSCBBOX *)NULL)) {
	    width = cropbox->urx - cropbox->llx;
	    height = cropbox->ury - cropbox->lly;
	}
	else {
	    if (mediabox) {
		width = mediabox->urx - mediabox->llx;
		height = mediabox->ury - mediabox->lly;
	    }
	    else {
		width = get_paper_width();
		height = get_paper_height();
	    }
	}
    }
    else {
	width = get_paper_width();
	height = get_paper_height();
    }

    if (display.orientation & 1) {
	/* page is rotated 90 degrees */
	int temp = width;
	width = height;
	height = temp;
    }


    if (fullscreen) {
	gs_addmess("gsview_fitwin: fullscreen not implemented\n");
	window_width = scroll_window->allocation.width;
	window_height = scroll_window->allocation.height;
    }
    else {
	/* get size including scroll bars area */
	window_width = scroll_window->allocation.width;
	window_height = scroll_window->allocation.height;
    }
    /* -4 is to allow for border around window */
    xdpi = (window_width - 4) * 72.0 / width;
    ydpi = (window_height - 4) * 72.0 / height;
    if (fullscreen) {
	xdpi2 = xdpi;
	ydpi2 = ydpi;
    }
    else {
	/* These are the resolutions allowing for a scroll bar */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -