pdf_obj * spc_lookup_object (const char *key) { pdf_obj *value = NULL; pdf_coord cp; int k; ASSERT(named_objects); if (!key) return NULL; for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++); switch (k) { case K_OBJ__XPOS: cp.x = dvi_dev_xpos(); cp.y = 0.0; pdf_dev_transform(&cp, NULL); value = pdf_new_number(ROUND(cp.x, .01)); break; case K_OBJ__YPOS: cp.x = 0.0; cp.y = dvi_dev_ypos(); pdf_dev_transform(&cp, NULL); value = pdf_new_number(ROUND(cp.y, .01)); break; case K_OBJ__THISPAGE: value = pdf_doc_this_page(); break; case K_OBJ__PAGES: value = pdf_doc_page_tree(); break; case K_OBJ__NAMES: value = pdf_doc_names(); break; case K_OBJ__RESOURCES: value = pdf_doc_current_page_resources(); break; case K_OBJ__CATALOG: value = pdf_doc_catalog(); break; case K_OBJ__DOCINFO: value = pdf_doc_docinfo(); break; default: value = pdf_names_lookup_object(named_objects, key, strlen(key)); break; } /* spc_handler_pdfm_bead() in spc_pdfm.c controls NULL too. if (!value) { ERROR("Object reference %s not exist.", key); } */ return value; }
static void print_error (const char *name, struct spc_env *spe, struct spc_arg *ap) { const char *p; char ebuf[64]; int i; long pg = spe->pg; pdf_coord c; c.x = spe->x_user; c.y = spe->y_user; pdf_dev_transform(&c, NULL); if (ap->command && name) { WARN("Interpreting special command %s (%s) failed.", ap->command, name); WARN(">> at page=\"%ld\" position=\"(%g, %g)\" (in PDF)", pg, c.x, c.y); } for (i = 0, p = ap->base; i < 63 && p < ap->endptr; p++) { if (isprint((unsigned char)*p)) ebuf[i++] = *p; else if (i + 4 < 63) i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p); else break; } ebuf[i] = '\0'; if (ap->curptr < ap->endptr) { while (i-- > 60) ebuf[i] = '.'; } WARN(">> xxx \"%s\"", ebuf); if (ap->curptr < ap->endptr) { for (i = 0, p = ap->curptr; i < 63 && p < ap->endptr; p++) { if (isprint((unsigned char)*p)) ebuf[i++] = *p; else if (i + 4 < 63) i += sprintf(ebuf + i, "\\x%02x", (unsigned char)*p); else break; } ebuf[i] = '\0'; if (ap->curptr < ap->endptr) { while (i-- > 60) ebuf[i] = '.'; } WARN(">> Reading special command stopped around >>%s<<", ebuf); ap->curptr = ap->endptr; } }
int pdf_copy_clip (FILE *image_file, int pageNo, double x_user, double y_user) { pdf_obj *page_tree, *contents; int depth = 0, top = -1; const char *clip_path, *end_path; char *save_path, *temp; pdf_tmatrix M; double stack[6]; pdf_file *pf; pf = pdf_open(NULL, image_file); if (!pf) return -1; pdf_dev_currentmatrix(&M); pdf_invertmatrix(&M); M.e += x_user; M.f += y_user; page_tree = pdf_get_page_obj (pf, pageNo, NULL, NULL); if (!page_tree) { pdf_close(pf); return -1; } contents = pdf_get_page_content(page_tree); pdf_release_obj(page_tree); if (!contents) { pdf_close(pf); return -1; } pdf_doc_add_page_content(" ", 1); save_path = malloc(pdf_stream_length(contents) + 1); strncpy(save_path, (const char *) pdf_stream_dataptr(contents), pdf_stream_length(contents)); clip_path = save_path; end_path = clip_path + pdf_stream_length(contents); depth = 0; for (; clip_path < end_path; clip_path++) { int color_dimen = 0; /* silence uninitialized warning */ char *token; skip_white(&clip_path, end_path); if (clip_path == end_path) break; if (depth > 1) { if (*clip_path == 'q') depth++; if (*clip_path == 'Q') depth--; parse_ident(&clip_path, end_path); continue; } else if (*clip_path == '-' || *clip_path == '+' || *clip_path == '.' || isdigit((unsigned char)*clip_path)) { stack[++top] = strtod(clip_path, &temp); clip_path = temp; } else if (*clip_path == '[') { /* Ignore, but put a dummy value on the stack (in case of d operator) */ parse_pdf_array(&clip_path, end_path, pf); stack[++top] = 0; } else if (*clip_path == '/') { if (strncmp("/DeviceGray", clip_path, 11) == 0 || strncmp("/Indexed", clip_path, 8) == 0 || strncmp("/CalGray", clip_path, 8) == 0) { color_dimen = 1; continue; } else if (strncmp("/DeviceRGB", clip_path, 10) == 0 || strncmp("/CalRGB", clip_path, 7) == 0 || strncmp("/Lab", clip_path, 4) == 0) { color_dimen = 3; continue; } else if (strncmp("/DeviceCMYK", clip_path, 11) == 0) { color_dimen = 4; continue; } else { clip_path++; parse_ident(&clip_path, end_path); skip_white(&clip_path, end_path); token = parse_ident(&clip_path, end_path); if (strcmp(token, "gs") == 0) { continue; } return -1; } } else { int j; pdf_tmatrix T; pdf_coord p0, p1, p2, p3; token = parse_ident(&clip_path, end_path); for (j = 0; j < sizeof(pdf_operators) / sizeof(pdf_operators[0]); j++) if (strcmp(token, pdf_operators[j].token) == 0) break; if (j == sizeof(pdf_operators) / sizeof(pdf_operators[0])) { return -1; } switch (pdf_operators[j].opcode) { case 0: case -1: case -2: case -3: case -4: /* Just pop the stack and do nothing. */ top += pdf_operators[j].opcode; if (top < -1) return -1; break; case OP_SETCOLOR: top -= color_dimen; if (top < -1) return -1; break; case OP_CLOSEandCLIP: pdf_dev_closepath(); case OP_CLIP: #if 0 pdf_dev_clip(); #else pdf_dev_flushpath('W', PDF_FILL_RULE_NONZERO); #endif break; case OP_CONCATMATRIX: if (top < 5) return -1; T.f = stack[top--]; T.e = stack[top--]; T.d = stack[top--]; T.c = stack[top--]; T.b = stack[top--]; T.a = stack[top--]; pdf_concatmatrix(&M, &T); break; case OP_SETCOLORSPACE: /* Do nothing. */ break; case OP_RECTANGLE: if (top < 3) return -1; p1.y = stack[top--]; p1.x = stack[top--]; p0.y = stack[top--]; p0.x = stack[top--]; if (M.b == 0 && M.c == 0) { pdf_tmatrix M0; M0.a = M.a; M0.b = M.b; M0.c = M.c; M0.d = M.d; M0.e = 0; M0.f = 0; pdf_dev_transform(&p0, &M); pdf_dev_transform(&p1, &M0); pdf_dev_rectadd(p0.x, p0.y, p1.x, p1.y); } else { p2.x = p0.x + p1.x; p2.y = p0.y + p1.y; p3.x = p0.x; p3.y = p0.y + p1.y; p1.x += p0.x; p1.y = p0.y; pdf_dev_transform(&p0, &M); pdf_dev_transform(&p1, &M); pdf_dev_transform(&p2, &M); pdf_dev_transform(&p3, &M); pdf_dev_moveto(p0.x, p0.y); pdf_dev_lineto(p1.x, p1.y); pdf_dev_lineto(p2.x, p2.y); pdf_dev_lineto(p3.x, p3.y); pdf_dev_closepath(); } break; case OP_CURVETO: if (top < 5) return -1; p0.y = stack[top--]; p0.x = stack[top--]; pdf_dev_transform(&p0, &M); p1.y = stack[top--]; p1.x = stack[top--]; pdf_dev_transform(&p1, &M); p2.y = stack[top--]; p2.x = stack[top--]; pdf_dev_transform(&p2, &M); pdf_dev_curveto(p2.x, p2.y, p1.x, p1.y, p0.x, p0.y); break; case OP_CLOSEPATH: pdf_dev_closepath(); break; case OP_LINETO: if (top < 1) return -1; p0.y = stack[top--]; p0.x = stack[top--]; pdf_dev_transform(&p0, &M); pdf_dev_lineto(p0.x, p0.y); break; case OP_MOVETO: if (top < 1) return -1; p0.y = stack[top--]; p0.x = stack[top--]; pdf_dev_transform(&p0, &M); pdf_dev_moveto(p0.x, p0.y); break; case OP_NOOP: pdf_doc_add_page_content(" n", 2); break; case OP_GSAVE: depth++; break; case OP_GRESTORE: depth--; break; case OP_CURVETO1: if (top < 3) return -1; p0.y = stack[top--]; p0.x = stack[top--]; pdf_dev_transform(&p0, &M); p1.y = stack[top--]; p1.x = stack[top--]; pdf_dev_transform(&p1, &M); pdf_dev_vcurveto(p1.x, p1.y, p0.x, p0.y); break; case OP_CURVETO2: if (top < 3) return -1; p0.y = stack[top--]; p0.x = stack[top--]; pdf_dev_transform(&p0, &M); p1.y = stack[top--]; p1.x = stack[top--]; pdf_dev_transform(&p1, &M); pdf_dev_ycurveto(p1.x, p1.y, p0.x, p0.y); break; default: return -1; } } } free(save_path); pdf_release_obj(contents); pdf_close(pf); return 0; }
/* * The following routine returns copies, not the original object. */ pdf_obj * spc_lookup_reference (const char *key) { pdf_obj *value = NULL; pdf_coord cp; int k; ASSERT(named_objects); if (!key) return NULL; for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++); switch (k) { /* xpos and ypos must be position in device space here. */ case K_OBJ__XPOS: cp.x = dvi_dev_xpos(); cp.y = 0.0; pdf_dev_transform(&cp, NULL); value = pdf_new_number(ROUND(cp.x, .01)); break; case K_OBJ__YPOS: cp.x = 0.0; cp.y = dvi_dev_ypos(); pdf_dev_transform(&cp, NULL); value = pdf_new_number(ROUND(cp.y, .01)); break; case K_OBJ__THISPAGE: value = pdf_doc_this_page_ref(); break; case K_OBJ__PREVPAGE: value = pdf_doc_prev_page_ref(); break; case K_OBJ__NEXTPAGE: value = pdf_doc_next_page_ref(); break; case K_OBJ__PAGES: value = pdf_ref_obj(pdf_doc_page_tree()); break; case K_OBJ__NAMES: value = pdf_ref_obj(pdf_doc_names()); break; case K_OBJ__RESOURCES: value = pdf_ref_obj(pdf_doc_current_page_resources()); break; case K_OBJ__CATALOG: value = pdf_ref_obj(pdf_doc_catalog()); break; case K_OBJ__DOCINFO: value = pdf_ref_obj(pdf_doc_docinfo()); break; default: if (ispageref(key)) value = pdf_doc_ref_page(atoi(key + 4)); else { value = pdf_names_lookup_reference(named_objects, key, strlen(key)); } break; } if (!value) { ERROR("Object reference %s not exist.", key); } return value; }