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

📄 gvx.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 4 页
字号:
/* These do not allow for the extra border provided by the scrolled_window */
/* We don't know how to obtain this extra width */
/*
	xdpi2 = (window_width - 
	    GTK_SCROLLED_WINDOW(scroll_window)->vscrollbar->allocation.width)
	    * 72.0 / width;
	ydpi2 = (window_height - 
	    GTK_SCROLLED_WINDOW(scroll_window)->hscrollbar->allocation.height)
	    * 72.0 / height;
*/
	ydpi2 = (window_height) * 72.0 / height;

	/* Assume scroll bar is 22 pixels wide */
	xdpi2 = (window_width - 22) * 72.0 / width;
	ydpi2 = (window_height - 22) * 72.0 / height;

    }

    if (display.orientation & 1) {
	/* page is rotated 90 degrees */
	float ftemp;
	ftemp = xdpi;
	xdpi = ydpi;
	ydpi = ftemp;
	ftemp = xdpi2;
	xdpi2 = ydpi2;
	ydpi2 = ftemp;
    }

    if ( ((xdpi + 0.5) > option.xdpi) && (xdpi - 0.5) < option.xdpi) {
	/* Width matches. Set size based on height. */
	if (fullscreen || (ydpi <= xdpi))
	    dpi = ydpi;
	else
	    dpi = ydpi2;
    }
    else if ( ((ydpi + 0.5) > option.ydpi) && (ydpi - 0.5) < option.ydpi) {
	/* Height matches. Set size based on width. */
	if (fullscreen || (xdpi <= ydpi))
	    dpi = xdpi;
	else
	    dpi = xdpi2;
    }
    else  {
	/* Neither width nor height match.  Fit the whole page. */
	if (xdpi > ydpi)
		dpi = ydpi;
	else
		dpi = xdpi;
    }
#ifdef DEBUG
    {
    char buf[MAXSTR];
    sprintf(buf, "\nwindow size=%d %d\n", 
    window_width, window_height);
    gs_addmess(buf);
    sprintf(buf, "size=%d %d\n", width, height);
    gs_addmess(buf);
    sprintf(buf, "old dpi=%f %f\n", option.xdpi, option.ydpi);
    gs_addmess(buf);
    sprintf(buf, "dpi=%f %f %f %f\n", xdpi, ydpi, xdpi2, ydpi2);
    gs_addmess(buf);
    sprintf(buf, "final dpi=%f\n", dpi);
    gs_addmess(buf);
    }
#endif
    option.xdpi = option.ydpi = dpi;
    gs_resize();
}

/* highlight words from first to last inclusive */
/* first may be > last */
/* word = -1 means nothing to mark */
void
highlight_words(int first, int last, BOOL marked)
{
    int left, right, top, bottom;
    float x, y;
    TEXTINDEX *text;
    GdkGC *gcinvert;
    int i;
    if ((first == -1) || (last == -1))
	return;

    if (!image.open)
	return;

    if ((first > (int)text_index_count) || (last > (int)text_index_count)) {
	gs_addmess("\nhighlight_words called with invalid arguments\n");
	return;
    }
    if (first > last) {
        int temp = first;
	first = last;
	last = temp;
    }

    gcinvert = gdk_gc_new(img->window);
    gdk_gc_set_function(gcinvert, GDK_INVERT);
    for (i = first; i<=last; i++) {
	text = &text_index[i];
	/* highlight found word */
	/* map bounding box to device coordinates */
	x = text->bbox.llx;
	y = text->bbox.lly;
	map_pt_to_pixel(&x, &y);
	left   = (int)x;
	bottom = (int)y;
	x = text->bbox.urx;
	y = 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;
	}

	/* redraw rectangle we about to invert */
	window_draw(img, left, top, right-left, bottom-top);

	if (marked) {
	    /* invert text */
	    gdk_draw_rectangle(img->window, gcinvert,
		    TRUE, left, top, right-left, bottom-top);
	}
    }
    gdk_gc_unref(gcinvert);
}


