summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile2
-rw-r--r--TODO20
-rw-r--r--apps/common/pdfapp.c23
-rw-r--r--fitz/node_tolisp.c (renamed from fitz/node_debug.c)0
-rw-r--r--fitz/node_toxml.c206
-rw-r--r--include/mupdf/page.h4
-rw-r--r--mupdf/pdf_unicode.c48
7 files changed, 273 insertions, 30 deletions
diff --git a/Jamfile b/Jamfile
index 6aa3b422..4fd7b673 100644
--- a/Jamfile
+++ b/Jamfile
@@ -98,7 +98,7 @@ Library libfitz :
base_rect.c
base_rune.c
- node_debug.c
+ node_toxml.c
node_misc1.c
node_misc2.c
node_optimize.c
diff --git a/TODO b/TODO
index cb9c1fc1..35e7e9a8 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,24 @@
cmap one-to-many mapping
+builtin standard cmap files
+put unicode strings in text object, not font
+
+xml parser
+unicode normaliser
+
+path stroke/dash/flatten work on real path struct
+turn into gel as second step after stroke/flatten
+add intersector for metro union/xor/difference stuff
+
+image rescale to exact size instead of by integer quantas
+
+public / private api
+
+top-level "driver" architecture (metro/pdf/whatever input)
+
+---
immediate plan:
- * design gui for editor
- * libfontfocus
- * write mupdf hackers guide
* clean up and 'freeze' public api
* get font bbox from fontdescriptor if available
diff --git a/apps/common/pdfapp.c b/apps/common/pdfapp.c
index d7bed118..ef342b43 100644
--- a/apps/common/pdfapp.c
+++ b/apps/common/pdfapp.c
@@ -394,6 +394,15 @@ void pdfapp_onkey(pdfapp_t *app, int c)
pdfapp_showpage(app, 0, 1);
break;
+ case 'a':
+ app->rotate -= 15;
+ pdfapp_showpage(app, 0, 1);
+ break;
+ case 's':
+ app->rotate += 15;
+ pdfapp_showpage(app, 0, 1);
+ break;
+
/*
* Pan view, but dont need to repaint image
*/
@@ -602,9 +611,11 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
{
fz_error *error;
pdf_textline *line, *ln;
- int x, y, c;
+ int y, c;
int i, p;
+ int bx0, bx1, by0, by1;
+
int x0 = app->image->x + app->selr.x0 - app->panx;
int x1 = app->image->x + app->selr.x1 - app->panx;
int y0 = app->image->y + app->selr.y0 - app->pany;
@@ -620,17 +631,19 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
y = y0 - 1;
for (i = 0; i < ln->len; i++)
{
- x = ln->text[i].x;
- y = ln->text[i].y;
+ bx0 = ln->text[i].bbox.x0;
+ bx1 = ln->text[i].bbox.x1;
+ by0 = ln->text[i].bbox.y0;
+ by1 = ln->text[i].bbox.y1;
c = ln->text[i].c;
if (c < 32)
c = '?';
- if (x >= x0 && x <= x1 && y >= y0 && y <= y1)
+ if (bx1 >= x0 && bx0 <= x1 && by1 >= y0 && by0 <= y1)
if (p < ucslen - 1)
ucsbuf[p++] = c;
}
- if (y >= y0 && y <= y1)
+ if (by1 >= y0 && by0 <= y1)
{
#ifdef WIN32
if (p < ucslen - 1)
diff --git a/fitz/node_debug.c b/fitz/node_tolisp.c
index b03d4e28..b03d4e28 100644
--- a/fitz/node_debug.c
+++ b/fitz/node_tolisp.c
diff --git a/fitz/node_toxml.c b/fitz/node_toxml.c
new file mode 100644
index 00000000..04a00423
--- /dev/null
+++ b/fitz/node_toxml.c
@@ -0,0 +1,206 @@
+#include <fitz.h>
+
+static void indent(int level)
+{
+ while (level--)
+ putchar(' ');
+}
+
+static void xmlnode(fz_node *node, int level);
+
+static void xmlmeta(fz_metanode *node, int level)
+{
+ fz_node *child;
+
+ indent(level);
+ printf("<meta");
+ if (node->name)
+ {
+ printf(" name=\"");
+ fz_debugobj(node->name);
+ printf("\" ");
+ }
+ printf(">\n");
+
+ for (child = node->super.first; child; child = child->next)
+ xmlnode(child, level + 1);
+
+ indent(level);
+ printf("</meta>\n");
+}
+
+static void xmlover(fz_overnode *node, int level)
+{
+ fz_node *child;
+ indent(level);
+ printf("<over>\n");
+ for (child = node->super.first; child; child = child->next)
+ xmlnode(child, level + 1);
+ indent(level);
+ printf("</over>\n");
+}
+
+static void xmlmask(fz_masknode *node, int level)
+{
+ fz_node *child;
+ indent(level);
+ printf("<mask>\n");
+ for (child = node->super.first; child; child = child->next)
+ xmlnode(child, level + 1);
+ indent(level);
+ printf("</mask>\n");
+}
+
+static void xmlblend(fz_blendnode *node, int level)
+{
+ fz_node *child;
+ indent(level);
+ printf("<blend mode=\"%d\">\n", node->mode);
+ for (child = node->super.first; child; child = child->next)
+ xmlnode(child, level + 1);
+ indent(level);
+ printf("</blend>\n");
+}
+
+static void xmltransform(fz_transformnode *node, int level)
+{
+ indent(level);
+ printf("<transform matrix=\"%g %g %g %g %g %g\">\n",
+ node->m.a, node->m.b,
+ node->m.c, node->m.d,
+ node->m.e, node->m.f);
+ xmlnode(node->super.first, level + 1);
+ indent(level);
+ printf("</transform>\n");
+}
+
+static void xmlcolor(fz_colornode *node, int level)
+{
+ int i;
+ indent(level);
+ printf("<solid colorspace=\"%s\" v=\"", node->cs->name);
+ for (i = 0; i < node->n; i++)
+ {
+ printf("%g", node->samples[i]);
+ if (i < node->n - 1)
+ putchar(' ');
+ }
+ printf("\" />\n");
+}
+
+static void xmllink(fz_linknode *node, int level)
+{
+ indent(level);
+ printf("<link name=\"%p\" />\n", node->tree);
+}
+
+static void xmlpath(fz_pathnode *node, int level)
+{
+ int i;
+
+ indent(level);
+
+ if (node->paint == FZ_STROKE)
+ {
+ printf("<path fill=\"stroke\" cap=\"%d\" join=\"%d\" width=\"%g\" miter=\"%g\"",
+ node->linecap,
+ node->linejoin,
+ node->linewidth,
+ node->miterlimit);
+ if (node->dash)
+ {
+ printf(" phase=\"%g\" array=\"", node->dash->phase);
+ for (i = 0; i < node->dash->len; i++)
+ printf("%g ", node->dash->array[i]);
+ printf("\"");
+ }
+ printf(">\n");
+ }
+ else
+ {
+ printf("<path fill=\"%s\">\n",
+ node->paint == FZ_FILL ? "nonzero" : "evenodd");
+ }
+
+ fz_debugpathnode(node);
+
+ indent(level);
+ printf("</path>\n");
+}
+
+static void xmltext(fz_textnode *node, int level)
+{
+ int i;
+
+ indent(level);
+ printf("<text font=\"%s\" matrix=\"%g %g %g %g\">\n", node->font->name,
+ node->trm.a, node->trm.b, node->trm.c, node->trm.d);
+
+ for (i = 0; i < node->len; i++)
+ {
+ indent(level + 1);
+ if (node->els[i].cid >= 32 && node->els[i].cid < 128)
+ printf("<g c=\"%c\" x=\"%g\" y=\"%g\" />\n",
+ node->els[i].cid, node->els[i].x, node->els[i].y);
+ else
+ printf("<g c=\"<%04x>\" x=\"%g\" y=\"%g\" />\n",
+ node->els[i].cid, node->els[i].x, node->els[i].y);
+ }
+
+ indent(level);
+ printf("</text>\n");
+}
+
+static void xmlimage(fz_imagenode *node, int level)
+{
+ fz_image *image = node->image;
+ indent(level);
+ printf("<image w=\"%d\" h=\"%d\" n=\"%d\" a=\"%d\" />\n",
+ image->w, image->h, image->n, image->a);
+}
+
+static void xmlshade(fz_shadenode *node, int level)
+{
+ indent(level);
+ printf("<shade />\n");
+}
+
+static void xmlnode(fz_node *node, int level)
+{
+ if (!node)
+ {
+ indent(level);
+ printf("<nil />\n");
+ return;
+ }
+
+ switch (node->kind)
+ {
+ case FZ_NMETA: xmlmeta((fz_metanode*)node, level); break;
+ case FZ_NOVER: xmlover((fz_overnode*)node, level); break;
+ case FZ_NMASK: xmlmask((fz_masknode*)node, level); break;
+ case FZ_NBLEND: xmlblend((fz_blendnode*)node, level); break;
+ case FZ_NTRANSFORM: xmltransform((fz_transformnode*)node, level); break;
+ case FZ_NCOLOR: xmlcolor((fz_colornode*)node, level); break;
+ case FZ_NPATH: xmlpath((fz_pathnode*)node, level); break;
+ case FZ_NTEXT: xmltext((fz_textnode*)node, level); break;
+ case FZ_NIMAGE: xmlimage((fz_imagenode*)node, level); break;
+ case FZ_NSHADE: xmlshade((fz_shadenode*)node, level); break;
+ case FZ_NLINK: xmllink((fz_linknode*)node, level); break;
+ }
+}
+
+void
+fz_debugnode(fz_node *node)
+{
+ xmlnode(node, 0);
+}
+
+void
+fz_debugtree(fz_tree *tree)
+{
+ printf("<tree>\n");
+ xmlnode(tree->root, 1);
+ printf("</tree>\n");
+}
+
diff --git a/include/mupdf/page.h b/include/mupdf/page.h
index 4304fa22..57aae34a 100644
--- a/include/mupdf/page.h
+++ b/include/mupdf/page.h
@@ -27,12 +27,12 @@ struct pdf_page_s
struct pdf_textchar_s
{
- int x, y, c;
+ fz_irect bbox;
+ int c;
};
struct pdf_textline_s
{
- fz_point height;
int len, cap;
pdf_textchar *text;
pdf_textline *next;
diff --git a/mupdf/pdf_unicode.c b/mupdf/pdf_unicode.c
index c9cc0807..1df96667 100644
--- a/mupdf/pdf_unicode.c
+++ b/mupdf/pdf_unicode.c
@@ -99,8 +99,6 @@ pdf_newtextline(pdf_textline **linep)
line = *linep = fz_malloc(sizeof(pdf_textline));
if (!line)
return fz_outofmem;
- line->height.x = 0; /* bad default value... */
- line->height.y = 10;
line->len = 0;
line->cap = 0;
line->text = nil;
@@ -118,7 +116,7 @@ pdf_droptextline(pdf_textline *line)
}
static fz_error *
-addtextchar(pdf_textline *line, int x, int y, int c)
+addtextchar(pdf_textline *line, fz_irect bbox, int c)
{
pdf_textchar *newtext;
int newcap;
@@ -133,8 +131,7 @@ addtextchar(pdf_textline *line, int x, int y, int c)
line->text = newtext;
}
- line->text[line->len].x = x;
- line->text[line->len].y = y;
+ line->text[line->len].bbox = bbox;
line->text[line->len].c = c;
line->len ++;
@@ -158,19 +155,15 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
fz_matrix trm;
float dx, dy, t;
fz_point p;
+ fz_point vx;
+ fz_point vy;
fz_vmtx v;
fz_hmtx h;
- int i, g, x, y;
+ int i, g;
+ int x, y;
+ fz_irect box;
int c;
- /* get line height */
- trm = fz_concat(tm, ctm);
- trm.e = 0;
- trm.f = 0;
- p.x = 0;
- p.y = 1;
- (*line)->height = fz_transformpoint(trm, p);
-
for (i = 0; i < text->len; i++)
{
g = text->els[i].cid;
@@ -178,8 +171,10 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
tm.e = text->els[i].x;
tm.f = text->els[i].y;
trm = fz_concat(tm, ctm);
- x = fz_floor(trm.e);
- y = fz_floor(trm.f);
+ x = trm.e;
+ y = trm.f;
+ trm.e = 0;
+ trm.f = 0;
p.x = text->els[i].x;
p.y = text->els[i].y;
@@ -192,12 +187,18 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
{
h = fz_gethmtx(text->font, g);
oldpt.x += h.w * 0.001;
+
+ vx.x = h.w * 0.001; vx.y = 0;
+ vy.x = 0; vy.y = 1;
}
else
{
v = fz_getvmtx(text->font, g);
- oldpt.y += v.w;
+ oldpt.y += v.w * 0.001;
t = dy; dy = dx; dx = t;
+
+ vx.x = 0.5; vx.y = 0;
+ vy.x = 0; vy.y = v.w * 0.001;
}
if (fabs(dy) > 0.2)
@@ -211,11 +212,20 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
}
else if (fabs(dx) > 0.2)
{
- error = addtextchar(*line, x, y, ' ');
+ box.x0 = x; box.x1 = x;
+ box.y0 = y; box.y1 = y;
+ error = addtextchar(*line, box, ' ');
if (error)
return error;
}
+ vx = fz_transformpoint(trm, vx);
+ vy = fz_transformpoint(trm, vy);
+ box.x0 = MIN(0, MIN(vx.x, vy.x)) + x;
+ box.x1 = MAX(0, MAX(vx.x, vy.x)) + x;
+ box.y0 = MIN(0, MIN(vx.y, vy.y)) + y;
+ box.y1 = MAX(0, MAX(vx.y, vy.y)) + y;
+
if (font->tounicode)
c = fz_lookupcid(font->tounicode, g);
else if (g < font->ncidtoucs)
@@ -223,7 +233,7 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
else
c = g;
- error = addtextchar(*line, x, y, c);
+ error = addtextchar(*line, box, c);
if (error)
return error;
}