summaryrefslogtreecommitdiff
path: root/desktop/selection.c
diff options
context:
space:
mode:
authorAdrian Lees <adrian@aemulor.com>2005-09-01 03:20:21 +0000
committerAdrian Lees <adrian@aemulor.com>2005-09-01 03:20:21 +0000
commit799cc060164f32789af151559cf4c70076ef4f10 (patch)
treec0b3d18ac14d5d1241768253686f8f4ccebf749c /desktop/selection.c
parent1481f4b7f08939bfd77161e960a57752a41f2aab (diff)
downloadnetsurf-799cc060164f32789af151559cf4c70076ef4f10.tar.gz
netsurf-799cc060164f32789af151559cf4c70076ef4f10.tar.bz2
[project @ 2005-09-01 03:20:21 by adrianl]
Save text in local encoding; fix selection of zero-length blocks svn path=/import/netsurf/; revision=1857
Diffstat (limited to 'desktop/selection.c')
-rw-r--r--desktop/selection.c135
1 files changed, 94 insertions, 41 deletions
diff --git a/desktop/selection.c b/desktop/selection.c
index ea4b55ef1..be713d2d2 100644
--- a/desktop/selection.c
+++ b/desktop/selection.c
@@ -20,6 +20,7 @@
#include "netsurf/render/box.h"
#include "netsurf/render/font.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/utf8.h"
#include "netsurf/utils/utils.h"
@@ -36,6 +37,13 @@ struct rdw_info {
};
+/* text selection currently being saved */
+struct save_state {
+ char *block;
+ size_t length;
+ size_t alloc;
+};
+
static inline bool after(const struct box *a, unsigned a_idx, unsigned b);
static inline bool before(const struct box *a, unsigned a_idx, unsigned b);
static bool redraw_handler(struct box *box, int offset, size_t length, void *handle);
@@ -397,34 +405,35 @@ bool selected_part(struct box *box, unsigned start_idx, unsigned end_idx,
{
size_t box_length = box->length + box->space;
- if (box->byte_offset >= start_idx &&
- box->byte_offset + box_length <= end_idx) {
-
- /* fully enclosed */
- *start_offset = 0;
- *end_offset = box_length;
- return true;
- }
- else if (box->byte_offset + box_length > start_idx &&
- box->byte_offset < end_idx) {
- /* partly enclosed */
- int offset = 0;
- int len;
-
- if (box->byte_offset < start_idx)
- offset = start_idx - box->byte_offset;
-
- len = box_length - offset;
-
- if (box->byte_offset + box_length > end_idx)
- len = end_idx - (box->byte_offset + offset);
-
- *start_offset = offset;
- *end_offset = offset + len;
-
- return true;
+ if (box_length > 0) {
+ if (box->byte_offset >= start_idx &&
+ box->byte_offset + box_length <= end_idx) {
+
+ /* fully enclosed */
+ *start_offset = 0;
+ *end_offset = box_length;
+ return true;
+ }
+ else if (box->byte_offset + box_length > start_idx &&
+ box->byte_offset < end_idx) {
+ /* partly enclosed */
+ int offset = 0;
+ int len;
+
+ if (box->byte_offset < start_idx)
+ offset = start_idx - box->byte_offset;
+
+ len = box_length - offset;
+
+ if (box->byte_offset + box_length > end_idx)
+ len = end_idx - (box->byte_offset + offset);
+
+ *start_offset = offset;
+ *end_offset = offset + len;
+
+ return true;
+ }
}
-
return false;
}
@@ -812,21 +821,46 @@ bool selection_highlighted(struct selection *s, struct box *box,
bool save_handler(struct box *box, int offset, size_t length, void *handle)
{
- FILE *out = (FILE*)handle;
- assert(out);
+ struct save_state *sv = handle;
+ size_t new_length;
+ const char *text;
+ int space = 0;
+ size_t len;
+
+ assert(sv);
if (box) {
- size_t len = min(length, box->length - offset);
+ len = min(length, box->length - offset);
+ text = box->text + offset;
- if (fwrite(box->text + offset, 1, len, out) < len)
- return false;
+ if (box->space && length > len) space = 1;
+ }
+ else {
+ text = "\n";
+ len = 1;
+ }
- if (box->space && length > len)
- return (EOF != fputc(' ', out));
+ new_length = sv->length + len + space;
+ if (new_length >= sv->alloc) {
+ size_t new_alloc = sv->alloc + (sv->alloc / 4);
+ char *new_block;
- return true;
+ if (new_alloc < new_length) new_alloc = new_length;
+
+ new_block = realloc(sv->block, new_alloc);
+ if (!new_block) return false;
+
+ sv->block = new_block;
+ sv->alloc = new_alloc;
}
- return (EOF != fputc('\n', out));
+
+ memcpy(sv->block + sv->length, text, len);
+ sv->length += len;
+
+ if (space)
+ sv->block[sv->length++] = ' ';
+
+ return true;
}
@@ -840,11 +874,30 @@ bool save_handler(struct box *box, int offset, size_t length, void *handle)
bool selection_save_text(struct selection *s, const char *path)
{
- FILE *out = fopen(path, "w");
- if (!out) return false;
+ struct save_state sv = { NULL, 0, 0 };
+ utf8_convert_ret ret;
+ char *result;
+ FILE *out;
+
+ if (!selection_traverse(s, save_handler, &sv)) {
+ free(sv.block);
+ return false;
+ }
- selection_traverse(s, save_handler, out);
+ ret = utf8_to_local_encoding(sv.block, sv.length, &result);
+ free(sv.block);
- fclose(out);
- return true;
+ if (ret != UTF8_CONVERT_OK) {
+ LOG(("failed to convert to local encoding, return %d", ret));
+ return false;
+ }
+
+ out = fopen(path, "w");
+ if (out) {
+ int res = fputs(result, out);
+ fclose(out);
+ return (res != EOF);
+ }
+
+ return false;
}