void
highlight_links()
{
PDFLINK link;
int i = 0;
float x, y;
int x0, y0, x1, y1;
int w2;
GdkGC *gclink = gdk_gc_new(img->window);
/* colour code doesn't work - we need to allocate a colour map first */
GdkColor red = {0, 65535, 0, 0};
    
    while ( pdf_get_link(i, &link) ) {
	i++;
	if (link.border_width) {
	    /* map bounding box to device coordinates */
	    x = link.bbox.llx;
	    y = link.bbox.lly;
	    map_pt_to_pixel(&x, &y);
	    x0   = (int)x;
	    y1   = (int)y;
	    x = link.bbox.urx;
	    y = link.bbox.ury;
	    map_pt_to_pixel(&x, &y);
	    x1   = (int)x;
	    y0   = (int)y;
	    if (y0 > y1) {
		int temp = y0;
		y0 = y1;
		y1 = temp;
	    }
	    if (x0 > x1)  {
		int temp = x1;
		x1 = x0;
		x0 = temp;
	    }
	    /* draw border */
	    if (link.colour_valid) {
		GdkColor colour = {0, 0, 0, 0};
		colour.red = (int)(link.colour_red*65535+0.5);
		colour.green = (int)(link.colour_green*65535+0.5);
		colour.blue = (int)(link.colour_blue*65535+0.5);
		gdk_gc_set_foreground(gclink, &colour);
	    }
	    else {
		gdk_gc_set_foreground(gclink, &red);
	    }
	    gdk_draw_rectangle(img->window, gclink, FALSE,
		x0, y0, x1-x0, y1-y0);

	    w2 = (int)((link.border_width+0.5)/2);
	    gdk_gc_set_line_attributes(gclink, w2, GDK_LINE_SOLID,
		GDK_CAP_BUTT, GDK_JOIN_MITER);
/*
	    RoundRect(hdc, rect.left-w2, rect.top-w2, 
		    rect.right+w2, rect.bottom+w2, 
		    2 * ((int)(link.border_xr+0.5)),
		    2 * ((int)(link.border_yr+0.5)));
*/
	}
    }
    gdk_gc_unref(gclink);
}


void
info_link(void)
{
float x, y;
PDFLINK link;
    if (get_cursorpos(&x, &y)) {
	if (is_link(x, y, &link)) {
	    on_link = TRUE;
	    on_link_page = link.page;
	    on_link_action = link.action;
	    statusbar_update();
	}
	else if (on_link)
	{
	    on_link = FALSE;
	    statusbar_update();
	}
    }
}

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

/* Save image to file */
/* doesn't work because of structure packing */
void
paste_to_file(void)
{
/* not implemented fully */
    LPBITMAP2 pbmih;
    BITMAPFILE bmfh;
    DWORD header_size;
    DWORD bitmap_size;
    FILE *f;
    PREBMAP pbmap;
    static char output[MAXSTR];

    image_lock(view.img);
    pbmih = get_bitmap();
    image_unlock(view.img);
    if (pbmih == (LPBITMAP2)NULL)
	 return;

    scan_dib(&pbmap, (BYTE *)pbmih);
    header_size = BITMAP2_LENGTH;
    bitmap_size = pbmap.height * pbmap.bytewidth;
    bmfh.bfType = ('M'<<8) | 'B';
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = header_size + BITMAPFILE_LENGTH;
    bmfh.bfSize = bitmap_size + bmfh.bfOffBits;

    if ( get_filename(output, TRUE, FILTER_BMP, 0, IDS_TOPICCLIP)
	&& ((f = fopen(output, "w")) != NULL) ) {
	fputc('B', f);
	fputc('M', f);
	write_dword(bmfh.bfSize, f);
	write_word(bmfh.bfReserved1, f);
	write_word(bmfh.bfReserved2, f);
	write_dword(bmfh.bfOffBits, f);
	fwrite(pbmih, 1, header_size + bitmap_size, f);
	fclose(f);
    }
    release_bitmap();
}


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

void show_buttons(void)
{
    if (option.button_show)
	gtk_widget_show(GTK_WIDGET(buttonbar));
    else
	gtk_widget_hide(GTK_WIDGET(buttonbar));
}

void set_scroll(int hscroll, int vscroll)
{
    GtkAdjustment *hadjust = gtk_scrolled_window_get_hadjustment(
	GTK_SCROLLED_WINDOW(scroll_window));
    GtkAdjustment *vadjust = gtk_scrolled_window_get_vadjustment(
	GTK_SCROLLED_WINDOW(scroll_window));
    hscroll = min(hscroll, (int)(hadjust->upper - hadjust->page_size));
    vscroll = min(vscroll, (int)(vadjust->upper - vadjust->page_size));
    if (hscroll >= 0)
	gtk_adjustment_set_value(gtk_scrolled_window_get_hadjustment(
	GTK_SCROLLED_WINDOW(scroll_window)), hscroll);
    if (vscroll >= 0)
	gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(
	GTK_SCROLLED_WINDOW(scroll_window)), vscroll);
}

/* if found word is not visible, scroll window to make it visible */
void scroll_to_find(void)
{
    float x, y;
    int left, right, top, bottom;
    int scrollx, scrolly;
    int window_width, window_height;

    BOOL changed = FALSE;

    /* first translate found box to window 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;

    /* get current scroll position */
    scrollx = (int)(gtk_scrolled_window_get_hadjustment(
	GTK_SCROLLED_WINDOW(scroll_window))->value);
    scrolly = (int)(gtk_scrolled_window_get_vadjustment(
	GTK_SCROLLED_WINDOW(scroll_window))->value);

    /* get current window size */
    /* this is approximate, since the scroll window size less the
     * scroll bar is larger than the client area
     */
    window_width = scroll_window->allocation.width -
	GTK_SCROLLED_WINDOW(scroll_window)->vscrollbar->allocation.width;
    window_height = scroll_window->allocation.height -
	GTK_SCROLLED_WINDOW(scroll_window)->hscrollbar->allocation.height;

    if ((left < scrollx) || (right > scrollx + window_width))
	changed = TRUE;
    if ((top < scrolly) || (bottom > scrolly + window_height))
	changed = TRUE;

    if (changed)
	set_scroll((left + right - window_width) / 2,
	    (top + bottom - window_height) / 2);
}


