shithub: pdffs

ref: a4a05ae434545d03ea8981e7aa4cc215bee577d7
dir: /main.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <ctype.h>
#include <bio.h>
#include <flate.h>
#include <draw.h>
#include <memdraw.h>
#include "pdf.h"

int mainstacksize = 128*1024;

static void
usage(void)
{
	fprint(2, "usage: %s FILE\n", argv0);
	threadexitsall("usage");
}

static int
dumppage(Object *page, int text)
{
	int ret;
	Page p;
	pageinit(&p, page);
	ret = pagerender(&p);
	if(ret){
		if(text){
			if(p.buf.sz != 0)
				fprint(1, "%s", (char*)p.buf.b);
		}else
			writememimage(1, p.image);
	}
	pagefree(&p);
	return ret;
}

static int
dumppages(Object *pages, int text)
{
	Object *page, *kids, *type;
	int i, count;
	kids = dictget(pages, "Kids");
	count = arraylen(kids);
	for(i = 0; i < count; i += 1){
		page = arrayget(kids, i);
		// Must be a dict, either Page or Pages
		type = dictget(page, "Type");
		// MUST be a name.
		if(strcmp(type->name, "Pages") == 0){
			if(!dumppages(page, text))
				return 0;
		}
		else if(strcmp(type->name, "Page") == 0){
			if(!dumppage(page, text))
				return 0;
			if(text)
				print("\n");
		}
		else
			sysfatal("Unexpected page node type '%s'", type->name);
	}
	return 1;
}


void
threadmain(int argc, char **argv)
{
	Object *v, o;
	Biobuf *b;
	Stream *s;
	Pdf *pdf;
	int i, n, k, nodump;

	quotefmtinstall();
	inflateinit();
	memimageinit();
	threadwaitchan();
	if(memimageinit() != 0)
		sysfatal("failed to initialize graphics: %r");

	ARGBEGIN{
	default:
		usage();
	}ARGEND
	
	nodump = 0;

	if(argc < 1)
		usage();
	if((b = Bopen(argv[0], OREAD|OCEXEC)) == nil)
		sysfatal("%r");
	if((pdf = pdfopen(b)) == nil)
		sysfatal("%s: %r", argv[0]);
	for(v = pdf->top, i = 1; v != nil && i < argc; i++){
		if(isdigit(argv[i][0])){
			n = atoi(argv[i]);
			v = arrayget(v, n);
		}else if((argv[i][0] == '.' || argv[i][0] == '!') && argv[i][1] == 0 && v->type == Ostream){
			Memimage *m;
			if((s = Sopen(v)) == nil)
				sysfatal("%r");
			if(argv[i][0] != '!' && (m = Sgetmemimage(s)) != nil){
				writememimage(1, m);
				freememimage(m);
			}else if(write(1, s->buf.b, s->buf.sz) != s->buf.sz){
				sysfatal("write failed");
			}
			Sclose(s);
			v = nil;
			break;
		}else if(argv[i][0] == '!' && argv[i][1] == 0 && v->type == Odict && strcmp(dictget(v, "Type")->name, "Page") == 0){
			if(!dumppage(v, 0))
				fprint(2, "page dump failed: %r\n");
			nodump = 1;
			break;
		}else if(argv[i][0] == '"' && argv[i][1] == 0 && v->type == Odict && strcmp(dictget(v, "Type")->name, "Page") == 0){
			if(!dumppage(v, 1))
				fprint(2, "page dump failed: %r\n");
			nodump = 1;
			break;
		}else if(argv[i][0] == '"' && argv[i][1] == 0 && v->type == Odict && strcmp(dictget(v, "Type")->name, "Pages") == 0){
			if(!dumppages(v, 1))
				fprint(2, "page dump failed: %r\n");
			nodump = 1;
			break;
		}else if(argv[i][0] == '*' && argv[i][1] == 0 && v->type == Odict){
			for(k = 0; k < v->dict.nkv; k++)
				print("%s\n", v->dict.kv[k].key);
			v = nil;
			break;
		}else if(argv[i][0] == '@' && argv[i][1] == 0 && v->type == Ostream){
			fprint(2, "%d %d\n", v->stream.off, v->stream.len);
			v = nil;
			break;
		}else if(argv[i][0] == '@' && isdigit(argv[i][1])){
			o.ref = 1;
			o.pdf = pdf;
			o.type = Oindir;
			o.indir.id = atoi(argv[i]+1);
			pdfeval(&o);
		}else{
			v = dictget(v, argv[i]);
		}
	}
	if(nodump){}
	else if(v == &null)
		fprint(2, "%r\n");
	else if(v != nil)
		print("%O\n", v);

/*
	if((v = dictget(pdf->info, "Creator")) != nil)
		fprint(2, "creator: %s\n", v->str);
	if((v = dictget(pdf->info, "Producer")) != nil)
		fprint(2, "producer: %s\n", v->str);
*/
	pdfclose(pdf);

	threadexitsall(nil);
}