📄 gvx.c
字号:
/* 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 + -