summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2013-02-26 16:13:51 +0000
committerRobin Watts <robin.watts@artifex.com>2013-02-26 19:02:01 +0000
commit5bf497485a597a866bb5c149ef02f2b10b74e1ea (patch)
tree3fbe1e53eba034f300e718db52c31ad06abf5d9f
parentdf1f7eb75709a95fdf3838976ebdf49a46430c3b (diff)
downloadmupdf-5bf497485a597a866bb5c149ef02f2b10b74e1ea.tar.xz
Include required quadPoints entry in created markup annotations.
Also change the way we pass the text rectangles so that non-axis-aligned ones can be permitted, and relocate the code that calculates the strike-out lines from the bounding boxes
-rw-r--r--android/jni/mupdf.c87
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFCore.java6
-rw-r--r--android/src/com/artifex/mupdfdemo/MuPDFPageView.java25
-rw-r--r--android/src/com/artifex/mupdfdemo/PageView.java2
-rw-r--r--fitz/doc_interactive.c5
-rw-r--r--fitz/fitz-internal.h5
-rw-r--r--pdf/mupdf-internal.h1
-rw-r--r--pdf/pdf_annot.c25
8 files changed, 99 insertions, 57 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index 88c7a8c6..f5abf328 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -32,6 +32,9 @@
#define MAX_SEARCH_HITS (500)
#define NUM_CACHE (3)
+#define STRIKE_HEIGHT (0.375f)
+#define LINE_THICKNESS (0.07f)
+#define SMALL_FLOAT (0.00001)
enum
{
@@ -1360,16 +1363,17 @@ JNI_FN(MuPDFCore_textAsHtml)(JNIEnv * env, jobject thiz)
}
JNIEXPORT void JNICALL
-JNI_FN(MuPDFCore_addStrikeOutAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray lines)
+JNI_FN(MuPDFCore_addStrikeOutAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray points)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
fz_interactive *idoc = fz_interact(doc);
page_cache *pc = &glo->pages[glo->current];
- jclass rect_cls;
- jfieldID x0_fid, y0_fid, x1_fid, y1_fid;
+ jclass pt_cls;
+ jfieldID x_fid, y_fid;
int i, n;
+ fz_point *pts = NULL;
fz_path *path = NULL;
fz_stroke_state *stroke = NULL;
fz_device *dev = NULL;
@@ -1380,6 +1384,7 @@ JNI_FN(MuPDFCore_addStrikeOutAnnotationInternal)(JNIEnv * env, jobject thiz, job
strike_list = fz_new_display_list(ctx);
+ fz_var(pts);
fz_var(path);
fz_var(stroke);
fz_var(dev);
@@ -1392,45 +1397,53 @@ JNI_FN(MuPDFCore_addStrikeOutAnnotationInternal)(JNIEnv * env, jobject thiz, job
float zoom = glo->resolution / 72;
zoom = 1.0 / zoom;
fz_scale(&ctm, zoom, zoom);
- LOGI("P1 %f", zoom);
- rect_cls = (*env)->FindClass(env, "android.graphics.RectF");
- if (rect_cls == NULL) fz_throw(ctx, "FindClass");
- LOGI("P2");
- x0_fid = (*env)->GetFieldID(env, rect_cls, "left", "F");
- if (x0_fid == NULL) fz_throw(ctx, "GetFieldID(left)");
- LOGI("P3");
- y0_fid = (*env)->GetFieldID(env, rect_cls, "top", "F");
- if (y0_fid == NULL) fz_throw(ctx, "GetFieldID(top)");
- LOGI("P4");
- x1_fid = (*env)->GetFieldID(env, rect_cls, "right", "F");
- if (x1_fid == NULL) fz_throw(ctx, "GetFieldID(right)");
- LOGI("P5");
- y1_fid = (*env)->GetFieldID(env, rect_cls, "bottom", "F");
- if (y1_fid == NULL) fz_throw(ctx, "GetFieldID(bottom)");
- LOGI("P6");
-
- n = (*env)->GetArrayLength(env, lines);
- LOGI("nlines=%d", n);
+ pt_cls = (*env)->FindClass(env, "android.graphics.PointF");
+ if (pt_cls == NULL) fz_throw(ctx, "FindClass");
+ x_fid = (*env)->GetFieldID(env, pt_cls, "x", "F");
+ if (x_fid == NULL) fz_throw(ctx, "GetFieldID(x)");
+ y_fid = (*env)->GetFieldID(env, pt_cls, "y", "F");
+ if (y_fid == NULL) fz_throw(ctx, "GetFieldID(y)");
+
+ n = (*env)->GetArrayLength(env, points);
+
+ pts = fz_malloc_array(ctx, n, sizeof(fz_point));
dev = fz_new_list_device(ctx, strike_list);
for (i = 0; i < n; i++)
{
- jobject line = (*env)->GetObjectArrayElement(env, lines, i);
- float x0 = (*env)->GetFloatField(env, line, x0_fid);
- float y0 = (*env)->GetFloatField(env, line, y0_fid);
- float x1 = (*env)->GetFloatField(env, line, x1_fid);
- float y1 = (*env)->GetFloatField(env, line, y1_fid);
- float vcenter = (y0 + y1)/2;
- float thickness = y1 - y0;
-
- if (!stroke || stroke->linewidth != thickness)
+ jobject opt = (*env)->GetObjectArrayElement(env, points, i);
+ pts[i].x = opt ? (*env)->GetFloatField(env, opt, x_fid) : 0.0f;
+ pts[i].y = opt ? (*env)->GetFloatField(env, opt, y_fid) : 0.0f;
+ }
+
+ annot = fz_create_annot(idoc, pc->page, FZ_ANNOT_STRIKEOUT);
+
+ fz_set_markup_annot_quadpoints(idoc, annot, pts, n);
+
+ for (i = 0; i < n; i += 4)
+ {
+ fz_point pt0 = pts[i];
+ fz_point pt1 = pts[i+1];
+ fz_point up;
+ float thickness;
+
+ up.x = pts[i+2].x - pts[i+1].x;
+ up.y = pts[i+2].y - pts[i+1].y;
+
+ pt0.x += STRIKE_HEIGHT * up.x;
+ pt0.y += STRIKE_HEIGHT * up.y;
+ pt1.x += STRIKE_HEIGHT * up.x;
+ pt1.y += STRIKE_HEIGHT * up.y;
+
+ thickness = sqrtf(up.x * up.x + up.y * up.y) * LINE_THICKNESS;
+
+ if (!stroke || fz_abs(stroke->linewidth - thickness) < SMALL_FLOAT)
{
if (stroke)
{
// assert(path)
fz_stroke_path(dev, path, stroke, &ctm, fz_device_rgb, color, 1.0);
- LOGI("Path stroked");
fz_drop_stroke_state(ctx, stroke);
stroke = NULL;
fz_free_path(ctx, path);
@@ -1438,29 +1451,25 @@ JNI_FN(MuPDFCore_addStrikeOutAnnotationInternal)(JNIEnv * env, jobject thiz, job
}
stroke = fz_new_stroke_state(ctx);
- LOGI("thickness(%f)", thickness);
stroke->linewidth = thickness;
path = fz_new_path(ctx);
}
- fz_moveto(ctx, path, x0, vcenter);
- LOGI("moveto(%f,%f)", x0, vcenter);
- fz_lineto(ctx, path, x1, vcenter);
- LOGI("lineto(%f,%f)", x1, vcenter);
+ fz_moveto(ctx, path, pt0.x, pt0.y);
+ fz_lineto(ctx, path, pt1.x, pt1.y);
}
if (stroke)
{
fz_stroke_path(dev, path, stroke, &ctm, fz_device_rgb, color, 1.0);
- LOGI("Path stroked");
}
- annot = fz_create_annot(idoc, pc->page, FZ_ANNOT_STRIKEOUT);
fz_set_annot_appearance(idoc, annot, strike_list);
dump_annotation_display_lists(glo);
}
fz_always(ctx)
{
+ fz_free(ctx, pts);
fz_free_device(dev);
fz_drop_stroke_state(ctx, stroke);
fz_free_path(ctx, path);
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
index f9b5f779..bfcb3582 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFCore.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFCore.java
@@ -39,7 +39,7 @@ public class MuPDFCore
private native RectF[] searchPage(String text);
private native TextChar[][][][] text();
private native byte[] textAsHtml();
- private native void addStrikeOutAnnotationInternal(RectF[] lines);
+ private native void addStrikeOutAnnotationInternal(PointF[] quadPoints);
private native void deleteAnnotationInternal(int annot_index);
private native int passClickEventInternal(int page, float x, float y);
private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
@@ -248,9 +248,9 @@ public class MuPDFCore
return lns.toArray(new TextWord[lns.size()][]);
}
- public synchronized void addStrikeOutAnnotation(int page, RectF[] lines) {
+ public synchronized void addStrikeOutAnnotation(int page, PointF[] quadPoints) {
gotoPage(page);
- addStrikeOutAnnotationInternal(lines);
+ addStrikeOutAnnotationInternal(quadPoints);
}
public synchronized void deleteAnnotation(int page, int annot_index) {
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFPageView.java b/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
index 63531ec8..d82b2d0a 100644
--- a/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
+++ b/android/src/com/artifex/mupdfdemo/MuPDFPageView.java
@@ -74,7 +74,7 @@ public class MuPDFPageView extends PageView implements MuPDFView {
private EditText mEditText;
private AsyncTask<String,Void,Boolean> mSetWidgetText;
private AsyncTask<String,Void,Void> mSetWidgetChoice;
- private AsyncTask<RectF[],Void,Void> mAddStrikeOut;
+ private AsyncTask<PointF[],Void,Void> mAddStrikeOut;
private AsyncTask<Integer,Void,Void> mDeleteAnnotation;
private Runnable changeReporter;
@@ -280,7 +280,7 @@ public class MuPDFPageView extends PageView implements MuPDFView {
}
public void strikeOutSelection() {
- final ArrayList<RectF> lines = new ArrayList<RectF>();
+ final ArrayList<PointF> quadPoints = new ArrayList<PointF>();
processSelectedText(new TextProcessor() {
RectF rect;
@@ -294,20 +294,17 @@ public class MuPDFPageView extends PageView implements MuPDFView {
public void onEndLine() {
if (!rect.isEmpty()) {
- // These are vertical lines so we can specify
- // both position and thickness with a RectF
- float vcenter = rect.bottom - (rect.bottom - rect.top)*STRIKE_HEIGHT;
- float thickness = (rect.bottom - rect.top)*LINE_THICKNESS;
- rect.top = vcenter - thickness/2;
- rect.bottom = vcenter + thickness/2;
- lines.add(rect);
+ quadPoints.add(new PointF(rect.left, rect.bottom));
+ quadPoints.add(new PointF(rect.right, rect.bottom));
+ quadPoints.add(new PointF(rect.right, rect.top));
+ quadPoints.add(new PointF(rect.left, rect.top));
}
}
});
- mAddStrikeOut = new AsyncTask<RectF[],Void,Void>() {
+ mAddStrikeOut = new AsyncTask<PointF[],Void,Void>() {
@Override
- protected Void doInBackground(RectF[]... params) {
+ protected Void doInBackground(PointF[]... params) {
addStrikeOut(params[0]);
return null;
}
@@ -319,7 +316,7 @@ public class MuPDFPageView extends PageView implements MuPDFView {
}
};
- mAddStrikeOut.execute(lines.toArray(new RectF[lines.size()]));
+ mAddStrikeOut.execute(quadPoints.toArray(new PointF[quadPoints.size()]));
deselectText();
}
@@ -378,8 +375,8 @@ public class MuPDFPageView extends PageView implements MuPDFView {
}
@Override
- protected void addStrikeOut(RectF[] lines) {
- mCore.addStrikeOutAnnotation(mPageNumber, lines);
+ protected void addStrikeOut(PointF[] quadPoints) {
+ mCore.addStrikeOutAnnotation(mPageNumber, quadPoints);
}
private void loadAnnotations() {
diff --git a/android/src/com/artifex/mupdfdemo/PageView.java b/android/src/com/artifex/mupdfdemo/PageView.java
index 849dbc1f..2412253f 100644
--- a/android/src/com/artifex/mupdfdemo/PageView.java
+++ b/android/src/com/artifex/mupdfdemo/PageView.java
@@ -146,7 +146,7 @@ public abstract class PageView extends ViewGroup {
protected abstract Bitmap updatePage(BitmapHolder h, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight);
protected abstract LinkInfo[] getLinkInfo();
protected abstract TextWord[][] getText();
- protected abstract void addStrikeOut(RectF[] lines);
+ protected abstract void addStrikeOut(PointF[] quadPoints);
private void reinit() {
// Cancel pending render task
diff --git a/fitz/doc_interactive.c b/fitz/doc_interactive.c
index bf08690a..c39cf05d 100644
--- a/fitz/doc_interactive.c
+++ b/fitz/doc_interactive.c
@@ -101,6 +101,11 @@ void fz_set_annot_appearance(fz_interactive *idoc, fz_annot *annot, fz_display_l
pdf_set_annot_appearance((pdf_document *)idoc, (pdf_annot *)annot, disp_list);
}
+void fz_set_markup_annot_quadpoints(fz_interactive *idoc, fz_annot *annot, fz_point *qp, int n)
+{
+ pdf_set_markup_annot_quadpoints((pdf_document *)idoc, (pdf_annot *)annot, qp, n);
+}
+
void fz_set_doc_event_callback(fz_interactive *idoc, fz_doc_event_cb *event_cb, void *data)
{
pdf_set_doc_event_callback((pdf_document *)idoc, event_cb, data);
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index 7f9beace..c1751fe9 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -1212,6 +1212,11 @@ void fz_delete_annot(fz_interactive *idoc, fz_page *page, fz_annot *annot);
void fz_set_annot_appearance(fz_interactive *idoc, fz_annot *annot, fz_display_list *disp_list);
/*
+ fz_set_markup_annot_quadpoints: set the quadpoints for a text-markup annotation.
+*/
+void fz_set_markup_annot_quadpoints(fz_interactive *idoc, fz_annot *annot, fz_point *qp, int n);
+
+/*
* Text buffer.
*
* The trm field contains the a, b, c and d coefficients.
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h
index 4b58f911..a4e34a8f 100644
--- a/pdf/mupdf-internal.h
+++ b/pdf/mupdf-internal.h
@@ -590,6 +590,7 @@ void pdf_choice_widget_set_value(pdf_document *doc, fz_widget *tw, int n, char *
pdf_annot *pdf_create_annot(pdf_document *doc, pdf_page *page, fz_annot_type type);
void pdf_delete_annot(pdf_document *doc, pdf_page *page, pdf_annot *annot);
void pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_display_list *disp_list);
+void pdf_set_markup_annot_quadpoints(pdf_document *doc, pdf_annot *annot, fz_point *qp, int n);
void pdf_set_doc_event_callback(pdf_document *doc, fz_doc_event_cb *event_cb, void *data);
void pdf_event_issue_alert(pdf_document *doc, fz_alert_event *event);
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index aa56e056..ccc7c24c 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -741,6 +741,31 @@ pdf_delete_annot(pdf_document *doc, pdf_page *page, pdf_annot *annot)
}
void
+pdf_set_markup_annot_quadpoints(pdf_document *doc, pdf_annot *annot, fz_point *qp, int n)
+{
+ fz_context *ctx = doc->ctx;
+ fz_matrix ctm;
+ pdf_obj *arr = pdf_new_array(ctx, n*2);
+ int i;
+
+ fz_invert_matrix(&ctm, &annot->page->ctm);
+
+ pdf_dict_puts_drop(annot->obj, "QuadPoints", arr);
+
+ for (i = 0; i < n; i++)
+ {
+ fz_point pt = qp[i];
+ pdf_obj *r;
+
+ fz_transform_point(&pt, &ctm);
+ r = pdf_new_real(ctx, pt.x);
+ pdf_array_push_drop(arr, r);
+ r = pdf_new_real(ctx, pt.y);
+ pdf_array_push_drop(arr, r);
+ }
+}
+
+void
pdf_set_annot_appearance(pdf_document *doc, pdf_annot *annot, fz_display_list *disp_list)
{
fz_context *ctx = doc->ctx;