1 /* Copyright (C) 2001-2004 Kenichi Suto
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 #include "defs.h"
19 #include "global.h"
20
21 #include "bmh.h"
22 #include "eb.h"
23 #include "history.h"
24 #include "hook.h"
25 #include "jcode.h"
26 #include "headword.h"
27 #include "dialog.h"
28 #include "xmlinternal.h"
29 #include "thread_search.h"
30 #include "dirtree.h"
31
32
33 #define MAX_HITS 50
34 #define MAXLEN_HEADING 65535
35 #define MAXLEN_TEXT 65535
36
37 #define EBOOK_MAX_KEYWORDS 256
38 #define MAX_BUFSIZE 65535
39
40 extern GList *group_list;
41 extern GList *book_list;
42 extern gint global_multi_code;
43
44 gint ebook_simple_search(BOOK_INFO *binfo, char *word, gint method, gchar *title);
45 static gint ebook_ending_search(BOOK_INFO *binfo, char *word, gint method, gchar *title);
46 static void sort_result(gchar *word);
47 static void plain_heading();
48
49 extern EB_Hookset text_hookset;
50 extern EB_Hookset heading_hookset;
51 extern EB_Hookset candidate_hookset;
52
53 static gboolean ebook_initialized = FALSE;
54
55 gboolean full_text_search_ignore_case = TRUE;
56
57 EB_Error_Code ebook_set_subbook(BOOK_INFO *binfo);
58
59 static gchar *ebook_message = NULL;
60
ebook_error_message(error_code)61 gchar *ebook_error_message(error_code)
62 {
63 const gchar *message;
64
65 if(ebook_message)
66 g_free(ebook_message);
67
68 message = eb_error_message(error_code);
69 ebook_message = iconv_convert(fs_codeset, "utf-8", message);
70 return(ebook_message);
71 }
72
73
ebook_search_method()74 gint ebook_search_method(){
75 const char *text;
76 int i;
77
78 LOG(LOG_DEBUG, "IN : ebook_search_method()");
79
80 text = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo_method)->entry));
81 for(i=0 ; search_method[i].name != 0 ; i ++){
82 if(strcmp(text, search_method[i].name) == 0){
83 LOG(LOG_DEBUG, "OUT : ebook_search_method()=%d", search_method[i].code);
84 return(search_method[i].code);
85 }
86 }
87
88 LOG(LOG_DEBUG, "OUT : ebook_search_method()=%d", SEARCH_METHOD_UNKNOWN);
89
90 return(SEARCH_METHOD_UNKNOWN);
91 }
92
load_book(const char * book_path,int subbook_no,gchar * appendix_path,gint appendix_subbook_no,gchar * fg,gchar * bg)93 BOOK_INFO *load_book(const char *book_path, int subbook_no, gchar *appendix_path, gint appendix_subbook_no, gchar *fg, gchar *bg)
94 {
95 EB_Error_Code error_code;
96 BOOK_INFO *binfo;
97 EB_Subbook_Code sublist[EB_MAX_SUBBOOKS];
98 int subcount;
99 char buff[512];
100 #if 0
101 GList *book_item;
102 #endif
103
104 LOG(LOG_DEBUG, "IN : load_book(%s, %d, %s, %d, %s %s)", book_path, subbook_no, appendix_path, appendix_subbook_no, fg, bg);
105
106 if(book_path == NULL){
107 LOG(LOG_DEBUG, "OUT : load_book() = NULL");
108 return(NULL);
109 }
110
111 // Search if there is the same book already.
112 #if 0
113 book_item = g_list_first(book_list);
114 while(book_item != NULL){
115 binfo = (BOOK_INFO *)(book_item->data);
116 if((strcmp(binfo->book_path, book_path) == 0) &&
117 (binfo->subbook_no == subbook_no)) {
118 if((binfo->appendix_path != NULL) &&
119 (appendix_path != NULL) &&
120 (strcmp(binfo->appendix_path, appendix_path) == 0) &&
121 (binfo->appendix_subbook_no == appendix_subbook_no)) {
122 return(binfo);
123 } else {
124 unload_book(binfo);
125 g_free(binfo);
126 break;
127 }
128 }
129 book_item = g_list_next(book_item);
130 }
131 #endif
132
133 binfo = (BOOK_INFO *)calloc(sizeof(BOOK_INFO),1);
134 if(binfo == NULL){
135 LOG(LOG_ERROR, "No memory");
136 exit(1);
137 }
138
139 binfo->book_path = fs_to_unicode((gchar *)book_path);
140 binfo->subbook_no = subbook_no;
141 if(appendix_path){
142 binfo->appendix_path = fs_to_unicode(appendix_path);
143 binfo->appendix_subbook_no = appendix_subbook_no;
144 }
145
146
147 binfo->book = (EB_Book *) malloc(sizeof(EB_Book));
148 eb_initialize_book(binfo->book);
149 error_code = eb_bind(binfo->book,
150 book_path);
151 if(error_code != EB_SUCCESS){
152 LOG(LOG_CRITICAL, "Failed to bind the book : %s",
153 ebook_error_message(error_code));
154 goto FAILED;
155 }
156
157 error_code = eb_subbook_list(
158 binfo->book,
159 sublist,
160 &subcount);
161 if(error_code != EB_SUCCESS){
162 LOG(LOG_CRITICAL, "Failed to get a subbook list : %s",
163 ebook_error_message(error_code));
164 goto FAILED;
165 }
166
167
168 error_code = eb_subbook_directory2(
169 binfo->book,
170 sublist[binfo->subbook_no],
171 buff);
172 if (error_code != EB_SUCCESS){
173 LOG(LOG_CRITICAL, "Failed to get the directory : %s",
174 ebook_error_message(error_code));
175 goto FAILED;
176 }
177 binfo->subbook_dir = strdup(buff);
178
179 error_code = eb_subbook_title2(
180 binfo->book,
181 sublist[binfo->subbook_no],
182 buff);
183 if (error_code != EB_SUCCESS){
184 LOG(LOG_CRITICAL, "Failed to get the title : %s",
185 ebook_error_message(error_code));
186 goto FAILED;
187 }
188 binfo->subbook_title = iconv_convert("euc-jp", "utf-8", buff);
189
190
191 if(binfo->appendix_path != NULL){
192 binfo->appendix = (EB_Appendix *) malloc(sizeof(EB_Appendix));
193 eb_initialize_appendix(binfo->appendix);
194
195 error_code = eb_bind_appendix(binfo->appendix,
196 appendix_path);
197 if(error_code != EB_SUCCESS){
198 LOG(LOG_CRITICAL, "Failed to bind appendix : %s",
199 ebook_error_message(error_code));
200 goto FAILED;
201 }
202 }
203
204
205
206 ebook_set_subbook(binfo);
207
208 binfo->available = TRUE;
209
210 if(eb_have_word_search(binfo->book)){
211 binfo->search_method[SEARCH_METHOD_WORD] = TRUE;
212 }
213
214 if(eb_have_endword_search(binfo->book)){
215 binfo->search_method[SEARCH_METHOD_ENDWORD] = TRUE;
216 }
217
218 if(eb_have_exactword_search(binfo->book)){
219 binfo->search_method[SEARCH_METHOD_EXACTWORD] = TRUE;
220 }
221
222 if(eb_have_keyword_search(binfo->book)){
223 binfo->search_method[SEARCH_METHOD_KEYWORD] = TRUE;
224 }
225 /*
226 eb_multi_search_list(binfo->book, multi_list, &multi_count);
227 for (i = 0; i < multi_count; i++) {
228 binfo->search_method[SEARCH_METHOD_MULTI1+i] = TRUE;
229 }
230 */
231 if(eb_have_multi_search(binfo->book)){
232 binfo->search_method[SEARCH_METHOD_MULTI] = TRUE;
233 }
234
235 if(eb_have_menu(binfo->book)){
236 binfo->search_method[SEARCH_METHOD_MENU] = TRUE;
237 }
238
239 if(eb_have_copyright(binfo->book)){
240 binfo->search_method[SEARCH_METHOD_COPYRIGHT] = TRUE;
241 }
242
243 if (eb_have_font(binfo->book, EB_FONT_16)){
244 error_code = eb_set_font(binfo->book, EB_FONT_16);
245 if (error_code != EB_SUCCESS) {
246 LOG(LOG_CRITICAL, "Failed to set font : subbook=%s\n%s",
247 binfo->subbook_title,
248 ebook_error_message(error_code));
249 }
250 }
251
252 if(bg && (strlen(bg) != 0))
253 binfo->bg = strdup(bg);
254
255 if(fg && (strlen(fg) != 0))
256 binfo->fg = strdup(fg);
257
258 book_list = g_list_append(book_list, binfo);
259
260 LOG(LOG_DEBUG, "OUT : load_book()");
261 return(binfo);
262
263 FAILED:
264 binfo->available = FALSE;
265
266 LOG(LOG_DEBUG, "OUT : load_book() = NULL");
267
268 return(NULL);
269 }
270
free_gaiji(BOOK_INFO * binfo)271 static void free_gaiji(BOOK_INFO *binfo){
272
273 GList *lists[8];
274 GList *item;
275 gint i;
276
277 LOG(LOG_DEBUG, "IN : free_gaiji()");
278
279 lists[0] = binfo->gaiji_narrow16;
280 lists[1] = binfo->gaiji_narrow24;
281 lists[2] = binfo->gaiji_narrow30;
282 lists[3] = binfo->gaiji_narrow48;
283 lists[4] = binfo->gaiji_wide16;
284 lists[5] = binfo->gaiji_wide24;
285 lists[6] = binfo->gaiji_wide30;
286 lists[7] = binfo->gaiji_wide48;
287
288
289
290 for(i=0; i < 8 ; i ++){
291 item = g_list_first(lists[i]);
292 while(item){
293 free(item->data);
294 item = g_list_next(item);
295 }
296 g_list_free(lists[i]);
297 }
298
299 binfo->gaiji_narrow16 = NULL;
300 binfo->gaiji_narrow24 = NULL;
301 binfo->gaiji_narrow30 = NULL;
302 binfo->gaiji_narrow48 = NULL;
303 binfo->gaiji_wide16 = NULL;
304 binfo->gaiji_wide24 = NULL;
305 binfo->gaiji_wide30 = NULL;
306 binfo->gaiji_wide48 = NULL;
307
308 LOG(LOG_DEBUG, "OUT : free_gaiji()");
309 }
310
unload_book(BOOK_INFO * binfo)311 void unload_book(BOOK_INFO *binfo)
312 {
313
314 LOG(LOG_DEBUG, "IN : unload_book()");
315
316 eb_unset_subbook(binfo->book);
317 eb_finalize_book(binfo->book);
318 free(binfo->book_path);
319 free(binfo->appendix_path);
320 free(binfo->subbook_dir);
321 free(binfo->subbook_title);
322
323 free_gaiji(binfo);
324
325 book_list = g_list_remove(book_list, binfo);
326
327 LOG(LOG_DEBUG, "OUT : unload_book()");
328 return;
329 }
330
check_search_method()331 void check_search_method()
332 {
333
334 #if 0
335 BOOK_INFO *binfo;
336 GList *book_item;
337 #endif
338 gint method_count=0;
339
340 LOG(LOG_DEBUG, "IN : check_search_method()");
341
342 #if 0
343 menu_word_search = FALSE;
344 menu_endword_search = FALSE;
345 menu_exactword_search = FALSE;
346 menu_keyword_search = FALSE;
347 menu_menu = FALSE;
348 menu_copyright = FALSE;
349 menu_multi_search = FALSE;
350
351 book_item = g_list_first(book_list);
352 while(book_item != NULL){
353 binfo = (BOOK_INFO *)(book_item->data);
354 if(binfo->search_method[SEARCH_METHOD_WORD] == TRUE)
355 menu_word_search = TRUE;
356 if(binfo->search_method[SEARCH_METHOD_ENDWORD] == TRUE)
357 menu_endword_search = TRUE;
358 if(binfo->search_method[SEARCH_METHOD_EXACTWORD] == TRUE)
359 menu_exactword_search = TRUE;
360 if(binfo->search_method[SEARCH_METHOD_KEYWORD] == TRUE)
361 menu_keyword_search = TRUE;
362 if(binfo->search_method[SEARCH_METHOD_MENU] == TRUE)
363 menu_menu = TRUE;
364 if(binfo->search_method[SEARCH_METHOD_COPYRIGHT] == TRUE)
365 menu_copyright = TRUE;
366 if(binfo->search_method[SEARCH_METHOD_MULTI] == TRUE)
367 menu_multi_search = TRUE;
368
369 book_item = g_list_next(book_item);
370 }
371
372 method_count = 0;
373
374 search_method[method_count].code = SEARCH_METHOD_AUTOMATIC;
375 search_method[method_count].name = strdup(_("Automatic Search"));
376 method_count ++;
377
378 if(menu_exactword_search == TRUE){
379 search_method[method_count].code = SEARCH_METHOD_EXACTWORD;
380 search_method[method_count].name = strdup(_("Exactword Search"));
381 method_count ++;
382 }
383
384 if(menu_word_search == TRUE){
385 search_method[method_count].code = SEARCH_METHOD_WORD;
386 search_method[method_count].name = strdup(_("Forward Search"));
387 method_count ++;
388 }
389
390 if(menu_endword_search == TRUE){
391 search_method[method_count].code = SEARCH_METHOD_ENDWORD;
392 search_method[method_count].name = strdup(_("Backward Search"));
393 method_count ++;
394 }
395
396 if(menu_keyword_search == TRUE){
397 search_method[method_count].code = SEARCH_METHOD_KEYWORD;
398 search_method[method_count].name = strdup(_("Keyword Search"));
399 method_count ++;
400 }
401
402 if(menu_multi_search == TRUE){
403 search_method[method_count].code = SEARCH_METHOD_MULTI;
404 search_method[method_count].name = strdup(_("Multiword Search"));
405 method_count ++;
406 }
407
408 /*
409 if(menu_menu == TRUE){
410 search_method[method_count].code = SEARCH_METHOD_MENU;
411 search_method[method_count].name = strdup(_("Menu"));
412 method_count ++;
413 }
414
415 if(menu_copyright == TRUE){
416 search_method[method_count].code = SEARCH_METHOD_COPYRIGHT;
417 search_method[method_count].name = strdup(_("Copyright"));
418 method_count ++;
419 }
420 */
421
422 search_method[method_count].code = SEARCH_METHOD_FULL_TEXT;
423 search_method[method_count].name = strdup(_("Full Text Search"));
424 method_count ++;
425
426 search_method[method_count].code = SEARCH_METHOD_INTERNET;
427 search_method[method_count].name = strdup(_("Internet Search"));
428 method_count ++;
429
430 search_method[method_count].code = SEARCH_METHOD_GREP;
431 search_method[method_count].name = strdup(_("File Search"));
432 method_count ++;
433
434
435 search_method[method_count].name = NULL;
436
437 #endif
438
439 method_count = 0;
440
441 search_method[method_count].code = SEARCH_METHOD_AUTOMATIC;
442 search_method[method_count].name = strdup(_("Automatic Search"));
443 method_count ++;
444
445 search_method[method_count].code = SEARCH_METHOD_EXACTWORD;
446 search_method[method_count].name = strdup(_("Exactword Search"));
447 method_count ++;
448
449 search_method[method_count].code = SEARCH_METHOD_WORD;
450 search_method[method_count].name = strdup(_("Forward Search"));
451 method_count ++;
452
453 search_method[method_count].code = SEARCH_METHOD_ENDWORD;
454 search_method[method_count].name = strdup(_("Backward Search"));
455 method_count ++;
456
457 search_method[method_count].code = SEARCH_METHOD_KEYWORD;
458 search_method[method_count].name = strdup(_("Keyword Search"));
459 method_count ++;
460
461 search_method[method_count].code = SEARCH_METHOD_MULTI;
462 search_method[method_count].name = strdup(_("Multiword Search"));
463 method_count ++;
464
465 /*
466 search_method[method_count].code = SEARCH_METHOD_MENU;
467 search_method[method_count].name = strdup(_("Menu"));
468 method_count ++;
469
470 search_method[method_count].code = SEARCH_METHOD_COPYRIGHT;
471 search_method[method_count].name = strdup(_("Copyright"));
472 method_count ++;
473 */
474
475 search_method[method_count].code = SEARCH_METHOD_FULL_TEXT;
476 search_method[method_count].name = strdup(_("Full Text Search"));
477 method_count ++;
478
479 search_method[method_count].code = SEARCH_METHOD_INTERNET;
480 search_method[method_count].name = strdup(_("Internet Search"));
481 method_count ++;
482
483 search_method[method_count].code = SEARCH_METHOD_GREP;
484 search_method[method_count].name = strdup(_("File Search"));
485 method_count ++;
486
487 search_method[method_count].name = NULL;
488
489
490 LOG(LOG_DEBUG, "OUT : check_search_method()");
491
492 }
493
ebook_start()494 gint ebook_start(){
495 EB_Error_Code error_code;
496
497 LOG(LOG_DEBUG, "IN : ebook_start()");
498
499 error_code = eb_initialize_library();
500 if(error_code != EB_SUCCESS){
501 LOG(LOG_CRITICAL, "Failed to initialize library : %s",
502 ebook_error_message(error_code));
503 return(1);
504 }
505
506 error_code = initialize_hooksets();
507 if(error_code != EB_SUCCESS){
508 return(1);
509 }
510
511 ebook_initialized = TRUE;
512
513 LOG(LOG_DEBUG, "OUT : ebook_start()");
514 return(0);
515
516 }
517
ebook_end()518 gint ebook_end(){
519
520 BOOK_INFO *binfo;
521 GList *book_item;
522
523 LOG(LOG_DEBUG, "IN : ebook_end()");
524
525 if(ebook_initialized == TRUE) {
526 LOG(LOG_DEBUG, "OUT : ebook_end()");
527 return(0);
528 }
529
530 book_item = g_list_first(book_list);
531 while(book_item != NULL){
532 binfo = (BOOK_INFO *)(book_item->data);
533 eb_unset_subbook(binfo->book);
534 eb_finalize_book(binfo->book);
535 free(binfo->book_path);
536 free(binfo->appendix_path);
537 free(binfo->subbook_dir);
538 free(binfo->subbook_title);
539
540 free_gaiji(binfo);
541
542 g_list_remove(book_list, book_item->data);
543 book_item = g_list_next(book_item);
544 }
545
546 finalize_hooksets();
547
548 book_list = NULL;
549 ebook_initialized = FALSE;
550
551 LOG(LOG_DEBUG, "OUT : ebook_end()");
552 return(0);
553 }
554
split_word(const gchar * word,gchar ** keywords)555 void split_word(const gchar *word, gchar **keywords)
556 {
557 gint i,j;
558 gchar *p;
559 gchar buff[512];
560 gint quoted=0;
561
562 LOG(LOG_DEBUG, "IN : split_word(%s)", word);
563
564 p = (gchar *)word;
565 i = 0;
566 j = 0;
567 keywords[0] = NULL;
568
569 if(strlen(word) > 512){
570 return;
571 }
572
573 while(1){
574 switch(*p){
575 case '\"':
576 if(quoted)
577 quoted = 0;
578 else
579 quoted = 1;
580 break;
581 case ' ':
582 case '\t':
583 case '\n':
584 if(quoted){
585 buff[j] = *p;
586 j ++;
587 } else {
588 buff[j] = '\0';
589 keywords[i] = strdup(buff);
590 i ++;
591 keywords[i] = NULL;
592 j = 0;
593 }
594 break;
595 default:
596 buff[j] = *p;
597 j ++;
598 }
599 p++;
600 if(*p == '\0'){
601 buff[j] = '\0';
602 if(strlen(buff) != 0){
603 keywords[i] = strdup(buff);
604 i ++;
605 }
606 keywords[i] = NULL;
607 break;
608 } else if(i == EBOOK_MAX_KEYWORDS) {
609 break;
610 }
611 }
612
613 for(i=0; ; i++){
614 if(keywords[i] == NULL)
615 break;
616 }
617
618 LOG(LOG_DEBUG, "OUT : split_word()");
619 }
620
cat_word(char * string,char ** words)621 void cat_word(char *string, char **words){
622 gint i;
623 gint len = 0;
624
625 LOG(LOG_DEBUG, "IN : cat_word()");
626
627 sprintf(string, "%s", words[0]);
628 len = strlen(words[0]);
629
630 for(i=1 ; words[i] != NULL ; i++){
631 strcat(string, " ");
632 strcat(string, words[i]);
633 len = len + strlen(words[i]) + 1;
634 }
635 string[len] = '\0';
636
637 LOG(LOG_DEBUG, "OUT : cat_word() = %s", string);
638 }
639
free_words(char ** words)640 void free_words(char **words){
641 gint i;
642
643 LOG(LOG_DEBUG, "IN : free_words()");
644
645 for(i=0; words[i] != NULL ; i++)
646 free(words[i]);
647
648 LOG(LOG_DEBUG, "OUT : free_words()");
649 }
650
check_duplicate_hit(EB_Position pos)651 static gboolean check_duplicate_hit(EB_Position pos){
652 GList *l;
653 RESULT *rp;
654
655 l = search_result;
656 while(l != NULL){
657 rp = (RESULT *)(l->data);
658 if((rp->data.eb.pos_text.page == pos.page) &&
659 (rp->data.eb.pos_text.offset == pos.offset))
660 return(TRUE);
661 l = g_list_next(l);
662 }
663 return(FALSE);
664 }
665
count_result(GList * result)666 static gint count_result(GList *result)
667 {
668 return(g_list_length(result));
669 }
670
ebook_my_backward_text(BOOK_INFO * binfo)671 EB_Error_Code ebook_my_backward_text(BOOK_INFO *binfo)
672 {
673
674 EB_Error_Code error_code=EB_SUCCESS;
675 EB_Position text_position;
676 char data[EB_SIZE_PAGE+4];
677 int i;
678 ssize_t length;
679
680 int start_page;
681 int end_page;
682 int current_page;
683 int current_offset;
684 int offset;
685 int read_page;
686
687 int stop_code;
688
689
690 error_code = ebook_set_subbook(binfo);
691 if(error_code != EB_SUCCESS){
692 LOG(LOG_CRITICAL, "Failed to set subbook : %s",
693 ebook_error_message(error_code));
694 return(error_code);
695 }
696
697 start_page = binfo->book->subbook_current->text.start_page;
698 end_page = binfo->book->subbook_current->text.end_page;
699
700 error_code = eb_tell_text(binfo->book, &text_position);
701 if(error_code != EB_SUCCESS){
702 LOG(LOG_CRITICAL, "Failed to tell text : %s",
703 ebook_error_message(error_code));
704 return(error_code);
705 }
706
707 current_page = text_position.page;
708 current_offset = text_position.offset;
709
710 offset = current_offset;
711
712 stop_code = binfo->book->text_context.auto_stop_code;
713
714 for(read_page = current_page ; read_page >= start_page ; read_page --){
715
716 text_position.page = read_page;
717 text_position.offset = 0;
718
719 error_code = eb_seek_text(binfo->book, &text_position);
720 if (error_code != EB_SUCCESS) {
721 LOG(LOG_CRITICAL, "Failed to seek text : %s",
722 ebook_error_message(error_code));
723 return(error_code);
724 }
725
726 memset(data, 0, EB_SIZE_PAGE + 4);
727
728 error_code = eb_read_rawtext(binfo->book,
729 EB_SIZE_PAGE+2,
730 data,
731 &length);
732 if (error_code != EB_SUCCESS || length != EB_SIZE_PAGE+2){
733 LOG(LOG_CRITICAL, "Failed to read rawtext : %s",
734 ebook_error_message(error_code));
735 return(error_code);
736 }
737
738 if(stop_code != -1)
739 binfo->book->text_context.auto_stop_code = stop_code;
740
741
742 for(i=offset-2 ; i >= 0 ; i -=2){
743 if(((binfo->appendix != NULL) &&
744 (eb_uint2(&data[i]) == binfo->appendix->subbook_current->stop_code0) &&
745 (eb_uint2(&data[i+2]) == binfo->appendix->subbook_current->stop_code1)) ||
746
747 ((binfo->appendix == NULL) &&
748 (eb_uint2(&data[i]) == 0x1f41) &&
749 (eb_uint1(&data[i+2]) == 0x01)) ||
750 (eb_uint2(&data[i]) == 0x1f02))
751 {
752
753 text_position.page = read_page;
754 text_position.offset = i;
755
756 error_code = eb_seek_text(binfo->book, &text_position);
757 if (error_code != EB_SUCCESS) {
758 LOG(LOG_CRITICAL, "Failed to seek text : %s",
759 ebook_error_message(error_code));
760 return(error_code);
761 }
762
763 if(stop_code != -1)
764 binfo->book->text_context.auto_stop_code = stop_code;
765
766 return(EB_SUCCESS);
767
768 }
769
770 }
771
772 offset = EB_SIZE_PAGE + 2;
773 }
774
775 text_position.page = current_page;
776 text_position.offset = current_offset;
777
778 error_code = eb_seek_text(binfo->book, &text_position);
779 if (error_code != EB_SUCCESS) {
780 LOG(LOG_CRITICAL, "Failed to seek text : %s",
781 ebook_error_message(error_code));
782 return(error_code);
783 }
784
785 return(EB_ERR_FAIL_SEEK_TEXT);
786
787 }
788
789 gint ascii_to_jisx2080_table [] = {
790 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00
791 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x08
792 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10
793 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x18
794 0x2121, 0x212a, 0x2140, 0x2174, 0x2170, 0x2173, 0x2175, 0x2147, // 0x20
795 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x215d, 0x2125, 0x213f, // 0x28
796 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, // 0x30
797 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, // 0x38
798 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, // 0x40
799 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, // 0x48
800 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, // 0x50
801 0x2358, 0x2359, 0x235a, 0x214e, 0x216f, 0x214f, 0x2130, 0x2132, // 0x58
802 0x212e, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, // 0x60
803 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, // 0x68
804 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, // 0x70
805 0x2378, 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2141, 0x0000 // 0x78
806 };
807
euc2jis(gchar * inbuf)808 static gchar *euc2jis(gchar *inbuf){
809 guchar *euc_p;
810 guchar *jisbuf=NULL;
811 guchar *jis_p;
812
813 euc_p = inbuf;
814 jis_p = jisbuf = malloc(strlen(euc_p)*2);
815
816 while(*euc_p != '\0'){
817 if(( 0x20 <= *euc_p) && (*euc_p <= 0x7e) && (ascii_to_jisx2080_table[*euc_p] != 0x00)){
818 *jis_p = (ascii_to_jisx2080_table[*euc_p] & 0xff00) >> 8;
819 jis_p ++;
820 *jis_p = ascii_to_jisx2080_table[*euc_p] & 0xff;
821 jis_p ++;
822 }
823 else if(iseuc(euc_p)){
824 *jis_p = *euc_p - 0x80;
825 jis_p ++;
826 euc_p++;
827 *jis_p = *euc_p - 0x80;
828 jis_p ++;
829 }
830
831 else if(*euc_p == 0x20){
832 *jis_p = 0x21;
833 jis_p ++;
834 *jis_p = 0x21;
835 jis_p ++;
836 }
837
838 else {
839 *jis_p = 0x21;
840 jis_p ++;
841 *jis_p = 0x29;
842 jis_p ++;
843 }
844
845 euc_p ++;
846 }
847 *jis_p = '\0';
848
849 return(jisbuf);
850 }
851
ebook_full_search_old(BOOK_INFO * binfo,char * word,gint method,gchar * title)852 static gint ebook_full_search_old(BOOK_INFO *binfo, char *word, gint method, gchar *title)
853 {
854
855 EB_Error_Code error_code=EB_SUCCESS;
856 EB_Position text_position;
857 char data[EB_SIZE_PAGE];
858 char *jisword;
859 char *word_p;
860 int i;
861 ssize_t length;
862 char *p;
863 char heading[MAXLEN_TEXT + 1];
864 RESULT *rp;
865
866 int start_page;
867 int end_page;
868 int current_page;
869
870 int stop_code;
871 int page_count=0;
872
873 LOG(LOG_DEBUG, "IN : ebook_full_search(%s)", word);
874
875 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
876 return(error_code);
877
878 start_page = binfo->book->subbook_current->text.start_page;
879 end_page = binfo->book->subbook_current->text.end_page;
880
881 // Read once in order to determine auto_stop_code
882 p = ebook_get_text(binfo, start_page, 0);
883 if(p)
884 free(p);
885 stop_code = binfo->book->text_context.auto_stop_code;
886
887 jisword = euc2jis(word);
888 word_p = jisword;
889
890 for(current_page = start_page ; current_page <= end_page ; current_page ++){
891
892 set_progress((float)(current_page - start_page) / (end_page - start_page + 1));
893 page_count ++;
894
895 text_position.page = current_page;
896 text_position.offset = 0;
897
898 error_code = eb_seek_text(binfo->book, &text_position);
899 if (error_code != EB_SUCCESS) {
900 LOG(LOG_CRITICAL, "Failed to seek text : %s",
901 ebook_error_message(error_code));
902 return(error_code);
903 }
904
905 error_code = eb_read_rawtext(binfo->book,
906 EB_SIZE_PAGE,
907 data,
908 &length);
909 if (error_code != EB_SUCCESS || length != EB_SIZE_PAGE){
910 LOG(LOG_CRITICAL, "Failed to read rawtext : %s",
911 ebook_error_message(error_code));
912 return(error_code);
913 }
914
915 for(i=0 ; i < EB_SIZE_PAGE ; i +=2){
916
917 // skip control characters
918 if(isjisp(&data[i]) != TRUE){
919 continue;
920
921 // match
922 } else if((data[i] == *word_p) &&
923 (data[i+1] == *(word_p+1))){
924
925 // See if keyword continues
926 if (*(word_p+2) != '\0'){
927 word_p += 2;
928 continue;
929 }
930 // In case ignoring upper letters and lower letters
931 } else if(full_text_search_ignore_case){
932 guint c1, c2;
933
934 c1 = eb_uint2(&data[i]);
935 c2 = eb_uint2(word_p);
936
937 // Alphabet
938 if ((0x2341 <= c1) && (c1 <= 0x237a) &&
939 (0x2341 <= c2) && (c2 <= 0x237a)){
940 // Convert to lower and do match
941 if(((0x2361 <= c1) ? (c1 - 0x20) : c1) == ((0x2361 <= c2) ? (c2 - 0x20) : c2)){
942 // See if keyword continues
943 if (*(word_p+2) != '\0'){
944 word_p += 2;
945 continue;
946 }
947 } else {
948 goto NO_MATCH;
949 }
950 } else {
951 goto NO_MATCH;
952 }
953 } else {
954 goto NO_MATCH;
955 }
956
957
958 // Match then read
959
960 text_position.page = current_page;
961 text_position.offset = i;
962
963 error_code = eb_seek_text(binfo->book, &text_position);
964 if (error_code != EB_SUCCESS) {
965 LOG(LOG_CRITICAL, "Failed to seek text : %s",
966 ebook_error_message(error_code));
967 // Do nothing
968 goto NO_MATCH;
969 }
970
971 // Because eb_seek_text() will clear auto_stop_code,
972 // restore old value.
973 if(stop_code != -1)
974 binfo->book->text_context.auto_stop_code = stop_code;
975
976 error_code = ebook_my_backward_text(binfo);
977 if(error_code != EB_SUCCESS){
978 LOG(LOG_CRITICAL, "Failed to back text : %s",
979 ebook_error_message(error_code));
980 // Do nothing
981 goto NO_MATCH;
982 }
983
984
985 error_code = eb_tell_text(binfo->book, &text_position);
986 if(error_code != EB_SUCCESS){
987 LOG(LOG_CRITICAL, "Failed to tell text : %s",
988 ebook_error_message(error_code));
989 // Do nothing
990 goto NO_MATCH;
991 }
992
993 if(check_duplicate_hit(text_position) == TRUE){
994 // Do nothing
995 goto NO_MATCH;
996 }
997
998
999 error_code = eb_read_text(binfo->book, binfo->appendix, &heading_hookset,
1000 NULL, MAXLEN_TEXT, heading, &length);
1001 if (error_code != EB_SUCCESS) {
1002 LOG(LOG_CRITICAL, "Failed to read text : %s",
1003 ebook_error_message(error_code));
1004 // Do nothing
1005 goto NO_MATCH;
1006 }
1007 heading[length] = '\0';
1008
1009 p = strchr(heading, '\n');
1010 if(p != NULL)
1011 *p = '\0';
1012
1013
1014 rp = (RESULT *)calloc(sizeof(RESULT),1);
1015 if(rp == NULL){
1016 LOG(LOG_ERROR, "No memory");
1017 exit(1);
1018 }
1019
1020 rp->heading = iconv_convert("euc-jp", "utf-8", heading);
1021 rp->word = iconv_convert("euc-jp", "utf-8", word);
1022 rp->type = RESULT_TYPE_EB;
1023 rp->data.eb.book_info = binfo;
1024 rp->data.eb.search_method = method;
1025 rp->data.eb.dict_title = strdup(title);
1026
1027 rp->data.eb.pos_heading = text_position;
1028 rp->data.eb.pos_text = text_position;
1029
1030 add_result(rp);
1031
1032 if((binfo->book->text_context.auto_stop_code != stop_code) &&
1033 (binfo->book->text_context.auto_stop_code != -1))
1034 stop_code = binfo->book->text_context.auto_stop_code;
1035 pthread_testcancel();
1036
1037 NO_MATCH:
1038 word_p = jisword;
1039 continue;
1040 }
1041 }
1042
1043 free(jisword);
1044
1045 LOG(LOG_DEBUG, "OUT : ebook_full_search()");
1046 return(error_code);
1047 }
1048
1049 // Full text search using BMH method.
ebook_full_search(BOOK_INFO * binfo,char * word,gint method,gchar * title)1050 static gint ebook_full_search(BOOK_INFO *binfo, char *word, gint method, gchar *title)
1051 {
1052
1053 EB_Error_Code error_code=EB_SUCCESS;
1054 EB_Position text_position;
1055 char data[EB_SIZE_PAGE];
1056 char *jisword;
1057 char *word_p;
1058 ssize_t length;
1059 char *p;
1060 char heading[MAXLEN_TEXT + 1];
1061 RESULT *rp;
1062
1063 int start_page;
1064 int end_page;
1065 int current_page;
1066
1067 int stop_code;
1068 int page_count=0;
1069
1070 BMH_TABLE *bmh;
1071 gchar *start_p;
1072 gint word_len;
1073
1074 LOG(LOG_DEBUG, "IN : ebook_full_search(%s)", word);
1075
1076 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
1077 return(error_code);
1078
1079 start_page = binfo->book->subbook_current->text.start_page;
1080 end_page = binfo->book->subbook_current->text.end_page;
1081
1082 // Read once in order to get auto_stop_code.
1083 p = ebook_get_text(binfo, start_page, 0);
1084 if(p)
1085 free(p);
1086 stop_code = binfo->book->text_context.auto_stop_code;
1087
1088 jisword = euc2jis(word);
1089 word_p = jisword;
1090
1091 bmh = bmh_prepare(jisword, TRUE);
1092
1093 word_len = strlen(jisword);
1094 memset(data, 0, word_len);
1095
1096 for(current_page = start_page ; current_page <= end_page ; current_page ++){
1097
1098 set_progress((float)(current_page - start_page) / (end_page - start_page + 1));
1099 page_count ++;
1100
1101 text_position.page = current_page;
1102 text_position.offset = 0;
1103
1104 error_code = eb_seek_text(binfo->book, &text_position);
1105 if (error_code != EB_SUCCESS) {
1106 LOG(LOG_CRITICAL, "Failed to seek text : %s",
1107 ebook_error_message(error_code));
1108 return(error_code);
1109 }
1110
1111 error_code = eb_read_rawtext(binfo->book,
1112 EB_SIZE_PAGE,
1113 &data[word_len],
1114 &length);
1115 if (error_code != EB_SUCCESS || length != EB_SIZE_PAGE){
1116 LOG(LOG_CRITICAL, "Failed to read rawtext : %s",
1117 ebook_error_message(error_code));
1118 return(error_code);
1119 }
1120
1121 start_p = data;
1122 while(start_p){
1123
1124 start_p = bmh_search(bmh, start_p, EB_SIZE_PAGE + word_len - (start_p - data));
1125
1126 if(start_p == NULL)
1127 break;
1128
1129 // Match then read
1130
1131 if((start_p - data) <= word_len) {
1132 text_position.page = current_page - 1;
1133 text_position.offset = EB_SIZE_PAGE - word_len;
1134 } else {
1135 text_position.page = current_page;
1136 text_position.offset = start_p - data - word_len;
1137 }
1138
1139 error_code = eb_seek_text(binfo->book, &text_position);
1140 if (error_code != EB_SUCCESS) {
1141 LOG(LOG_CRITICAL, "Failed to seek text : %s",
1142 ebook_error_message(error_code));
1143 // Do nothing
1144 goto NO_MATCH;
1145 }
1146
1147 // Because eb_seek_text() will clear auto_stop_code,
1148 // restore old value.
1149 if(stop_code != -1)
1150 binfo->book->text_context.auto_stop_code = stop_code;
1151
1152 error_code = ebook_my_backward_text(binfo);
1153 if(error_code != EB_SUCCESS){
1154 LOG(LOG_CRITICAL, "Failed to back text : %s",
1155 ebook_error_message(error_code));
1156 // Do nothing
1157 goto NO_MATCH;
1158 }
1159
1160
1161 error_code = eb_tell_text(binfo->book, &text_position);
1162 if(error_code != EB_SUCCESS){
1163 LOG(LOG_CRITICAL, "Failed to tell text : %s",
1164 ebook_error_message(error_code));
1165 // Do nothing
1166 goto NO_MATCH;
1167 }
1168
1169 if(check_duplicate_hit(text_position) == TRUE){
1170 // Do nothing
1171 goto NO_MATCH;
1172 }
1173
1174
1175 error_code = eb_read_text(binfo->book, binfo->appendix, &heading_hookset,
1176 NULL, MAXLEN_TEXT, heading, &length);
1177 if (error_code != EB_SUCCESS) {
1178 LOG(LOG_CRITICAL, "Failed to read text : %s",
1179 ebook_error_message(error_code));
1180 // Do nothing
1181 goto NO_MATCH;
1182 }
1183 heading[length] = '\0';
1184
1185 p = strchr(heading, '\n');
1186 if(p != NULL)
1187 *p = '\0';
1188
1189
1190 rp = (RESULT *)calloc(sizeof(RESULT),1);
1191 if(rp == NULL){
1192 LOG(LOG_ERROR, "No memory");
1193 exit(1);
1194 }
1195
1196 rp->heading = iconv_convert("euc-jp", "utf-8", heading);
1197 rp->word = iconv_convert("euc-jp", "utf-8", word);
1198 rp->type = RESULT_TYPE_EB;
1199 rp->data.eb.book_info = binfo;
1200 rp->data.eb.search_method = method;
1201 rp->data.eb.dict_title = strdup(title);
1202
1203 rp->data.eb.pos_heading = text_position;
1204 rp->data.eb.pos_text = text_position;
1205
1206 add_result(rp);
1207
1208 if((binfo->book->text_context.auto_stop_code != stop_code) &&
1209 (binfo->book->text_context.auto_stop_code != -1))
1210 stop_code = binfo->book->text_context.auto_stop_code;
1211 pthread_testcancel();
1212
1213 NO_MATCH:
1214 start_p += word_len;
1215 continue;
1216 }
1217
1218 }
1219
1220 bmh_free(bmh);
1221 free(jisword);
1222
1223 LOG(LOG_DEBUG, "OUT : ebook_full_search()");
1224 return(error_code);
1225 }
1226
1227 // Sort by dictionary, then search method
ebook_search2(char * g_word,GtkTreeIter * parent)1228 static gint ebook_search2(char *g_word, GtkTreeIter *parent)
1229 {
1230
1231 int j;
1232 int method;
1233 EB_Error_Code error_code=EB_SUCCESS;
1234 GtkTreeIter iter;
1235
1236 gchar *word = strdup(g_word);
1237
1238 LOG(LOG_DEBUG, "IN : ebook_search2()");
1239
1240 clear_search_result();
1241
1242 method = ebook_search_method();
1243
1244
1245 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(dict_store), &iter, parent) == TRUE){
1246 do {
1247
1248 gint type;
1249 gchar *title;
1250 gboolean active;
1251 BOOK_INFO *binfo;
1252
1253 gtk_tree_model_get(GTK_TREE_MODEL(dict_store),
1254 &iter,
1255 DICT_TYPE_COLUMN, &type,
1256 DICT_TITLE_COLUMN, &title,
1257 DICT_ACTIVE_COLUMN, &active,
1258 DICT_MEMBER_COLUMN, &binfo,
1259 -1);
1260
1261 if(active != TRUE)
1262 continue;
1263 if(binfo == NULL)
1264 continue;
1265 if(binfo->available == FALSE)
1266 continue;
1267
1268
1269 if(method == SEARCH_METHOD_AUTOMATIC){
1270 for(j=SEARCH_METHOD_MIN ; j<=SEARCH_METHOD_MAX ; j++){
1271
1272 // Except word search and backward search.
1273 if((j == SEARCH_METHOD_WORD) && (!bword_search_automatic))
1274 continue;
1275
1276 if(j == SEARCH_METHOD_ENDWORD)
1277 continue;
1278
1279 if(binfo->search_method[j] == TRUE){
1280 if(bending_correction == 0){
1281 error_code = ebook_simple_search(binfo, word, j, title);
1282 } else {
1283 error_code = ebook_ending_search(binfo, word, j, title);
1284 }
1285 if (error_code != EB_SUCCESS){
1286 if(error_code == EB_ERR_TOO_MANY_WORDS)
1287 continue;
1288 LOG(LOG_CRITICAL, "Failed to search : %s",
1289 ebook_error_message(error_code));
1290 goto END;
1291 }
1292 }
1293 }
1294 } else if((method == SEARCH_METHOD_FULL_TEXT) ||
1295 (method == SEARCH_METHOD_FULL_HEADING)){
1296 set_cancel_dlg_text(binfo->subbook_title);
1297 error_code = ebook_full_search(binfo, word, method, title); goto END;
1298 } else {
1299 if(binfo->search_method[method] == TRUE){
1300 if(bending_correction == 0){
1301 error_code = ebook_simple_search(binfo, word, method, title);
1302 } else {
1303 error_code = ebook_ending_search(binfo, word, method, title);
1304 }
1305 }
1306 }
1307
1308 g_free (title);
1309 if(error_code != EB_SUCCESS)
1310 goto END;
1311
1312 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(dict_store), &iter) == TRUE);
1313 }
1314
1315 END:
1316 LOG(LOG_DEBUG, "OUT : ebook_search2()");
1317 return 0;
1318 }
1319
1320 // Sort by search method, then dictionary
ebook_search3(char * g_word,GtkTreeIter * parent)1321 static gint ebook_search3(char *g_word, GtkTreeIter *parent)
1322 {
1323
1324 int j;
1325 int method;
1326 EB_Error_Code error_code=EB_SUCCESS;
1327 GtkTreeIter iter;
1328
1329 gchar *word = strdup(g_word);
1330
1331 LOG(LOG_DEBUG, "IN : ebook_search3()");
1332
1333 clear_search_result();
1334
1335 method = ebook_search_method();
1336
1337
1338 if(method == SEARCH_METHOD_AUTOMATIC){
1339 for(j=SEARCH_METHOD_MIN ; j<=SEARCH_METHOD_MAX ; j++){
1340
1341 // Except word search and backward search
1342 if((j == SEARCH_METHOD_WORD) && (!bword_search_automatic))
1343 continue;
1344
1345 if(j == SEARCH_METHOD_ENDWORD)
1346 continue;
1347
1348 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(dict_store), &iter, parent) == TRUE){
1349 do {
1350 gint type;
1351 gchar *title;
1352 gboolean active;
1353 BOOK_INFO *binfo;
1354
1355 gtk_tree_model_get(GTK_TREE_MODEL(dict_store),
1356 &iter,
1357 DICT_TYPE_COLUMN, &type,
1358 DICT_TITLE_COLUMN, &title,
1359 DICT_ACTIVE_COLUMN, &active,
1360 DICT_MEMBER_COLUMN, &binfo,
1361 -1);
1362
1363 if(active != TRUE)
1364 continue;
1365 if(binfo == NULL)
1366 continue;
1367 if(binfo->available == FALSE)
1368 continue;
1369
1370
1371 if(binfo->search_method[j] == TRUE){
1372 if(bending_correction == 0){
1373 error_code = ebook_simple_search(binfo, word, j, title);
1374 } else {
1375 error_code = ebook_ending_search(binfo, word, j, title);
1376 }
1377 if (error_code != EB_SUCCESS){
1378 if(error_code == EB_ERR_TOO_MANY_WORDS)
1379 continue;
1380 LOG(LOG_CRITICAL, "Failed to search : %s",
1381 ebook_error_message(error_code));
1382 goto END;
1383 }
1384 }
1385
1386 g_free (title);
1387
1388 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(dict_store), &iter) == TRUE);
1389 }
1390
1391 }
1392
1393 }
1394
1395 END:
1396 plain_heading();
1397 sort_result(g_word);
1398
1399 LOG(LOG_DEBUG, "OUT : ebook_search3()");
1400 return 0;
1401 }
1402
plain_heading()1403 static void plain_heading()
1404 {
1405 RESULT *rp;
1406 GList *l;
1407 gint len;
1408 gchar *p;
1409 gchar *pp;
1410 guchar body[65536];
1411 gint i;
1412 gunichar ch;
1413
1414 gchar start_tag[512];
1415 gchar tag_name[512];
1416
1417 for(l = search_result ; l != NULL; l = g_list_next(l)){
1418 rp = (RESULT *)(l->data);
1419
1420
1421 len = g_utf8_strlen(rp->heading, -1);
1422 p = rp->heading;
1423 pp = body;
1424
1425 for(i=0;i<len;i++){
1426 ch = g_utf8_get_char(p);
1427 if(ch == '<'){
1428 get_start_tag(p, start_tag);
1429 get_tag_name(start_tag, tag_name);
1430
1431 if(strcmp(tag_name, "gaiji") == 0){
1432 skip_start_tag(&p, tag_name);
1433 } else if(strcmp(tag_name, "sub") == 0){
1434 skip_end_tag(&p, tag_name);
1435 } else if(strcmp(tag_name, "sup") == 0){
1436 skip_end_tag(&p, tag_name);
1437
1438 }
1439 } else if(g_unichar_isspace(ch)){
1440 p = g_utf8_next_char(p);
1441 } else {
1442 pp += g_unichar_to_utf8(ch,
1443 pp);
1444 *pp = '\0';
1445 p = g_utf8_next_char(p);
1446 }
1447 }
1448
1449 rp->data.eb.plain_heading = g_strdup(body);
1450
1451 }
1452 }
1453
sort_result(gchar * word)1454 static void sort_result(gchar *word)
1455 {
1456 RESULT *rp;
1457 GList *l;
1458 GList *insert;
1459 gchar l_word[512];
1460 gunichar ch;
1461 gint i;
1462 gint len;
1463 gchar *p;
1464 gchar *pp;
1465
1466 char *keywords[EBOOK_MAX_KEYWORDS + 1];
1467
1468 len = g_utf8_strlen(word, -1);
1469
1470 p = word;
1471 pp = l_word;
1472
1473 for(i=0;i<len;i++){
1474 ch = g_utf8_get_char(p);
1475 if(g_unichar_isspace(ch) == FALSE){
1476 pp += g_unichar_to_utf8(ch, pp);
1477 *pp = '\0';
1478 }
1479 p = g_utf8_next_char(p);
1480 }
1481
1482 insert = g_list_first(search_result);
1483
1484 // Exact match
1485 for(l = search_result ; l != NULL; ){
1486 rp = (RESULT *)(l->data);
1487
1488 if((strstr(rp->data.eb.plain_heading, l_word) == rp->data.eb.plain_heading) &&
1489 (strlen(rp->data.eb.plain_heading) == strlen(l_word))){
1490 if(l != insert){
1491 l = g_list_next(l);
1492 search_result = g_list_remove(search_result, rp);
1493 search_result = g_list_insert_before(search_result, insert, rp);
1494 continue;
1495 } else {
1496 insert = g_list_next(insert);
1497 }
1498 }
1499 l = g_list_next(l);
1500 }
1501
1502 // Forward match
1503 for(l = insert ; l != NULL; ){
1504 rp = (RESULT *)(l->data);
1505
1506 if(strstr(rp->data.eb.plain_heading, l_word) == rp->data.eb.plain_heading){
1507 if(l != insert){
1508 l = g_list_next(l);
1509 search_result = g_list_remove(search_result, rp);
1510 search_result = g_list_insert_before(search_result, insert, rp);
1511 continue;
1512 } else {
1513 insert = g_list_next(insert);
1514 }
1515 }
1516 l = g_list_next(l);
1517 }
1518
1519 // Partial match
1520 for(l = insert ; l != NULL; ){
1521 rp = (RESULT *)(l->data);
1522
1523 if(strstr(rp->data.eb.plain_heading, l_word) != NULL){
1524 if(l != insert){
1525 l = g_list_next(l);
1526 search_result = g_list_remove(search_result, rp);
1527 search_result = g_list_insert_before(search_result, insert, rp);
1528 continue;
1529 } else {
1530 insert = g_list_next(insert);
1531 }
1532 }
1533 l = g_list_next(l);
1534 }
1535
1536
1537 // keyword match
1538 split_word(word, keywords);
1539 for(l = insert ; l != NULL; ){
1540 rp = (RESULT *)(l->data);
1541
1542 for(i=0 ; ; i++){
1543 if(keywords[i] == NULL){
1544 if(l != insert){
1545 l = g_list_next(l);
1546 search_result = g_list_remove(search_result, rp);
1547 search_result = g_list_insert_before(search_result, insert, rp);
1548 continue;
1549 } else {
1550 insert = g_list_next(insert);
1551 }
1552 }
1553 if(strstr(rp->data.eb.plain_heading, l_word) == NULL)
1554 break;
1555 }
1556 l = g_list_next(l);
1557 }
1558
1559 free_words(keywords);
1560
1561 }
1562
ebook_search_thread(void * arg)1563 static void *ebook_search_thread(void *arg)
1564 {
1565 char word[MAX_BUFSIZE];
1566 gboolean active;
1567 GtkTreeIter iter;
1568 gint state;
1569
1570
1571 LOG(LOG_DEBUG, "IN : ebook_search_thread(%s)", arg);
1572
1573 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state);
1574 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &state);
1575
1576
1577 strncpy(word, arg, sizeof(word) -1);
1578 word[sizeof(word)-1] = '\0';
1579
1580 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dict_store), &iter) == TRUE){
1581 do {
1582 gtk_tree_model_get (GTK_TREE_MODEL(dict_store),
1583 &iter,
1584 DICT_ACTIVE_COLUMN, &active,
1585 -1);
1586 if(active == TRUE){
1587 if((ebook_search_method() == SEARCH_METHOD_AUTOMATIC) &&
1588 (bsort_by_dictionary == FALSE)){
1589 ebook_search3(word, &iter);
1590 } else {
1591 ebook_search2(word, &iter);
1592 }
1593 thread_end();
1594 break;
1595 }
1596 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(dict_store), &iter) == TRUE);
1597 }
1598
1599 LOG(LOG_DEBUG, "OUT : ebook_search_thread()");
1600
1601 return(NULL);
1602 }
1603
1604 static gchar *gword=NULL;
1605
ebook_search(const char * word,gint method)1606 gint ebook_search(const char *word, gint method)
1607 {
1608 LOG(LOG_DEBUG, "IN : ebook_search(%s)", word);
1609
1610 if(gword != NULL)
1611 g_free(gword);
1612
1613 gword = strdup(word);
1614
1615 if(method == SEARCH_METHOD_FULL_TEXT){
1616 // Cancelable
1617 thread_search(TRUE, _("Fulltext search"),
1618 ebook_search_thread, (void *)gword);
1619 } else {
1620 // Non-cancelable
1621 thread_search(FALSE, _("Fulltext search"),
1622 ebook_search_thread, (void *)gword);
1623 }
1624
1625 LOG(LOG_DEBUG, "OUT : ebook_search()");
1626
1627 return(0);
1628
1629 }
1630
ebook_search_auto(char * g_word,gint method)1631 gint ebook_search_auto(char *g_word, gint method)
1632 {
1633 GtkTreeIter iter;
1634
1635 LOG(LOG_DEBUG, "IN : ebook_search_auto()");
1636
1637 if(method == SEARCH_METHOD_FULL_TEXT) {
1638 LOG(LOG_DEBUG, "OUT : ebook_search_auto()");
1639 return(0);
1640 }
1641
1642 // Search group named "selection" and use it if exests
1643 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dict_store), &iter) == TRUE){
1644 do {
1645 gchar *title;
1646
1647 gtk_tree_model_get (GTK_TREE_MODEL(dict_store),
1648 &iter,
1649 DICT_TITLE_COLUMN, &title,
1650 -1);
1651 if(strcasecmp(title, "selection") == 0){
1652 g_free(title);
1653 ebook_search2(g_word, &iter);
1654 return(0);
1655 }
1656 g_free(title);
1657 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(dict_store), &iter) == TRUE);
1658 }
1659
1660 // If there is no "selection" group, use active group
1661 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dict_store), &iter) == TRUE){
1662 do {
1663 gboolean active;
1664
1665 gtk_tree_model_get (GTK_TREE_MODEL(dict_store),
1666 &iter,
1667 DICT_ACTIVE_COLUMN, &active,
1668 -1);
1669 if(active == TRUE){
1670 ebook_search2(g_word, &iter);
1671 return(0);
1672 }
1673 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(dict_store), &iter) == TRUE);
1674 }
1675
1676 LOG(LOG_DEBUG, "OUT : ebook_search_auto()");
1677 return(0);
1678 }
1679
1680
ebook_simple_search2(BOOK_INFO * binfo,char * word,gint method,gchar * title)1681 gint ebook_simple_search2(BOOK_INFO *binfo, char *word, gint method, gchar *title)
1682 {
1683 EB_Error_Code error_code=EB_SUCCESS;
1684 int i, total_hits=0;
1685 ssize_t len;
1686 EB_Hit hits[MAX_HITS];
1687 int hitcount;
1688 char heading[MAXLEN_HEADING + 1];
1689 char *keywords[EBOOK_MAX_KEYWORDS + 1];
1690 RESULT *rp;
1691
1692 LOG(LOG_DEBUG, "IN : ebook_simple_search2(%s, %s, %d, %s)", binfo->subbook_title, word, method, title);
1693
1694 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS){
1695 LOG(LOG_DEBUG, "OUT : ebook_simple_search2()");
1696 return(error_code);
1697 }
1698
1699 switch(method){
1700 case SEARCH_METHOD_WORD:
1701 error_code = eb_search_word(binfo->book, word);
1702 break;
1703 case SEARCH_METHOD_ENDWORD:
1704 error_code = eb_search_endword(binfo->book, word);
1705 break;
1706 case SEARCH_METHOD_EXACTWORD:
1707 error_code = eb_search_exactword(binfo->book, word);
1708 break;
1709 case SEARCH_METHOD_KEYWORD:
1710 split_word(word, keywords);
1711 error_code = eb_search_keyword(binfo->book,
1712 (const char * const *)keywords);
1713 free_words(keywords);
1714 break;
1715 case SEARCH_METHOD_MULTI:
1716 split_word(word, keywords);
1717
1718 for(i=0;i<EBOOK_MAX_KEYWORDS;i++){
1719 if(keywords[i] == NULL)
1720 break;
1721 }
1722
1723 error_code = eb_search_multi(binfo->book,
1724 global_multi_code,
1725 (const char * const *)keywords);
1726 free_words(keywords);
1727 break;
1728 default:
1729 error_code = EB_ERR_NO_SUCH_SEARCH;
1730 break;
1731 }
1732
1733 if (error_code != EB_SUCCESS){
1734 LOG(LOG_CRITICAL, "Failed to search : %s",
1735 ebook_error_message(error_code));
1736 return(error_code);
1737 }
1738
1739 total_hits = count_result(search_result);
1740
1741 while(1){
1742 error_code = eb_hit_list(binfo->book,
1743 MAX_HITS,
1744 hits,
1745 &hitcount);
1746 if(error_code != EB_SUCCESS){
1747 return(error_code);
1748 }
1749
1750 if(hitcount == 0)
1751 break;
1752 LOG(LOG_DEBUG, "%d HIT", hitcount);
1753
1754 for(i = 0 ; i < hitcount ; i ++){
1755 if((max_search != 0) && (total_hits >= max_search))
1756 return(EB_SUCCESS);
1757
1758 if(check_duplicate_hit(hits[i].text) == TRUE)
1759 continue;
1760
1761 rp = (RESULT *)calloc(sizeof(RESULT),1);
1762 if(rp == NULL){
1763 LOG(LOG_ERROR, "No memory");
1764 exit(1);
1765 }
1766
1767 error_code = eb_seek_text(binfo->book,
1768 &(hits[i].heading));
1769
1770 if(error_code != EB_SUCCESS){
1771 return(error_code);
1772 }
1773
1774 error_code = eb_read_heading(binfo->book,
1775 binfo->appendix,
1776 &heading_hookset,
1777 NULL,
1778 MAXLEN_HEADING,
1779 heading,
1780 &len);
1781 if (error_code != EB_SUCCESS) {
1782 return(error_code);
1783 }
1784 heading[len] = '\0';
1785
1786 rp->heading = iconv_convert("euc-jp", "utf-8", heading);
1787 if(method == SEARCH_METHOD_MULTI)
1788 rp->word = NULL;
1789 else
1790 rp->word = iconv_convert("euc-jp", "utf-8", word);
1791
1792 rp->type = RESULT_TYPE_EB;
1793 rp->data.eb.book_info = binfo;
1794 rp->data.eb.search_method = method;
1795 rp->data.eb.dict_title = strdup(title);
1796
1797 rp->data.eb.pos_heading = hits[i].heading;
1798 rp->data.eb.pos_text = hits[i].text;
1799
1800 add_result(rp);
1801
1802 total_hits ++;
1803
1804 }
1805 }
1806
1807 LOG(LOG_DEBUG, "OUT : ebook_simple_search2()");
1808 return(error_code);
1809 }
1810
ebook_simple_search(BOOK_INFO * binfo,char * word,gint method,gchar * title)1811 gint ebook_simple_search(BOOK_INFO *binfo, char *word, gint method, gchar *title)
1812 {
1813 gchar *l_word=NULL;
1814 EB_Error_Code error_code=EB_SUCCESS;
1815
1816 LOG(LOG_DEBUG, "IN : ebook_simple_search()");
1817
1818 // If the keyword is Japanese, try Hiragana and Katakana
1819
1820 if(iseuc(word)){
1821 l_word = g_strdup(word);
1822 katakana_to_hiragana(l_word);
1823 error_code = ebook_simple_search2(binfo, l_word, method, title);
1824 if(error_code != EB_SUCCESS){
1825 goto END;
1826 }
1827
1828 hiragana_to_katakana(l_word);
1829 error_code = ebook_simple_search2(binfo, l_word, method, title);
1830 } else {
1831 // Not Japanese
1832 error_code = ebook_simple_search2(binfo, word, method, title);
1833 }
1834 END:
1835 g_free(l_word);
1836 LOG(LOG_DEBUG, "OUT : ebook_simple_search()");
1837 return(error_code);
1838 }
1839
ebook_ending_search(BOOK_INFO * binfo,char * word,gint method,gchar * title)1840 static gint ebook_ending_search(BOOK_INFO *binfo, char *word, gint method, gchar *title)
1841 {
1842 EB_Error_Code error_code=EB_SUCCESS;
1843 gint i;
1844 gint len_word, len_ending;
1845 char *keywords[EBOOK_MAX_KEYWORDS + 1];
1846 char new_word[MAX_BUFSIZE];
1847 char new_key[256];
1848 char *save_key;
1849
1850 GtkTreeIter iter;
1851
1852 LOG(LOG_DEBUG, "IN : ebook_ending_search(method=%d)", method);
1853
1854
1855 g_assert(binfo != NULL);
1856 g_assert(word != NULL);
1857
1858 error_code = ebook_simple_search(binfo, word, method, title);
1859
1860 if((bending_only_nohit == 1) && (count_result(search_result) != 0)){
1861 return(error_code);
1862 }
1863
1864 split_word(word, keywords);
1865
1866 for(i=0; keywords[i] != NULL ; i++){
1867
1868 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(stemming_en_store), &iter) == TRUE){
1869 do {
1870 gchar *pattern;
1871 gchar *normal;
1872
1873 gtk_tree_model_get(GTK_TREE_MODEL(stemming_en_store),
1874 &iter,
1875 STEMMING_PATTERN_COLUMN, &pattern,
1876 STEMMING_NORMAL_COLUMN, &normal,
1877 -1);
1878
1879
1880 len_word = strlen(keywords[i]);
1881 len_ending = strlen(pattern);
1882 if(len_word < len_ending){
1883 continue;
1884 }
1885
1886 if(strcmp(&keywords[i][len_word - len_ending], pattern) == 0){
1887 memcpy(new_key, keywords[i], len_word - len_ending);
1888 if(normal)
1889 sprintf(&new_key[len_word - len_ending],"%s", normal);
1890 else
1891 new_key[len_word - len_ending] = '\0';
1892 save_key = keywords[i];
1893 keywords[i] = new_key;
1894 cat_word(new_word, keywords);
1895 error_code = ebook_simple_search(binfo, new_word, method, title);
1896 keywords[i] = save_key;
1897 if(error_code != EB_SUCCESS){
1898 return(error_code);
1899 }
1900 }
1901
1902 g_free(pattern);
1903 g_free(normal);
1904
1905 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(stemming_en_store), &iter) == TRUE);
1906 }
1907
1908
1909 }
1910
1911 // Japanese stemming
1912 // Japanese keyword must not be multiple words.
1913
1914 if(keywords[1] == NULL){
1915
1916 if((count_result(search_result) != 0) &&
1917 (bending_only_nohit == 1))
1918 goto END;
1919
1920 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(stemming_ja_store), &iter) == TRUE){
1921 do {
1922 gchar *pattern;
1923 gchar *normal;
1924 gchar *tmp;
1925
1926 gtk_tree_model_get(GTK_TREE_MODEL(stemming_ja_store),
1927 &iter,
1928 STEMMING_PATTERN_COLUMN, &pattern,
1929 STEMMING_NORMAL_COLUMN, &normal,
1930 -1);
1931
1932 tmp = iconv_convert("utf-8", "euc-jp", pattern);
1933 g_free(pattern);
1934 pattern = tmp;
1935
1936 tmp = iconv_convert("utf-8", "euc-jp", normal);
1937 g_free(normal);
1938 normal = tmp;
1939
1940 len_word = strlen(keywords[0]);
1941 len_ending = strlen(pattern);
1942 if(len_word < len_ending){
1943 continue;
1944 }
1945
1946
1947 for(i=0; i<len_word; i+=2){
1948 if(strncmp(&keywords[0][i], pattern, len_ending) == 0){
1949 memcpy(new_key, keywords[0], i);
1950 sprintf(&new_key[i],"%s", normal);
1951 error_code = ebook_simple_search(binfo, new_key, method, title);
1952 if(error_code != EB_SUCCESS){
1953 return(error_code);
1954 }
1955 }
1956 }
1957
1958
1959 g_free(pattern);
1960 g_free(normal);
1961
1962 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(stemming_ja_store), &iter) == TRUE);
1963 }
1964
1965 // If there is no hit, try using only Kanji part.
1966 if((count_result(search_result) == 0) &&
1967 (iseuckanji(keywords[0]))){
1968 len_word = strlen(keywords[0]);
1969 strcpy(new_key, keywords[0]);
1970 for(i=0; i<len_word; i+=2){
1971 if(!iseuckanji(&new_key[i])) {
1972 new_key[i] = '\0';
1973 break;
1974 }
1975 }
1976
1977 error_code = ebook_simple_search(binfo, new_key, method, title);
1978 if(error_code != EB_SUCCESS){
1979 return(error_code);
1980 }
1981 }
1982 }
1983
1984 END:
1985 free_words(keywords);
1986
1987 LOG(LOG_DEBUG, "OUT : ebook_ending_search()");
1988 return(error_code);
1989 }
1990
ebook_get_heading(BOOK_INFO * binfo,int page,int offset)1991 gchar *ebook_get_heading(BOOK_INFO *binfo, int page, int offset)
1992 {
1993 EB_Error_Code error_code;
1994 ssize_t len;
1995 char heading[MAXLEN_HEADING + 1];
1996 EB_Position position;
1997 gchar *p;
1998
1999 LOG(LOG_DEBUG, "IN : ebook_get_heading()");
2000
2001 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2002 return(NULL);
2003
2004 error_code = eb_seek_text(binfo->book, &position);
2005 if(error_code != EB_SUCCESS){
2006 LOG(LOG_CRITICAL, "Failed to seek text : %s",
2007 ebook_error_message(error_code));
2008 return(NULL);
2009 }
2010
2011 error_code = eb_read_heading(binfo->book, binfo->appendix, &text_hookset, NULL, MAXLEN_HEADING, heading, &len);
2012 if (error_code != EB_SUCCESS) {
2013 LOG(LOG_CRITICAL, "Failed to read heading : %s",
2014 ebook_error_message(error_code));
2015 return(NULL);
2016 }
2017 heading[len] = '\0';
2018
2019 p = malloc(len+1);
2020 memcpy(p, heading, len+1);
2021 LOG(LOG_DEBUG, "OUT : ebook_get_heading()");
2022 return(p);
2023 }
2024
ebook_get_text(BOOK_INFO * binfo,int page,int offset)2025 gchar *ebook_get_text(BOOK_INFO *binfo, int page, int offset){
2026 EB_Error_Code error_code;
2027 ssize_t len;
2028 char text[MAXLEN_TEXT + 1];
2029 EB_Position position;
2030 gchar *p;
2031
2032 LOG(LOG_DEBUG, "IN : ebook_get_text()");
2033
2034 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2035 return(NULL);
2036
2037
2038 position.page = page;
2039 position.offset = offset;
2040
2041 error_code = eb_seek_text(binfo->book, &position);
2042 if(error_code != EB_SUCCESS){
2043 LOG(LOG_CRITICAL, "Failed to seek text : %s",
2044 ebook_error_message(error_code));
2045 LOG(LOG_DEBUG, "OUT : ebook_get_text()=NULL");
2046 return(NULL);
2047 }
2048
2049
2050 error_code = eb_read_text(binfo->book, binfo->appendix, &text_hookset,
2051 NULL, MAXLEN_TEXT, text, &len);
2052 if (error_code != EB_SUCCESS) {
2053 LOG(LOG_CRITICAL, "Failed to read text : %s",
2054 ebook_error_message(error_code));
2055 LOG(LOG_DEBUG, "OUT : ebook_get_text()=NULL");
2056 return(NULL);
2057 }
2058 text[len] = '\0';
2059
2060 p = malloc(len+1);
2061 memcpy(p, text, len+1);
2062
2063 LOG(LOG_DEBUG, "OUT : ebook_get_text()");
2064 return(p);
2065 }
2066
ebook_get_candidate(BOOK_INFO * binfo,int page,int offset)2067 gchar *ebook_get_candidate(BOOK_INFO *binfo, int page, int offset)
2068 {
2069 EB_Error_Code error_code;
2070 ssize_t len;
2071 char text[MAXLEN_TEXT + 1];
2072 EB_Position position;
2073 gchar *p;
2074
2075
2076 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2077 return(NULL);
2078
2079
2080 position.page = page;
2081 position.offset = offset;
2082
2083 error_code = eb_seek_text(binfo->book, &position);
2084 if(error_code != EB_SUCCESS){
2085 LOG(LOG_CRITICAL, "Failed to seek text : %s",
2086 ebook_error_message(error_code));
2087 return(NULL);
2088 }
2089
2090 error_code = eb_read_text(binfo->book, binfo->appendix, &candidate_hookset,
2091 NULL, MAXLEN_TEXT, text, &len);
2092 if (error_code != EB_SUCCESS) {
2093 LOG(LOG_CRITICAL, "Failed to read text : %s",
2094 ebook_error_message(error_code));
2095 return(NULL);
2096 }
2097 text[len] = '\0';
2098
2099 p = malloc(len+1);
2100 memcpy(p, text, len+1);
2101 return(p);
2102 }
2103
ebook_forward_text(BOOK_INFO * binfo)2104 EB_Error_Code ebook_forward_text(BOOK_INFO *binfo)
2105 {
2106 EB_Error_Code error_code;
2107
2108 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2109 return(error_code);
2110
2111 error_code = eb_seek_text(binfo->book, ¤t_result->data.eb.pos_text);
2112 if(error_code != EB_SUCCESS){
2113 LOG(LOG_CRITICAL, "Failed to seek text : %s",
2114 ebook_error_message(error_code));
2115 return(error_code);
2116 }
2117
2118 error_code = eb_forward_text(binfo->book, binfo->appendix);
2119 if(error_code != EB_SUCCESS){
2120 LOG(LOG_CRITICAL, "Failed to forward text : %s",
2121 ebook_error_message(error_code));
2122 return(error_code);
2123 }
2124
2125 return(EB_SUCCESS);
2126 }
2127
ebook_backward_text(BOOK_INFO * binfo)2128 EB_Error_Code ebook_backward_text(BOOK_INFO *binfo)
2129 {
2130 EB_Error_Code error_code;
2131 int stop_code = -1;
2132
2133 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2134 return(error_code);
2135
2136 stop_code = binfo->book->text_context.auto_stop_code;
2137
2138 error_code = eb_seek_text(binfo->book, ¤t_result->data.eb.pos_text);
2139 if(error_code != EB_SUCCESS){
2140 LOG(LOG_CRITICAL, "Failed to seek text : %s",
2141 ebook_error_message(error_code));
2142 return(error_code);
2143 }
2144
2145 if(stop_code != -1)
2146 binfo->book->text_context.auto_stop_code = stop_code;
2147
2148 error_code = ebook_my_backward_text(binfo);
2149 if(error_code != EB_SUCCESS){
2150 LOG(LOG_CRITICAL, "Failed to back text : %s",
2151 ebook_error_message(error_code));
2152 return(error_code);
2153 }
2154
2155 return(EB_SUCCESS);
2156 }
2157
ebook_tell_text(BOOK_INFO * binfo,gint * page,gint * offset)2158 void ebook_tell_text(BOOK_INFO *binfo, gint *page, gint *offset)
2159 {
2160 EB_Error_Code error_code;
2161 EB_Position position;
2162
2163 error_code = eb_tell_text(binfo->book, &position);
2164 if(error_code != EB_SUCCESS){
2165 LOG(LOG_CRITICAL, "Failed to tell text : %s",
2166 ebook_error_message(error_code));
2167 return;
2168 }
2169
2170 *page = position.page;
2171 *offset = position.offset;
2172
2173 return;
2174 }
2175
ebook_menu(BOOK_INFO * binfo,EB_Position * pos)2176 EB_Error_Code ebook_menu(BOOK_INFO *binfo, EB_Position *pos)
2177 {
2178 EB_Error_Code error_code=EB_SUCCESS;
2179
2180 error_code = eb_menu(binfo->book, pos);
2181 if(error_code != EB_SUCCESS) {
2182 LOG(LOG_CRITICAL, "Failed to get menu position : %s",
2183 ebook_error_message(error_code));
2184 }
2185 return(error_code);
2186 }
2187
ebook_copyright(BOOK_INFO * binfo,EB_Position * pos)2188 EB_Error_Code ebook_copyright(BOOK_INFO *binfo, EB_Position *pos)
2189 {
2190 EB_Error_Code error_code=EB_SUCCESS;
2191
2192 error_code = eb_copyright(binfo->book, pos);
2193 if(error_code != EB_SUCCESS) {
2194 LOG(LOG_CRITICAL, "Failed to get copyright position : %s",
2195 ebook_error_message(error_code));
2196 }
2197 return(error_code);
2198 }
2199
ebook_bitmap_to_xbm(const char * bitmap,int width,int height,char * xbm,size_t * xbm_length)2200 static void ebook_bitmap_to_xbm(const char *bitmap, int width, int height, char *xbm, size_t *xbm_length)
2201 {
2202 char *xbm_p = xbm;
2203 const unsigned char *bitmap_p = (const unsigned char *)bitmap;
2204 int bitmap_size = (width + 7) / 8 * height;
2205 int hex;
2206 int i;
2207
2208 for (i = 0; i < bitmap_size; i++) {
2209 hex = 0;
2210 if (*bitmap_p & 0x80)
2211 hex |= 0x01;
2212 if (*bitmap_p & 0x40)
2213 hex |= 0x02;
2214 if (*bitmap_p & 0x20)
2215 hex |= 0x04;
2216 if (*bitmap_p & 0x10)
2217 hex |= 0x08;
2218 if (*bitmap_p & 0x08)
2219 hex |= 0x10;
2220 if (*bitmap_p & 0x04)
2221 hex |= 0x20;
2222 if (*bitmap_p & 0x02)
2223 hex |= 0x40;
2224 if (*bitmap_p & 0x01)
2225 hex |= 0x80;
2226 bitmap_p++;
2227
2228 *xbm_p = hex;
2229 xbm_p ++;
2230 }
2231
2232 *xbm_length = (xbm_p - xbm);
2233 }
2234
check_gaiji_size(BOOK_INFO * binfo,gint prefered_size)2235 gint check_gaiji_size(BOOK_INFO *binfo, gint prefered_size){
2236 gint size;
2237
2238 size = prefered_size;
2239
2240 switch(size){
2241 case 48:
2242 if (eb_have_font(binfo->book, EB_FONT_48)){
2243 size = 48;
2244 break;
2245 }
2246 size = 30;
2247 case 30:
2248 if (eb_have_font(binfo->book, EB_FONT_30)){
2249 size = 30;
2250 break;
2251 }
2252 size = 24;
2253 case 24:
2254 if (eb_have_font(binfo->book, EB_FONT_24)){
2255 size = 24;
2256 break;
2257 }
2258 size = 16;
2259 case 16:
2260 if (eb_have_font(binfo->book, EB_FONT_16)){
2261 size = 16;
2262 break;
2263 }
2264 LOG(LOG_CRITICAL, "Failed to find 16 dot gaiji : subbook=%s",
2265 binfo->subbook_title);
2266 return(-1);
2267
2268 }
2269
2270 if(size != prefered_size){
2271 LOG(LOG_CRITICAL, "Cannot find %d dot gaiji. Use %d dot instead",
2272 prefered_size, size);
2273 }
2274
2275 return(size);
2276
2277 }
2278
read_gaiji_as_bitmap(BOOK_INFO * binfo,gchar * name,gint size,gint * width,gint * height)2279 guchar *read_gaiji_as_bitmap(BOOK_INFO *binfo, gchar *name, gint size, gint *width, gint *height)
2280 {
2281 EB_Error_Code error_code = EB_SUCCESS;
2282 gint char_no;
2283 gchar bitmap_data[EB_SIZE_WIDE_FONT_48];
2284 guchar *image_data;
2285 size_t image_size;
2286 int image_width;
2287 int image_height;
2288 EB_Subbook *subbook;
2289
2290
2291 char_no = strtol(&name[1], NULL, 16);
2292
2293 subbook = binfo->book->subbook_current;
2294
2295 switch (size) {
2296 case 16:
2297 error_code = eb_set_font(binfo->book, EB_FONT_16);
2298 break;
2299 case 24:
2300 error_code = eb_set_font(binfo->book, EB_FONT_24);
2301 break;
2302 case 30:
2303 error_code = eb_set_font(binfo->book, EB_FONT_30);
2304 break;
2305 case 48:
2306 error_code = eb_set_font(binfo->book, EB_FONT_48);
2307 break;
2308 }
2309
2310 if (error_code != EB_SUCCESS) {
2311 LOG(LOG_CRITICAL, "Failed to set font : subbook=%s\n%s",
2312 binfo->subbook_title,
2313 ebook_error_message(error_code));
2314 return(NULL);
2315 }
2316
2317
2318 error_code = eb_font_height(binfo->book, &image_height);
2319 if (error_code != EB_SUCCESS) {
2320 LOG(LOG_CRITICAL, "Failed to get font height : subbook=%s\n%s",
2321 binfo->subbook_title,
2322 ebook_error_message(error_code));
2323 return(NULL);
2324 }
2325
2326
2327 if(name[0] == 'h'){
2328 if (!eb_have_narrow_font(binfo->book)){
2329 LOG(LOG_CRITICAL, "%s does not have narrow font",
2330 binfo->subbook_title);
2331 return(NULL);
2332 }
2333 error_code = eb_narrow_font_width(binfo->book, &image_width);
2334 if (error_code != EB_SUCCESS) {
2335 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2336 binfo->subbook_title,
2337 ebook_error_message(error_code));
2338 return(NULL);
2339 }
2340 error_code = eb_narrow_font_character_bitmap(
2341 binfo->book,
2342 char_no,
2343 bitmap_data);
2344 if (error_code != EB_SUCCESS) {
2345 LOG(LOG_CRITICAL, "Failed to read narrow font : subbook=%s, character=0x%04x\n%s",
2346 binfo->subbook_title,
2347 char_no,
2348 ebook_error_message(error_code));
2349 return(NULL);
2350
2351 }
2352 } else {
2353 if (!eb_have_wide_font(binfo->book)){
2354 LOG(LOG_CRITICAL, "%s does not have wide font",
2355 binfo->subbook_title);
2356 return(NULL);
2357 }
2358 error_code = eb_wide_font_width(binfo->book, &image_width);
2359 if (error_code != EB_SUCCESS) {
2360 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2361 binfo->subbook_title,
2362 ebook_error_message(error_code));
2363 return(NULL);
2364 }
2365 error_code = eb_wide_font_character_bitmap(
2366 binfo->book,
2367 char_no,
2368 bitmap_data);
2369 if (error_code != EB_SUCCESS) {
2370 LOG(LOG_CRITICAL, "Failed to read wide font : subbook=%s, character=0x%04x\n%s",
2371 binfo->subbook_title,
2372 char_no,
2373 ebook_error_message(error_code));
2374 return(NULL);
2375 }
2376 }
2377
2378 image_data = malloc(image_width * image_height / 8);
2379 ebook_bitmap_to_xbm(bitmap_data, image_width,
2380 image_height, image_data, &image_size);
2381
2382 *width = image_width;
2383 *height = image_height;
2384
2385 return(image_data);
2386
2387 }
2388
ebook_bitmap_to_xpm(const gchar * bitmap,gint width,gint height,gchar * color)2389 static gchar **ebook_bitmap_to_xpm(const gchar *bitmap, gint width, gint height, gchar *color)
2390 {
2391 gchar **xpm;
2392 gchar *xpm_p;
2393 int i, j;
2394 const unsigned char *bitmap_p = (const unsigned char *)bitmap;
2395
2396 xpm = g_new(gchar *, height + 4 + gaiji_adjustment);
2397
2398 xpm[0] = g_strdup_printf("%d %d 2 1", width, height+gaiji_adjustment);
2399 xpm[1] = g_strdup_printf(" c None");
2400 if(color == NULL)
2401 xpm[2] = g_strdup_printf(". c Black");
2402 else
2403 xpm[2] = g_strdup_printf(". c %s", color);
2404
2405 for (i = 0; i < gaiji_adjustment; i++) {
2406 xpm[i+3] = g_new(guchar, width + 1);
2407 memset(xpm[i+3], ' ', width);
2408 xpm[i+3][width] = '\0';
2409 }
2410
2411 for (;i < height + gaiji_adjustment; i++) {
2412 xpm[i+3] = g_new(guchar, width + 1);
2413 xpm_p = xpm[i+3];
2414 for (j = 0; j + 7 < width; j += 8, bitmap_p++) {
2415 *xpm_p++ = (*bitmap_p & 0x80) ? '.' : ' ';
2416 *xpm_p++ = (*bitmap_p & 0x40) ? '.' : ' ';
2417 *xpm_p++ = (*bitmap_p & 0x20) ? '.' : ' ';
2418 *xpm_p++ = (*bitmap_p & 0x10) ? '.' : ' ';
2419 *xpm_p++ = (*bitmap_p & 0x08) ? '.' : ' ';
2420 *xpm_p++ = (*bitmap_p & 0x04) ? '.' : ' ';
2421 *xpm_p++ = (*bitmap_p & 0x02) ? '.' : ' ';
2422 *xpm_p++ = (*bitmap_p & 0x01) ? '.' : ' ';
2423 }
2424
2425 if (j < width) {
2426 if (j++ < width)
2427 *xpm_p++ = (*bitmap_p & 0x80) ? '.' : ' ';
2428 if (j++ < width)
2429 *xpm_p++ = (*bitmap_p & 0x40) ? '.' : ' ';
2430 if (j++ < width)
2431 *xpm_p++ = (*bitmap_p & 0x20) ? '.' : ' ';
2432 if (j++ < width)
2433 *xpm_p++ = (*bitmap_p & 0x10) ? '.' : ' ';
2434 if (j++ < width)
2435 *xpm_p++ = (*bitmap_p & 0x08) ? '.' : ' ';
2436 if (j++ < width)
2437 *xpm_p++ = (*bitmap_p & 0x04) ? '.' : ' ';
2438 if (j++ < width)
2439 *xpm_p++ = (*bitmap_p & 0x02) ? '.' : ' ';
2440 if (j++ < width)
2441 *xpm_p++ = (*bitmap_p & 0x01) ? '.' : ' ';
2442 bitmap_p++;
2443 }
2444 *xpm_p = '\0';
2445 }
2446 xpm[i+3] = '\0';
2447
2448 return(xpm);
2449 }
2450
2451
read_gaiji_as_xpm(BOOK_INFO * binfo,gchar * name,gint size,gint * width,gint * height,gchar * color)2452 gchar **read_gaiji_as_xpm(BOOK_INFO *binfo, gchar *name, gint size, gint *width, gint *height, gchar *color)
2453 {
2454 EB_Error_Code error_code = EB_SUCCESS;
2455 gint char_no;
2456 gchar bitmap_data[EB_SIZE_WIDE_FONT_48];
2457 guchar *image_data;
2458 int image_width;
2459 int image_height;
2460 EB_Subbook *subbook;
2461 gchar **xpm;
2462
2463 LOG(LOG_DEBUG, "IN : read_gaiji_as_xpm(name=%s, size=%d)", name, size);
2464
2465 char_no = strtol(&name[1], NULL, 16);
2466
2467 subbook = binfo->book->subbook_current;
2468
2469 switch (size) {
2470 case 16:
2471 error_code = eb_set_font(binfo->book, EB_FONT_16);
2472 break;
2473 case 24:
2474 error_code = eb_set_font(binfo->book, EB_FONT_24);
2475 break;
2476 case 30:
2477 error_code = eb_set_font(binfo->book, EB_FONT_30);
2478 break;
2479 case 48:
2480 error_code = eb_set_font(binfo->book, EB_FONT_48);
2481 break;
2482 }
2483
2484 if (error_code != EB_SUCCESS) {
2485 LOG(LOG_CRITICAL, "Failed to set font : subbook=%s\n%s",
2486 binfo->subbook_title,
2487 ebook_error_message(error_code));
2488 return(NULL);
2489 }
2490
2491
2492 error_code = eb_font_height(binfo->book, &image_height);
2493 if (error_code != EB_SUCCESS) {
2494 LOG(LOG_CRITICAL, "Failed to get font height : subbook=%s\n%s",
2495 binfo->subbook_title,
2496 ebook_error_message(error_code));
2497 return(NULL);
2498 }
2499
2500
2501 if(name[0] == 'h'){
2502 if (!eb_have_narrow_font(binfo->book)){
2503 LOG(LOG_CRITICAL, "%s does not have narrow font",
2504 binfo->subbook_title);
2505 return(NULL);
2506 }
2507 error_code = eb_narrow_font_width(binfo->book, &image_width);
2508 if (error_code != EB_SUCCESS) {
2509 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2510 binfo->subbook_title,
2511 ebook_error_message(error_code));
2512 return(NULL);
2513 }
2514 error_code = eb_narrow_font_character_bitmap(
2515 binfo->book,
2516 char_no,
2517 bitmap_data);
2518 if (error_code != EB_SUCCESS) {
2519 LOG(LOG_CRITICAL, "Failed to read narrow font : subbook=%s, character=0x%04x\n%s",
2520 binfo->subbook_title,
2521 char_no,
2522 ebook_error_message(error_code));
2523 return(NULL);
2524
2525 }
2526 } else {
2527 if (!eb_have_wide_font(binfo->book)){
2528 LOG(LOG_CRITICAL, "%s does not have wide font",
2529 binfo->subbook_title);
2530 return(NULL);
2531 }
2532 error_code = eb_wide_font_width(binfo->book, &image_width);
2533 if (error_code != EB_SUCCESS) {
2534 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2535 binfo->subbook_title,
2536 ebook_error_message(error_code));
2537 return(NULL);
2538 }
2539 error_code = eb_wide_font_character_bitmap(
2540 binfo->book,
2541 char_no,
2542 bitmap_data);
2543 if (error_code != EB_SUCCESS) {
2544 LOG(LOG_CRITICAL, "Failed to read wide font : subbook=%s, character=0x%04x\n%s",
2545 binfo->subbook_title,
2546 char_no,
2547 ebook_error_message(error_code));
2548 return(NULL);
2549 }
2550 }
2551
2552 image_data = malloc((image_width + 4)* (image_height* 5));
2553 xpm = ebook_bitmap_to_xpm(bitmap_data, image_width, image_height, color);
2554
2555 *width = image_width;
2556 *height = image_height + gaiji_adjustment;
2557
2558 #if 0
2559 {
2560 gint i;
2561 for(i=0; i < size+3 ; i ++){
2562 printf("%s\n", xpm[i]);
2563 }
2564 }
2565 #endif
2566
2567 LOG(LOG_DEBUG, "OUT : read_gaiji_as_xpm()");
2568
2569 return(xpm);
2570
2571 }
2572
2573 #define GIF_PREAMBLE_LENGTH 38
2574
2575 static const unsigned char gif_preamble[GIF_PREAMBLE_LENGTH] = {
2576 /*
2577 * Header. (6 bytes)
2578 */
2579 'G', 'I', 'F', '8', '9', 'a',
2580
2581 /*
2582 * Logical Screen Descriptor. (7 bytes)
2583 * global color table flag = 1.
2584 * color resolution = 1 - 1 = 0.
2585 * sort flag = 0.
2586 * size of global color table = 1 - 1 = 0.
2587 * background color index = 0.
2588 * the pixel aspect ratio = 0 (unused)
2589 * Logical screen width and height are set at run time.
2590 */
2591 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
2592
2593 /*
2594 * Global Color Table. (6 bytes)
2595 * These are set at run time.
2596 */
2597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2598
2599 /*
2600 * Graphic Control Extension. (8 bytes)
2601 * disposal method = 0.
2602 * user input flag = 0.
2603 * transparency flag = 1.
2604 * delay time = 0.
2605 * transparent color index = 0.
2606 */
2607 0x21, 0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
2608
2609 /*
2610 * Image Descriptor. (10 bytes)
2611 * image left position = 0.
2612 * image top position = 0.
2613 * local color table flag = 0.
2614 * interlace flag = 0.
2615 * sort flag = 0.
2616 * size of local color table = 0.
2617 * Image width and height are set at run time.
2618 */
2619 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2620
2621 /*
2622 * Code size. (1byte)
2623 */
2624 0x03
2625 };
2626
2627
ebook_bitmap_to_gif(bitmap,width,height,gif,gif_length,fg,bg)2628 static void ebook_bitmap_to_gif(bitmap, width, height, gif, gif_length, fg, bg)
2629 const char *bitmap;
2630 int width;
2631 int height;
2632 char *gif;
2633 guint *gif_length;
2634 guint fg;
2635 guint bg;
2636 {
2637 unsigned char *gif_p = (unsigned char *)gif;
2638 const unsigned char *bitmap_p = (const unsigned char *)bitmap;
2639 int i, j;
2640
2641
2642 /*
2643 * Copy the default preamble.
2644 */
2645 memcpy(gif_p, gif_preamble, GIF_PREAMBLE_LENGTH);
2646
2647 /*
2648 * Set logical screen width and height.
2649 */
2650 gif_p[6] = width & 0xff;
2651 gif_p[7] = (width >> 8) & 0xff;
2652 gif_p[8] = height & 0xff;
2653 gif_p[9] = (height >> 8) & 0xff;
2654
2655 /*
2656 * Set global colors.
2657 */
2658 gif_p[13] = (bg >> 16) & 0xff;
2659 gif_p[14] = (bg >> 8) & 0xff;
2660 gif_p[15] = bg & 0xff;
2661 gif_p[16] = (fg >> 16) & 0xff;
2662 gif_p[17] = (fg >> 8) & 0xff;
2663 gif_p[18] = fg & 0xff;
2664
2665 /*
2666 * Set image width and height.
2667 */
2668 gif_p[32] = width & 0xff;
2669 gif_p[33] = (width >> 8) & 0xff;
2670 gif_p[34] = height & 0xff;
2671 gif_p[35] = (height >> 8) & 0xff;
2672
2673 gif_p += GIF_PREAMBLE_LENGTH;
2674
2675 /*
2676 * Output image data.
2677 */
2678 for (i = 0; i < height; i++) {
2679 *gif_p++ = (unsigned char)width;
2680 for (j = 0; j + 7 < width; j += 8, bitmap_p++) {
2681 *gif_p++ = (*bitmap_p & 0x80) ? 0x81 : 0x80;
2682 *gif_p++ = (*bitmap_p & 0x40) ? 0x81 : 0x80;
2683 *gif_p++ = (*bitmap_p & 0x20) ? 0x81 : 0x80;
2684 *gif_p++ = (*bitmap_p & 0x10) ? 0x81 : 0x80;
2685 *gif_p++ = (*bitmap_p & 0x08) ? 0x81 : 0x80;
2686 *gif_p++ = (*bitmap_p & 0x04) ? 0x81 : 0x80;
2687 *gif_p++ = (*bitmap_p & 0x02) ? 0x81 : 0x80;
2688 *gif_p++ = (*bitmap_p & 0x01) ? 0x81 : 0x80;
2689 }
2690
2691 if (j < width) {
2692 if (j++ < width)
2693 *gif_p++ = (*bitmap_p & 0x80) ? 0x81 : 0x80;
2694 if (j++ < width)
2695 *gif_p++ = (*bitmap_p & 0x40) ? 0x81 : 0x80;
2696 if (j++ < width)
2697 *gif_p++ = (*bitmap_p & 0x20) ? 0x81 : 0x80;
2698 if (j++ < width)
2699 *gif_p++ = (*bitmap_p & 0x10) ? 0x81 : 0x80;
2700 if (j++ < width)
2701 *gif_p++ = (*bitmap_p & 0x08) ? 0x81 : 0x80;
2702 if (j++ < width)
2703 *gif_p++ = (*bitmap_p & 0x04) ? 0x81 : 0x80;
2704 if (j++ < width)
2705 *gif_p++ = (*bitmap_p & 0x02) ? 0x81 : 0x80;
2706 if (j++ < width)
2707 *gif_p++ = (*bitmap_p & 0x01) ? 0x81 : 0x80;
2708 bitmap_p++;
2709 }
2710 }
2711
2712 /*
2713 * Output a trailer.
2714 */
2715 memcpy(gif_p, "\001\011\000\073", 4);
2716 gif_p += 4;
2717
2718 if (gif_length != NULL)
2719 *gif_length = ((char *)gif_p - gif);
2720
2721 }
2722
2723
read_gaiji_as_xbm(BOOK_INFO * binfo,gchar * name,gchar * fname,guint fg,guint bg)2724 guchar *read_gaiji_as_xbm(BOOK_INFO *binfo, gchar *name, gchar *fname, guint fg, guint bg)
2725 {
2726 EB_Error_Code error_code;
2727 gint char_no;
2728 gchar bitmap_data[EB_SIZE_WIDE_FONT_48];
2729 guchar image_data[EB_SIZE_FONT_IMAGE];
2730 size_t image_size;
2731 int image_width;
2732 int image_height;
2733 EB_Subbook *subbook;
2734 FILE *fp;
2735
2736
2737 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2738 return(NULL);
2739
2740 char_no = strtol(&name[1], NULL, 16);
2741
2742 subbook = binfo->book->subbook_current;
2743
2744 error_code = eb_font_height(binfo->book, &image_height);
2745 if (error_code != EB_SUCCESS) {
2746 LOG(LOG_CRITICAL, "Failed to get font height : subbook=%s\n%s",
2747 binfo->subbook_title,
2748 ebook_error_message(error_code));
2749 return(NULL);
2750 }
2751
2752
2753 if(name[0] == 'h'){
2754 if (!eb_have_narrow_font(binfo->book)){
2755 LOG(LOG_CRITICAL, "%s does not have narrow font",
2756 binfo->subbook_title);
2757 return(NULL);
2758 }
2759 error_code = eb_narrow_font_width(binfo->book, &image_width);
2760 if (error_code != EB_SUCCESS) {
2761 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2762 binfo->subbook_title,
2763 ebook_error_message(error_code));
2764 return(NULL);
2765 }
2766 error_code = eb_narrow_font_character_bitmap(
2767 binfo->book,
2768 char_no,
2769 bitmap_data);
2770 if (error_code != EB_SUCCESS) {
2771 LOG(LOG_CRITICAL, "Failed to read narrow font : subbook=%s, character=0x%04x\n%s",
2772 binfo->subbook_title,
2773 char_no,
2774 ebook_error_message(error_code));
2775 return(NULL);
2776
2777 }
2778 } else {
2779 if (!eb_have_wide_font(binfo->book)){
2780 LOG(LOG_CRITICAL, "%s does not have wide font",
2781 binfo->subbook_title);
2782 return(NULL);
2783 }
2784 error_code = eb_wide_font_width(binfo->book, &image_width);
2785 if (error_code != EB_SUCCESS) {
2786 LOG(LOG_CRITICAL, "Failed to get font width : subbook=%s\n%s",
2787 binfo->subbook_title,
2788 ebook_error_message(error_code));
2789 return(NULL);
2790 }
2791 error_code = eb_wide_font_character_bitmap(
2792 binfo->book,
2793 char_no,
2794 bitmap_data);
2795 if (error_code != EB_SUCCESS) {
2796 LOG(LOG_CRITICAL, "Failed to read wide font : subbook=%s, character=0x%04x\n%s",
2797 binfo->subbook_title,
2798 char_no,
2799 ebook_error_message(error_code));
2800 return(NULL);
2801 }
2802 }
2803
2804
2805 ebook_bitmap_to_gif(bitmap_data, image_width,
2806 image_height, image_data, &image_size, fg, bg);
2807
2808
2809 fp = fopen(fname, "wb");
2810 if(fp == NULL){
2811 LOG(LOG_CRITICAL, "file open failed : %s", fname);
2812 }
2813 fwrite(image_data, image_size, 1, fp);
2814 fclose(fp);
2815
2816 return(NULL);
2817
2818 }
2819
ebook_output_wave(BOOK_INFO * binfo,gchar * filename,gint page,gint offset,gint size)2820 EB_Error_Code ebook_output_wave(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint size)
2821 {
2822 EB_Position pos;
2823 char binary_data[EB_SIZE_PAGE];
2824 EB_Error_Code error_code;
2825 EB_Position end_position;
2826 ssize_t read_length;
2827 FILE *fp;
2828
2829 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2830 return(error_code);
2831
2832 pos.page = page;
2833 pos.offset = offset;
2834
2835 end_position.page = pos.page
2836 + (size / EB_SIZE_PAGE);
2837 end_position.offset = pos.offset
2838 + (size % EB_SIZE_PAGE);
2839 if (EB_SIZE_PAGE <= end_position.offset) {
2840 end_position.offset -= EB_SIZE_PAGE;
2841 end_position.page++;
2842 }
2843
2844 /*
2845 * Read sound data.
2846 */
2847 error_code = eb_set_binary_wave(binfo->book,
2848 &pos, &end_position);
2849 if (error_code != EB_SUCCESS){
2850 LOG(LOG_CRITICAL, "Failed to set binary wave : %s",
2851 ebook_error_message(error_code));
2852 return(error_code);
2853 }
2854
2855 fp = fopen(filename, "wb");
2856 if(fp == NULL){
2857 LOG(LOG_CRITICAL, "Failed to open file : %s",
2858 filename);
2859 return(EB_ERR_BAD_FILE_NAME);
2860 }
2861
2862 for (;;) {
2863 error_code = eb_read_binary(binfo->book,
2864 EB_SIZE_PAGE,
2865 binary_data, &read_length);
2866 if (error_code != EB_SUCCESS || read_length == 0){
2867 fclose(fp);
2868 return(error_code);
2869 }
2870
2871 // If there are extra data (32 bytes) before fmt chunk,remove them.
2872 if((strncmp("fmt ", &binary_data[44], 4) == 0) &&
2873 (strncmp("fmt ", &binary_data[12], 4) != 0)){
2874 LOG(LOG_CRITICAL, "Warning: extra header found in WAVE data.");
2875 fwrite(binary_data, 12, 1, fp);
2876 fwrite(&binary_data[44], read_length - 44, 1, fp);
2877 } else {
2878 fwrite(binary_data, read_length, 1, fp);
2879 }
2880 }
2881
2882 /* not reached */
2883 return(EB_SUCCESS);
2884 }
2885
ebook_output_mpeg(BOOK_INFO * binfo,gchar * srcname,gchar * destname)2886 EB_Error_Code ebook_output_mpeg(BOOK_INFO *binfo, gchar *srcname, gchar *destname)
2887 {
2888 char binary_data[EB_SIZE_PAGE];
2889 guint argv[4];
2890 EB_Error_Code error_code;
2891 ssize_t read_length;
2892 FILE *fp;
2893
2894 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2895 return(error_code);
2896
2897 if((error_code = eb_decompose_movie_file_name(argv, srcname)) != EB_SUCCESS)
2898 return(error_code);
2899
2900 /*
2901 * Read sound data.
2902 */
2903 error_code = eb_set_binary_mpeg(binfo->book, argv);
2904 if (error_code != EB_SUCCESS){
2905 LOG(LOG_CRITICAL, "Failed to set binary mpeg : %s",
2906 ebook_error_message(error_code));
2907 return(error_code);
2908 }
2909
2910 fp = fopen(destname, "wb");
2911 if(fp == NULL){
2912 LOG(LOG_CRITICAL, "Failed to open file : %s", destname);
2913 return(EB_ERR_BAD_FILE_NAME);
2914 }
2915
2916 for (;;) {
2917 error_code = eb_read_binary(binfo->book,
2918 EB_SIZE_PAGE,
2919 binary_data, &read_length);
2920 if (error_code != EB_SUCCESS || read_length == 0){
2921 fclose(fp);
2922 return(error_code);
2923 }
2924 fwrite(binary_data, read_length, 1, fp);
2925 }
2926
2927 /* not reached */
2928 return(EB_SUCCESS);
2929 }
2930
ebook_output_color(BOOK_INFO * binfo,gchar * filename,gint page,gint offset)2931 EB_Error_Code ebook_output_color(BOOK_INFO *binfo, gchar *filename, gint page, gint offset)
2932 {
2933 EB_Position pos;
2934 char binary_data[EB_SIZE_PAGE];
2935 EB_Error_Code error_code;
2936 ssize_t read_length;
2937 FILE *fp;
2938
2939 pos.page = page;
2940 pos.offset = offset;
2941
2942 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2943 return(error_code);
2944
2945 error_code = eb_set_binary_color_graphic(binfo->book,
2946 &pos);
2947
2948 if (error_code != EB_SUCCESS){
2949 LOG(LOG_CRITICAL, "Failed to set binary color graphic : %s",
2950 ebook_error_message(error_code));
2951 return(error_code);
2952 }
2953
2954 fp = fopen(filename, "wb");
2955 if(fp == NULL){
2956 LOG(LOG_CRITICAL, "Failed to open file : %s",
2957 filename);
2958 return(EB_ERR_BAD_FILE_NAME);
2959 }
2960
2961 for (;;) {
2962 error_code = eb_read_binary(binfo->book, EB_SIZE_PAGE,
2963 binary_data, &read_length);
2964 if (error_code != EB_SUCCESS || read_length == 0){
2965 fclose(fp);
2966 return(error_code);
2967 }
2968 fwrite(binary_data, read_length, 1, fp);
2969 }
2970
2971 /* not reached */
2972 return(EB_SUCCESS);
2973 }
2974
2975
ebook_output_gray(BOOK_INFO * binfo,gchar * filename,gint page,gint offset,gint width,gint height)2976 EB_Error_Code ebook_output_gray(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint width, gint height)
2977 {
2978 EB_Position pos;
2979 char binary_data[EB_SIZE_PAGE];
2980 EB_Error_Code error_code;
2981 ssize_t read_length;
2982 FILE *fp;
2983
2984 pos.page = page;
2985 pos.offset = offset;
2986
2987 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
2988 return(error_code);
2989
2990 error_code = eb_set_binary_gray_graphic(binfo->book,
2991 &pos, width, height);
2992 if (error_code != EB_SUCCESS){
2993 LOG(LOG_CRITICAL, "Failed to set binary gray graphic : %s",
2994 ebook_error_message(error_code));
2995 return(error_code);
2996 }
2997
2998 fp = fopen(filename, "wb");
2999 if(fp == NULL){
3000 LOG(LOG_CRITICAL, "Failed to open file : %s",
3001 filename);
3002 return(EB_ERR_BAD_FILE_NAME);
3003 }
3004
3005 for (;;) {
3006 error_code = eb_read_binary(binfo->book, EB_SIZE_PAGE,
3007 binary_data, &read_length);
3008 if (error_code != EB_SUCCESS || read_length == 0){
3009 fclose(fp);
3010 return(error_code);
3011 }
3012 fwrite(binary_data, read_length, 1, fp);
3013 }
3014
3015 /* not reached */
3016 return(EB_SUCCESS);
3017 }
3018
ebook_output_mono(BOOK_INFO * binfo,gchar * filename,gint page,gint offset,gint width,gint height)3019 EB_Error_Code ebook_output_mono(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint width, gint height)
3020 {
3021 FILE *fp;
3022 EB_Error_Code error_code;
3023 EB_Position pos;
3024 char *binary_data;
3025 ssize_t read_length;
3026 gint data_size;
3027 gchar *bmp_data;
3028 gint bmp_length;
3029
3030 #ifdef COLOR_HACK
3031
3032 guchar fg[4];
3033 guchar bg[4];
3034 GdkColor color;
3035
3036 color = dict_area->area->style->fg[GTK_STATE_NORMAL];
3037 fg[0] = (guchar)color.red;
3038 fg[1] = (guchar)color.green;
3039 fg[2] = (guchar)color.blue;
3040 fg[3] = 0x0;
3041
3042 color = dict_area->area->style->bg[GTK_STATE_NORMAL];
3043 bg[0] = (guchar)color.red;
3044 bg[1] = (guchar)color.green;
3045 bg[2] = (guchar)color.blue;
3046 bg[3] = 0x0;
3047
3048 #endif
3049
3050 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
3051 return(error_code);
3052
3053 fp = fopen(filename, "wb");
3054 if(fp == NULL){
3055 LOG(LOG_CRITICAL, "Failed to open file : %s",
3056 filename);
3057 return(EB_ERR_BAD_FILE_NAME);
3058 }
3059
3060 pos.page = page;
3061 pos.offset = offset;
3062
3063 eb_seek_text(binfo->book, &pos);
3064
3065 error_code = eb_set_binary_mono_graphic(binfo->book,
3066 &pos, width, height);
3067
3068
3069 // Workaround for dictionaries such as Super Tougou Jisho 2000,
3070 // whose graphics data is in Honmon2.
3071 // Fixed in eb-3.3.
3072 if (error_code != EB_SUCCESS){
3073
3074 if((width % 8) != 0)
3075 width = (width / 8)*8 + 8;
3076
3077 data_size = width * height / 8;
3078
3079 binary_data = malloc(data_size);
3080 bmp_data = malloc(data_size*10);
3081
3082
3083 pos.page = page;
3084 pos.offset = offset;
3085
3086 eb_seek_text(binfo->book, &pos);
3087 error_code = eb_read_rawtext(binfo->book,
3088 data_size,
3089 binary_data,
3090 &read_length);
3091 if (error_code != EB_SUCCESS || read_length == 0){
3092 return(error_code);
3093 }
3094
3095 eb_bitmap_to_bmp(binary_data,
3096 width,
3097 height,
3098 bmp_data,
3099 &bmp_length);
3100
3101 fwrite(bmp_data, bmp_length, 1, fp);
3102
3103 #ifdef COLOR_HACK
3104 fseek(fp, 54, SEEK_SET);
3105 fwrite(bg, 4, 1, fp);
3106 fseek(fp, 58, SEEK_SET);
3107 fwrite(fg, 4, 1, fp);
3108 #endif
3109 fclose(fp);
3110 free(binary_data);
3111 free(bmp_data);
3112 return(EB_SUCCESS);
3113 }
3114
3115
3116 if (error_code != EB_SUCCESS){
3117 LOG(LOG_CRITICAL, "Failed to set binary mono : %s",
3118 ebook_error_message(error_code));
3119 return(error_code);
3120 }
3121
3122 for (;;) {
3123 char binary_data[EB_SIZE_PAGE];
3124
3125 error_code = eb_read_binary(binfo->book,
3126 EB_SIZE_PAGE,
3127 binary_data, &read_length);
3128 if (error_code != EB_SUCCESS || read_length == 0){
3129 fclose(fp);
3130 return(error_code);
3131 }
3132 #ifdef COLOR_HACK
3133 memcpy(&binary_data[54], bg, 4);
3134 memcpy(&binary_data[58], fg, 4);
3135 #endif
3136 fwrite(binary_data, read_length, 1, fp);
3137 }
3138
3139 /* not reached */
3140 fclose(fp);
3141 return(EB_SUCCESS);
3142 }
3143
ebook_get_rawtext(BOOK_INFO * binfo,gint page,gint offset)3144 gchar *ebook_get_rawtext(BOOK_INFO *binfo, gint page, gint offset)
3145 {
3146 EB_Position pos;
3147 char *binary_data;
3148 EB_Error_Code error_code;
3149 ssize_t read_length;
3150
3151 binary_data = malloc(EB_SIZE_PAGE);
3152
3153 if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
3154 return(NULL);
3155
3156 pos.page = page;
3157 pos.offset = offset;
3158
3159 eb_seek_text(binfo->book, &pos);
3160 error_code = eb_read_rawtext(binfo->book,
3161 EB_SIZE_PAGE,
3162 binary_data,
3163 &read_length);
3164 if (error_code != EB_SUCCESS || read_length == 0){
3165 return(NULL);
3166 }
3167
3168 return(binary_data);
3169 }
3170
ebook_set_subbook(BOOK_INFO * binfo)3171 EB_Error_Code ebook_set_subbook(BOOK_INFO *binfo)
3172 {
3173
3174 EB_Error_Code error_code;
3175
3176 error_code = eb_set_subbook(binfo->book, binfo->subbook_no);
3177 if (error_code != EB_SUCCESS){
3178 LOG(LOG_CRITICAL, "Failed to set subbook %s, %d : %s",
3179 binfo->book_path, binfo->subbook_no,
3180 ebook_error_message(error_code));
3181 return(error_code);
3182 }
3183
3184
3185 if(binfo->appendix != NULL){
3186 error_code = eb_set_appendix_subbook(binfo->appendix,
3187 binfo->appendix_subbook_no);
3188 if (error_code != EB_SUCCESS){
3189 LOG(LOG_CRITICAL, "Failed to set appendix subbook : %s",
3190 ebook_error_message(error_code));
3191 return(error_code);
3192 }
3193 }
3194 return(EB_SUCCESS);
3195
3196 }
3197
3198