gint do_args_tag;

gint
do_args(gpointer data)
{
    GSVIEW_ARGS *pargs = &args;
    if (do_args_tag)
	gtk_idle_remove(do_args_tag);
    else
	return TRUE;	/* Ignore multiple calls */
    do_args_tag = 0;

    if (gsview_changed()) {
	gtk_main_quit();
	return TRUE;
    }

    registration_check();

    /* 
     * we had some command line options that couldn't be
     * be processed until the window was created.
     */

    if (pargs->print || pargs->convert) {
	make_cwd(pargs->filename);
	gsview_selectfile(pargs->filename);
	if (pargs->device[0]) {
	    if (pargs->print)
		strcpy(option.printer_device, pargs->device);
	    else
		strcpy(option.convert_device, pargs->device);
	}
	if ((pargs->queue[0]) && pargs->print)
	    strcpy(option.printer_queue, pargs->queue);
	if (dfreopen() != 0) {
	    release_mutex();
	    return 0;
	}
	if (psfile.name[0] != '\0') {
	    option.print_to_file = FALSE;
	    gsview_print(!pargs->print);
	}
	dfclose();
    }
    else if (pargs->spool) {
	gs_addmess("-s unsupported\n");
    }
    else  if (pargs->filename[0]) {
	make_cwd(pargs->filename);
	gsview_displayfile(pargs->filename);
	gsview_wcmd(NULL, (gpointer)0); 	/* give it a kick */
    }

    selection_add();

    return TRUE;
}


void *
gs_thread(void *arg)
{
    while (!quitnow) {
	if (!pending.now)
	    wait_event();
	if (!quitnow)
	    gs_process();
    }

    /* signal that we have finished */
    post_img_message(WM_QUIT, 0);   /* shut down application */
    return NULL;
}

int main( int argc, char *argv[] )
{
    int rc;
    /* This is gtk+-1.2 which doesn't support UTF-8 cleanly,
     * so remove it if set in LANG environment variable.
     * Our menus and strings are in a local codepage, not UTF-8.
     */
    char lang[MAXSTR];
    char *p;
    gchar *xdisplay;
    memset(lang, 0, sizeof(lang));
    strncpy(lang, "LANG=", 5);
    p = getenv("LANG");
    if (p) {
	strncpy(lang+5, p, sizeof(lang)-6);
	p = strchr(lang, '.');
    }
    if (p && ((strcmp(p, ".UTF-8") == 0) || (strcmp(p, ".utf8") == 0))) {
	*p = '\0';	/* remove UTF-8 */
 	putenv(lang);
    }
    pszLocale = gtk_set_locale();
    setlocale(LC_NUMERIC, "C");
    gtk_init (&argc, &argv);
    gdk_rgb_init();
    gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
    gtk_widget_set_default_visual(gdk_rgb_get_visual());
    xdisplay = gdk_get_display();
    xdisplay_local = (xdisplay[0] == ':');

    gs_getcwd(workdir, sizeof(workdir));

    rc = gsview_init(argc, argv);

    gs_addmessf("debug=%d\n", debug);
    if (rc < 0) {
	fprintf(stdout, "Initialisation failed\n");
	return 1;
    }
    else if (rc > 0) {
	return 0;	/* clean exit */
    }
    do_args_tag = gtk_idle_add(do_args, (gpointer)0);
    set_menu_sensitive();
    set_last_used();

#ifdef MULTITHREAD
    if (multithread) {
	/* start thread for displaying */
	if (pthread_create(&display.tid, NULL, gs_thread, NULL)) {
	    fprintf(stdout, "pthread_create failed\n");
	    return 1;
	}
    }
#endif

    /* test code for single threading */
    if (multithread) {
        gtk_main();
    }
    else {
        while (!quitnow) {
	    /* wait for event */
	    gtk_main_iteration();
	    if (pending.now) {
		gs_process();	/* start Ghostscript */
	    }
	}
    }

    close_img_message();
#ifdef MULTITHREAD
    if (multithread) {
	sem_destroy(&display.event);
	pthread_mutex_destroy(&image.hmutex);
	pthread_mutex_destroy(&hmutex_ps);
    }
#endif

    unload_pstoedit();
    measure_close();
    psfile_free(&psfile);
    pdf_free_link();
    if (option.settings && !print_silent)
	write_profile(); 
    else
	write_profile_last_files();	/* always save MRU files */
  
    return 0;
}

/* end of gvx.cpp */

⌨️ 快捷键说明

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