--- texk/xdvik/special.c.orig 2020-02-25 20:42:58 UTC +++ texk/xdvik/special.c @@ -683,6 +683,12 @@ static size_t g_bbox_info_max_size = 0; contains these coordinates. */ +double bbox_matrix[2][2] = {{1.0, 0.0}, {0.0, 1.0}}; +Boolean bbox_scaled = False, bbox_rotated = False; + +#define bbox_xscale bbox_matrix[0][0] +#define bbox_yscale bbox_matrix[1][1] + static void append_bbox_info(int x, int y, int w, int h, int angle) { @@ -727,25 +733,25 @@ draw_bbox0(int xcorner, int ycorner) do_color_change(); #endif - if (bbox_angle == 0) { - ycorner -= bbox_voffset; - XDrawRectangle(DISP, currwin.win, globals.gc.high, xcorner, ycorner, bbox_width, bbox_height); + if (! bbox_rotated) { + ycorner -= bbox_voffset * bbox_yscale; + XDrawRectangle(DISP, currwin.win, globals.gc.high, xcorner, ycorner, + bbox_width * bbox_xscale, bbox_height * bbox_yscale); if (resource.postscript == 0) { if (htex_inside_href) { - htex_set_anchorsize(xcorner, ycorner, xcorner + bbox_width, ycorner + bbox_height); + htex_set_anchorsize(xcorner, ycorner, xcorner + bbox_width * bbox_xscale, + ycorner + bbox_height * bbox_yscale); htex_set_objecttype(HTEX_IMG); } } } else { - float sin_a = sin(bbox_angle * (TWOPI / 360)); - float cos_a = cos(bbox_angle * (TWOPI / 360)); float a, b, c, d; - a = cos_a * bbox_width; - b = -sin_a * bbox_width; - c = -sin_a * bbox_height; - d = -cos_a * bbox_height; + a = bbox_matrix[0][0] * bbox_width; + b = bbox_matrix[1][0] * bbox_width; + c = -bbox_matrix[0][1] * bbox_height; + d = -bbox_matrix[1][1] * bbox_height; XDrawLine(DISP, currwin.win, globals.gc.high, xcorner, ycorner, @@ -774,27 +780,27 @@ display_bboxes(void) size_t i; for (i = 0; i < g_bbox_info_size; i++) { - if (globals.debug & DBG_PS) { - fprintf(stderr, "drawing bbox %lu at %d %d, %d x %d, angle %d\n", - (unsigned long)i, - g_bbox_info[i].x, - g_bbox_info[i].y, - g_bbox_info[i].w, - g_bbox_info[i].h, - g_bbox_info[i].angle); - } + if (globals.debug & DBG_PS) { + fprintf(stderr, "drawing bbox %lu at %d %d, %d x %d, angle %d\n", + (unsigned long)i, + g_bbox_info[i].x, + g_bbox_info[i].y, + g_bbox_info[i].w, + g_bbox_info[i].h, + g_bbox_info[i].angle); + } #if 0 - XDrawRectangle(DISP, currwin.win, globals.gc.high, - g_bbox_info[i].x, - g_bbox_info[i].y, - g_bbox_info[i].w, - g_bbox_info[i].h); + XDrawRectangle(DISP, currwin.win, globals.gc.high, + g_bbox_info[i].x, + g_bbox_info[i].y, + g_bbox_info[i].w, + g_bbox_info[i].h); #else - bbox_valid = True; - bbox_width = g_bbox_info[i].w; - bbox_height = bbox_voffset = g_bbox_info[i].h; - bbox_angle = g_bbox_info[i].angle; - draw_bbox0(g_bbox_info[i].x, g_bbox_info[i].y + bbox_height); + bbox_valid = True; + bbox_width = g_bbox_info[i].w; + bbox_height = bbox_voffset = g_bbox_info[i].h; + bbox_angle = g_bbox_info[i].angle; + draw_bbox0(g_bbox_info[i].x, g_bbox_info[i].y + bbox_height); #endif } bbox_angle = 0; @@ -821,6 +827,9 @@ save_bbox(void) ycorner -= bbox_voffset; append_bbox_info(xcorner, ycorner, bbox_width, bbox_height, bbox_angle); + if (currwin.win == mane.win && resource.postscript != 1) { + draw_bbox(); + } /* register boundaries of this box as anchor boundaries */ if (htex_inside_href) { @@ -899,6 +908,11 @@ ps_startup2(void) } +typedef struct { + double matrix[2][2]; + double x, y; +} ROTATE_STACK; + /* * dumb parsing of PostScript - search for rotation H. Zeller 1/97 * Returns true if we find a potentially non-supported command that @@ -908,7 +922,53 @@ static Boolean ps_parseraw(const char *PostScript_cmd) { const char *p; + double xscale, yscale, angle, sin_a, cos_a, a, b, c, d; + int n; + static int rotate_stack_len = 0; + static int rotate_stack_ptr = 0; + static ROTATE_STACK *rotate_stack = NULL; + p = strstr(PostScript_cmd, "currentpoint grestore moveto"); + if (p != NULL) { + if (rotate_stack_ptr > 0) { + double r; + rotate_stack_ptr--; + r = sqrt(((DVI_H - rotate_stack[rotate_stack_ptr].x) + * (DVI_H - rotate_stack[rotate_stack_ptr].x) + + (DVI_V - rotate_stack[rotate_stack_ptr].y) + * (DVI_V - rotate_stack[rotate_stack_ptr].y)) + / (bbox_matrix[0][0] * bbox_matrix[0][0] + + bbox_matrix[1][0] * bbox_matrix[1][0])) + * (rotate_stack[rotate_stack_ptr].matrix[0][0] + * bbox_matrix[1][0] + - rotate_stack[rotate_stack_ptr].matrix[1][0] + * bbox_matrix[0][0]) + / (rotate_stack[rotate_stack_ptr].matrix[0][0] + * rotate_stack[rotate_stack_ptr].matrix[0][0] + + rotate_stack[rotate_stack_ptr].matrix[1][0] + * rotate_stack[rotate_stack_ptr].matrix[1][0]); + DVI_H += r * rotate_stack[rotate_stack_ptr].matrix[1][0]; + DVI_V += r * rotate_stack[rotate_stack_ptr].matrix[0][0]; + PXL_V = pixel_conv(DVI_V); + bcopy(rotate_stack[rotate_stack_ptr].matrix, bbox_matrix, + sizeof(bbox_matrix)); + bbox_rotated + = (bbox_matrix[0][1] != 0.0 || bbox_matrix[1][0] != 0.0) + ? True : False; + bbox_scaled + = (bbox_rotated + || bbox_matrix[0][0] != 1.0 || bbox_matrix[1][1] != 1.0) + ? True : False; + } + if (globals.debug & DBG_PS) + fprintf(stderr, "current angle %f: %s\n", + bbox_matrix[0][0] != 0 + ? -atan(bbox_matrix[1][0] / bbox_matrix[0][0]) + * (360 / TWOPI) + : bbox_matrix[1][0] >= 0 ? (double)90 : (double)-90, + PostScript_cmd); + } + bbox_angle = 0; p = strstr(PostScript_cmd, "rotate"); if (p != NULL) { @@ -916,9 +976,137 @@ ps_parseraw(const char *PostScript_cmd) --p; while (*p != '\0' && isdigit((int)*p)) --p; + if (*p == '.') --p; + while (*p != '\0' && isdigit(*p)) --p; if (*p != '+' && *p != '-') ++p; - sscanf(p, "%d neg rotate", &bbox_angle); + n = sscanf(p, "%lf neg rotate", &angle); + if (n != 1) { + fprintf(stderr, "%s: cannot get angle.\n", globals.program_name); + angle = 0.0; + } + bbox_angle = angle; + if (rotate_stack_ptr >= rotate_stack_len) { + rotate_stack_len += 0x10; + rotate_stack = (ROTATE_STACK *) + xrealloc(rotate_stack, + sizeof(ROTATE_STACK) * rotate_stack_len); + } + bcopy(bbox_matrix, rotate_stack[rotate_stack_ptr].matrix, + sizeof(bbox_matrix)); + rotate_stack[rotate_stack_ptr].x = DVI_H; + rotate_stack[rotate_stack_ptr].y = DVI_V; + rotate_stack_ptr++; + + sin_a = sin(-angle * (TWOPI / 360)); + cos_a = cos(-angle * (TWOPI / 360)); + a = bbox_matrix[0][0] * cos_a + bbox_matrix[0][1] * sin_a; + b = - bbox_matrix[0][0] * sin_a + bbox_matrix[0][1] * cos_a; + c = bbox_matrix[1][0] * cos_a + bbox_matrix[1][1] * sin_a; + d = - bbox_matrix[1][0] * sin_a + bbox_matrix[1][1] * cos_a; + bbox_matrix[0][0] = a; + bbox_matrix[0][1] = b; + bbox_matrix[1][0] = c; + bbox_matrix[1][1] = d; + bbox_rotated = (b != 0.0 || c != 0.0) ? True : False; + bbox_scaled + = (bbox_rotated + || bbox_matrix[0][0] != 1.0 || bbox_matrix[1][1] != 1.0) + ? True : False; + if (globals.debug & DBG_PS) + fprintf(stderr, "current angle %f: %s\n", + bbox_matrix[0][0] != 0 + ? -atan(bbox_matrix[1][0] / bbox_matrix[0][0]) + * (360 / TWOPI) + : bbox_matrix[1][0] >= 0 ? (double)90 : (double)-90, + PostScript_cmd); + } + + p = strstr(PostScript_cmd, "scale"); + if (p != NULL) { + if (strncmp(p - 4, "div", 3) == 0) { + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + if (*p == '.') --p; + while (*p != '\0' && isdigit(*p)) --p; + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + if (*p == '.') --p; + while (*p != '\0' && isdigit(*p)) --p; + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + ++p; + n = sscanf(p, "1 %lf div 1 %lf div scale", &xscale, &yscale); + if (n == 2) { +#ifdef PTEX + if(TATE) { + double temp; + temp = xscale; + xscale = 1.0/yscale; + yscale = 1.0/temp; + } + else { + xscale = 1.0/xscale; + yscale = 1.0/yscale; + } +#else + xscale = 1.0/xscale; + yscale = 1.0/yscale; +#endif + } else { + fprintf(stderr, + "%s: cannot get scaling factors.\n", + globals.program_name); + xscale = yscale = 1.0; + } + } else { + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + if (*p == '.') --p; + while (*p != '\0' && isdigit(*p)) --p; + while (*p != '\0' && !isdigit(*p)) --p; + while (*p != '\0' && isdigit(*p)) --p; + if (*p == '.') --p; + while (*p != '\0' && isdigit(*p)) --p; + if (*p != '+' && *p != '-') ++p; + n = sscanf(p, "%lf %lf scale", &xscale, &yscale); +#ifdef PTEX + if(TATE) { + double temp; + temp = xscale; + xscale = yscale; + yscale = temp; + } +#endif + if (n != 2) { + fprintf(stderr, + "%s: cannot get scaling factors.\n", + globals.program_name); + xscale = yscale = 1.0; + } + } + bbox_matrix[0][0] *= xscale; + bbox_matrix[0][1] *= yscale; + bbox_matrix[1][0] *= xscale; + bbox_matrix[1][1] *= yscale; + bbox_scaled + = (bbox_rotated + || bbox_matrix[0][0] != 1.0 || bbox_matrix[1][1] != 1.0) + ? True : False; + if (globals.debug & DBG_PS) + fprintf(stderr, "current scale %f,%f: %s\n", + bbox_xscale, bbox_yscale, PostScript_cmd); + angle = 0.0; + if (strstr(PostScript_cmd, "neg rotate")) { + n = sscanf(p, "%lf neg rotate", &angle); + if (n != 1) { + fprintf(stderr, "%s: cannot get angle. (%s)\n", globals.program_name,p); + angle = 0.0; + } + } + bbox_angle = angle; return True; } if (strstr(PostScript_cmd, " scale ") != NULL) @@ -1589,10 +1777,10 @@ psfig_special(char *cp) #endif /* also raw PostScript, but no extra colon to skip */ #if PS - if (INSIDE_MANE_WIN) { - if (ps_parseraw(cp)) + if (ps_parseraw(cp) && INSIDE_MANE_WIN) have_raw_postscript = True; + if (INSIDE_MANE_WIN) { if (psfig_begun) psp.drawraw(cp); else { @@ -2437,6 +2625,100 @@ scan_papersize(const char *cp0) } /* +** Modified 22/3/95. +*/ + +typedef struct psh_node { + char *this_file; + struct psh_node *next; +} t_pshnode; + +static t_pshnode *psh_head = (t_pshnode *) NULL, *psh_tail = (t_pshnode *) NULL; + +/* +** Include one header file. +*/ + +static void psh_includehfile(cp, beginning) +char *cp; +int beginning; + +{ + static char rawstring[] = " stop\n%%xdvimark\nH userdict begin\0"; + + if (!beginning) + psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y, ""); + psp.drawraw(rawstring); + send_ps_file(cp, kpse_pict_format); + psp.drawend(" end\n"); +} + +/* +** Include all header files. +*/ + +void psh_includeall() + +{ + t_pshnode *this_node; + + this_node = psh_head; + while (this_node != (t_pshnode *) NULL) { + psh_includehfile(this_node->this_file, 1); + this_node = this_node->next; + } +} + +/* +** Deal with the "header=" special. +*/ + +static void psh_header(cp) +char *cp; + +{ + t_pshnode *this_node; + char *psheader; + + /* + ** Find the file. + */ + + psheader = kpse_find_file ( cp+7, kpse_tex_ps_header_format, true ); + + if (psheader) { + + /* + ** Include the file directly in /userdict. + */ + + /* psh_includehfile(psheader, 0); */ + /* deleted by Kazuaki NAKAYAMA (nakayama@ripms.shinshu-u.ac.jp) */ + + /* + ** Add a new node to the list of header files. + */ + + this_node = (t_pshnode *) xmalloc(sizeof(t_pshnode)); + this_node->this_file = strcpy(xmalloc((strlen(psheader) + 1) * sizeof(char)), psheader); + this_node->next = (t_pshnode *) NULL; + if (psh_head == (t_pshnode *) NULL) + psh_head = psh_tail = this_node; + else { + psh_tail->next = this_node; + psh_tail = this_node; + } + + } else + XDVI_WARNING((stderr, "Included PostScript header file %s not found", cp + 7)); +} + +/* +** End Modifications +*/ + + +/* * The following copyright message applies to the rest of this file. --PV */ @@ -2659,6 +2941,8 @@ applicationDoSpecial(char *cp, size_t len) case CMD('b', 'k'): blacken_last(); return; + case CMD('h', 'e'): + psh_header(cp); return; case CMD('i', 'p'): /* throw away the path -- jansteen */ path_len = 0; return;