bool ReaderViewNative::openRecentBook() { CRLog::debug("ReaderViewNative::openRecentBook()"); int index = 0; if ( _docview->isDocumentOpened() ) { CRLog::debug("ReaderViewNative::openRecentBook() : saving previous document state"); _docview->swapToCache(); _docview->getDocument()->updateMap(); _docview->savePosition(); closeBook(); index = 1; } LVPtrVector<CRFileHistRecord> & files = _docview->getHistory()->getRecords(); CRLog::info("ReaderViewNative::openRecentBook() : %d files found in history, startIndex=%d", files.length(), index); if ( index < files.length() ) { CRFileHistRecord * file = files.get( index ); lString16 fn = file->getFilePathName(); CRLog::info("ReaderViewNative::openRecentBook() : checking file %s", LCSTR(fn)); // TODO: check error if ( LVFileExists(fn) ) { return loadDocument( fn ); } else { CRLog::error("file %s doesn't exist", LCSTR(fn)); return false; } //_docview->swapToCache(); } else { CRLog::info("ReaderViewNative::openRecentBook() : no recent book found in history"); } return false; }
bool ReaderViewNative::loadDocument( lString16 filename ) { CRLog::info("Loading document %s", LCSTR(filename)); bool res = _docview->LoadDocument(filename.c_str()); CRLog::info("Document %s is loaded %s", LCSTR(filename), (res?"successfully":"with error")); return res; }
jbyteArray scanBookCoverInternal (JNIEnv * _env, jclass _class, jstring _path) { CRJNIEnv env(_env); lString16 path = env.fromJavaString(_path); CRLog::debug("scanBookCoverInternal(%s) called", LCSTR(path)); lString16 arcname, item; LVStreamRef res; jbyteArray array = NULL; LVContainerRef arc; if (!LVSplitArcName(path, arcname, item)) { // not in archive LVStreamRef stream = LVOpenFileStream(path.c_str(), LVOM_READ); if (!stream.isNull()) { arc = LVOpenArchieve(stream); if (!arc.isNull()) { // ZIP-based format if (DetectEpubFormat(stream)) { // EPUB // extract coverpage from epub res = GetEpubCoverpage(arc); } } else { res = GetFB2Coverpage(stream); if (res.isNull()) { doc_format_t fmt; if (DetectPDBFormat(stream, fmt)) { res = GetPDBCoverpage(stream); } } } } } else { CRLog::debug("scanBookCoverInternal() : is archive, item=%s, arc=%s", LCSTR(item), LCSTR(arcname)); LVStreamRef arcstream = LVOpenFileStream(arcname.c_str(), LVOM_READ); if (!arcstream.isNull()) { arc = LVOpenArchieve(arcstream); if (!arc.isNull()) { LVStreamRef stream = arc->OpenStream(item.c_str(), LVOM_READ); if (!stream.isNull()) { CRLog::debug("scanBookCoverInternal() : archive stream opened ok, parsing"); res = GetFB2Coverpage(stream); if (res.isNull()) { doc_format_t fmt; if (DetectPDBFormat(stream, fmt)) { res = GetPDBCoverpage(stream); } } } } } } if (!res.isNull()) array = env.streamToJByteArray(res); if (array != NULL) CRLog::debug("scanBookCoverInternal() : returned cover page array"); else CRLog::debug("scanBookCoverInternal() : cover page data not found"); return array; }
bool HyphDictionaryList::open(lString16 hyphDirectory, bool clear) { CRLog::info("HyphDictionaryList::open(%s)", LCSTR(hyphDirectory) ); if (clear) { _list.clear(); addDefault(); } if ( hyphDirectory.empty() ) return true; //LVAppendPathDelimiter( hyphDirectory ); LVContainerRef container; LVStreamRef stream; if ( (hyphDirectory.endsWith("/") || hyphDirectory.endsWith("\\")) && LVDirectoryExists(hyphDirectory) ) { container = LVOpenDirectory( hyphDirectory.c_str(), L"*.*" ); } else if ( LVFileExists(hyphDirectory) ) { stream = LVOpenFileStream( hyphDirectory.c_str(), LVOM_READ ); if ( !stream.isNull() ) container = LVOpenArchieve( stream ); } if ( !container.isNull() ) { int len = container->GetObjectCount(); int count = 0; CRLog::info("%d items found in hyph directory", len); for ( int i=0; i<len; i++ ) { const LVContainerItemInfo * item = container->GetObjectInfo( i ); lString16 name = item->GetName(); lString16 suffix; HyphDictType t = HDT_NONE; if ( name.endsWith(".pdb") ) { suffix = "_hyphen_(Alan).pdb"; t = HDT_DICT_ALAN; } else if ( name.endsWith(".pattern") ) { suffix = ".pattern"; t = HDT_DICT_TEX; } else continue; lString16 filename = hyphDirectory + name; lString16 id = name; lString16 title = name; if ( title.endsWith( suffix ) ) title.erase( title.length() - suffix.length(), suffix.length() ); _list.add( new HyphDictionary( t, title, id, filename ) ); count++; } CRLog::info("%d dictionaries added to list", _list.length()); return true; } else { CRLog::info("no hyphenation dictionary items found in hyph directory %s", LCSTR(hyphDirectory)); } return false; }
void addPattern(lString16 pattern) { if (pattern[0] == '.') pattern[0] = ' '; if (pattern[pattern.length()-1] == '.') pattern[pattern.length()-1] = ' '; fprintf(out, " <pattern>%s</pattern>\n", LCSTR(pattern)); }
void processLine(lString16 & line) { if (line.lastChar()=='\r' || line.lastChar()=='\n') line.erase(line.length()-1, 1); if (state == 0) { // if (line.startsWith(lString16("%"))) { fprintf(out, "%s\n", LCSTR(line)); return; } if (line.startsWith(lString16("\\patterns{"))) { start(); return; } } else { lString16 word; for (int i=0; i<=line.length(); i++) { lChar16 ch = (i<line.length()) ? line[i] : 0; if (ch == '}') break; if (ch==' ' || ch=='\t' || ch=='%' || ch==0) { if (!word.empty()) { addPattern(word); word.clear(); } if (ch!=' ' && ch!='\t') break; } else { word.append(1, ch); } } } }
bool HyphDictionaryList::activate( lString16 id ) { CRLog::trace("HyphDictionaryList::activate(%s)", LCSTR(id)); HyphDictionary * p = find(id); if ( p ) return p->activate(); else return false; }
CRPropRef CRJNIEnv::fromJavaProperties( jobject jprops ) { CRPropRef props = LVCreatePropsContainer(); CRObjectAccessor jp(env, jprops); CRMethodAccessor p_getProperty(jp, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); jobject en = CRMethodAccessor( jp, "propertyNames", "()Ljava/util/Enumeration;").callObj(); CRObjectAccessor jen(env, en); CRMethodAccessor jen_hasMoreElements(jen, "hasMoreElements", "()Z"); CRMethodAccessor jen_nextElement(jen, "nextElement", "()Ljava/lang/Object;"); while ( jen_hasMoreElements.callBool() ) { jstring key = (jstring)jen_nextElement.callObj(); jstring value = (jstring)p_getProperty.callObj(key); props->setString(LCSTR(fromJavaString(key)),LCSTR(fromJavaString(value))); env->DeleteLocalRef(key); env->DeleteLocalRef(value); } return props; }
bool hasUnsupportedEncryption() { for (int i=0; i<_list.length(); i++) { lString16 method = _list[i]->_method; if (method != L"http://ns.adobe.com/pdf/enc#RC") { CRLog::debug("unsupported encryption method: %s", LCSTR(method)); return true; } } return false; }
bool ReaderViewNative::saveHistory( lString16 filename ) { if ( !filename.empty() ) historyFileName = filename; if ( historyFileName.empty() ) return false; if ( _docview->isDocumentOpened() ) { CRLog::debug("ReaderViewNative::saveHistory() : saving position"); _docview->savePosition(); } CRLog::info("Trying to save history to file %s", LCSTR(historyFileName)); CRFileHist * hist = _docview->getHistory(); LVStreamRef stream = LVOpenFileStream(historyFileName.c_str(), LVOM_WRITE); if ( stream.isNull() ) { CRLog::error("Cannot create file %s for writing", LCSTR(historyFileName)); return false; } if ( _docview->isDocumentOpened() ) _docview->savePosition(); return hist->saveToStream( stream.get() ); }
bool ReaderViewNative::loadHistory( lString16 filename ) { CRFileHist * hist = _docview->getHistory(); if ( !filename.empty() ) historyFileName = filename; historyFileName = filename; if ( historyFileName.empty() ) { CRLog::error("No history file name specified"); return false; } CRLog::info("Trying to load history from file %s", LCSTR(historyFileName)); LVStreamRef stream = LVOpenFileStream(historyFileName.c_str(), LVOM_READ); if ( stream.isNull() ) { CRLog::error("Cannot open file %s", LCSTR(historyFileName)); return false; } bool res = hist->loadFromStream( stream ); if ( res ) CRLog::info("%d items found", hist->getRecords().length()); else CRLog::error("Cannot read history file content"); return res; }
/* * Class: org_coolreader_crengine_Engine * Method: scanBookPropertiesInternal * Signature: (Lorg/coolreader/crengine/FileInfo;)Z */ JNIEXPORT jboolean JNICALL Java_org_coolreader_crengine_Engine_scanBookPropertiesInternal (JNIEnv * _env, jclass _engine, jobject _fileInfo) { CRJNIEnv env(_env); jclass objclass = env->GetObjectClass(_fileInfo); jfieldID fid = env->GetFieldID(objclass, "pathname", "Ljava/lang/String;"); lString16 filename = env.fromJavaString( (jstring)env->GetObjectField(_fileInfo, fid) ); fid = env->GetFieldID(objclass, "arcname", "Ljava/lang/String;"); lString16 arcname = env.fromJavaString( (jstring)env->GetObjectField(_fileInfo, fid) ); if ( filename.empty() ) return JNI_FALSE; if ( !arcname.empty() ) filename = arcname + "@/" + filename; BookProperties props; CRLog::debug("Looking for properties of file %s", LCSTR(filename)); bool res = GetBookProperties(LCSTR(filename), &props); if ( !res ) return JNI_FALSE; #define SET_STR_FLD(fldname,src) \ { \ jfieldID fid = env->GetFieldID(objclass, fldname, "Ljava/lang/String;"); \ env->SetObjectField(_fileInfo,fid,env.toJavaString(src)); \ } #define SET_INT_FLD(fldname,src) \ { \ jfieldID fid = env->GetFieldID(objclass, fldname, "I"); \ env->SetIntField(_fileInfo,fid,src); \ } SET_STR_FLD("title",props.title); SET_STR_FLD("authors",props.author); SET_STR_FLD("series",props.series); SET_INT_FLD("seriesNumber",props.seriesNumber); SET_STR_FLD("language",props.language); return JNI_TRUE; }
/* * vSubstring2Diagram - put a sub string into a diagram */ void vSubstring2Diagram(diagram_type *pDiag, char *szString, size_t tStringLength, long lStringWidth, UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, USHORT usFontSize, USHORT usMaxFontSize) { lString16 s( szString, tStringLength); #ifdef _LINUX TRACE("antiword::vSubstring2Diagram(%s)", LCSTR(s)); #else TRACE("antiword::vSubstring2Diagram()"); #endif s.trimDoubleSpaces(!last_space_char, true, false); last_space_char = (s.lastChar()==' '); // vSubstringXML(pDiag, szString, tStringLength, lStringWidth, // usFontstyle); if ( !inside_p && !inside_li ) { writer->OnTagOpenNoAttr(NULL, L"p"); inside_p = true; } bool styleBold = bIsBold(usFontstyle); bool styleItalic = bIsItalic(usFontstyle); lString16 style; style << fontSizeToPercent( L"font-size: ", usFontSize, 30, 300 ); if ( !style.empty() ) { writer->OnTagOpen(NULL, L"span"); writer->OnAttribute(NULL, L"style", style.c_str()); writer->OnTagBody(); } if ( styleBold ) writer->OnTagOpenNoAttr(NULL, L"b"); if ( styleItalic ) writer->OnTagOpenNoAttr(NULL, L"i"); //================= writer->OnText(s.c_str(), s.length(), 0); //================= if ( styleItalic ) writer->OnTagClose(NULL, L"i"); if ( styleBold ) writer->OnTagClose(NULL, L"b"); if ( !style.empty() ) writer->OnTagClose(NULL, L"span"); pDiag->lXleft += lStringWidth; } /* end of vSubstring2Diagram */
void MainWindow::onPropsChange( PropsRef props ) { for ( int i=0; i<props->count(); i++ ) { QString name = props->name( i ); QString value = props->value( i ); int v = (value != "0"); CRLog::debug("MainWindow::onPropsChange [%d] '%s'=%s ", i, props->name(i), props->value(i).toUtf8().data() ); if ( name == PROP_WINDOW_FULLSCREEN ) { bool state = windowState().testFlag(Qt::WindowFullScreen); bool vv = v ? true : false; if ( state != vv ) setWindowState( windowState() ^ Qt::WindowFullScreen ); } if ( name == PROP_WINDOW_SHOW_MENU ) { ui->menuBar->setVisible( v ); } if ( name == PROP_WINDOW_SHOW_SCROLLBAR ) { ui->scroll->setVisible( v ); } if ( name == PROP_BACKGROUND_IMAGE ) { lString16 fn = qt2cr(value); LVImageSourceRef img; if ( !fn.empty() && fn[0]!='[' ) { CRLog::debug("Background image file: %s", LCSTR(fn)); LVStreamRef stream = LVOpenFileStream(fn.c_str(), LVOM_READ); if ( !stream.isNull() ) { img = LVCreateStreamImageSource(stream); } } fn.lowercase(); bool tiled = ( fn.pos(lString16("\\textures\\"))>=0 || fn.pos(lString16("/textures/"))>=0); ui->view->getDocView()->setBackgroundImage(img, tiled); } if ( name == PROP_WINDOW_TOOLBAR_SIZE ) { ui->mainToolBar->setVisible( v ); } if ( name == PROP_WINDOW_SHOW_STATUSBAR ) { ui->statusBar->setVisible( v ); } if ( name == PROP_WINDOW_STYLE ) { QApplication::setStyle( value ); } } }
static void dumpZip( LVContainerRef arc ) { lString16 arcName = LVExtractFilenameWithoutExtension( arc->GetName() ); if ( arcName.empty() ) arcName = L"unziparc"; lString16 outDir = lString16("/tmp/") + arcName; LVCreateDirectory(outDir); for ( int i=0; i<arc->GetObjectCount(); i++ ) { const LVContainerItemInfo * info = arc->GetObjectInfo(i); if ( !info->IsContainer() ) { lString16 outFileName = outDir + L"/" + info->GetName(); LVCreateDirectory(LVExtractPath(outFileName)); LVStreamRef in = arc->OpenStream(info->GetName(), LVOM_READ); LVStreamRef out = LVOpenFileStream(outFileName.c_str(), LVOM_WRITE); if ( !in.isNull() && !out.isNull() ) { CRLog::trace("Writing %s", LCSTR(outFileName)); LVPumpStream(out.get(), in.get()); } } } }
/* * Class: org_coolreader_crengine_Engine * Method: scanBookCoverInternal * Signature: (Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_org_coolreader_crengine_Engine_scanBookCoverInternal (JNIEnv * _env, jobject _engine, jstring _path) { CRJNIEnv env(_env); lString16 path = env.fromJavaString(_path); CRLog::debug("scanBookCoverInternal(%s) called", LCSTR(path)); lString16 arcname, item; LVStreamRef res; jbyteArray array = NULL; LVContainerRef arc; if (!LVSplitArcName(path, arcname, item)) { // not in archive LVStreamRef stream = LVOpenFileStream(path.c_str(), LVOM_READ); if (!stream.isNull()) { arc = LVOpenArchieve(stream); if (!arc.isNull()) { // ZIP-based format if (DetectEpubFormat(stream)) { // EPUB // extract coverpage from epub res = GetEpubCoverpage(arc); } } else { doc_format_t fmt; if (DetectPDBFormat(stream, fmt)) { res = GetPDBCoverpage(stream); } } } } if (!res.isNull()) array = env.streamToJByteArray(res); if (array != NULL) CRLog::debug("scanBookCoverInternal() : returned cover page array"); else CRLog::debug("scanBookCoverInternal() : cover page data not found"); return array; }
bool match( const lChar16 * s, char * mask ) { TexPattern * p = this; bool found = false; while ( p ) { bool res = true; for ( int i=2; p->word[i]; i++ ) if ( p->word[i]!=s[i] ) { res = false; break; } if ( res ) { if ( p->word[0]==s[0] && (p->word[1]==0 || p->word[1]==s[1]) ) { #if DUMP_PATTERNS==1 CRLog::debug("Pattern matched: %s %s on %s %s", LCSTR(lString16(p->word)), p->attr, LCSTR(lString16(s)), mask); #endif p->apply(mask); found = true; } } p = p->next; } return found; }
static bool GetBookProperties(const char *name, BookProperties * pBookProps) { CRLog::trace("GetBookProperties( %s )", name); // check archieve lString16 arcPathName; lString16 arcItemPathName; bool isArchiveFile = LVSplitArcName( lString16(name), arcPathName, arcItemPathName ); // open stream LVStreamRef stream = LVOpenFileStream( (isArchiveFile ? arcPathName : Utf8ToUnicode(lString8(name))).c_str() , LVOM_READ); if (!stream) { CRLog::error("cannot open file %s", name); return false; } if ( DetectEpubFormat( stream ) ) { CRLog::trace("GetBookProperties() : epub format detected"); return GetEPUBBookProperties( name, stream, pBookProps ); } time_t t = (time_t)time(0); if ( isArchiveFile ) { int arcsize = (int)stream->GetSize(); LVContainerRef container = LVOpenArchieve(stream); if ( container.isNull() ) { CRLog::error( "Cannot read archive contents from %s", LCSTR(arcPathName) ); return false; } stream = container->OpenStream(arcItemPathName.c_str(), LVOM_READ); if ( stream.isNull() ) { CRLog::error( "Cannot open archive file item stream %s", LCSTR(lString16(name)) ); return false; } } struct stat fs; if ( !stat( name, &fs ) ) { t = fs.st_mtime; } // read document #if COMPACT_DOM==1 ldomDocument doc(stream, 0); #else ldomDocument doc; #endif ldomDocumentWriter writer(&doc, true); doc.setNodeTypes( fb2_elem_table ); doc.setAttributeTypes( fb2_attr_table ); doc.setNameSpaceTypes( fb2_ns_table ); LVXMLParser parser( stream, &writer ); CRLog::trace( "checking format..." ); if ( !parser.CheckFormat() ) { return false; } CRLog::trace( "parsing..." ); if ( !parser.Parse() ) { return false; } CRLog::trace( "parsed" ); #if 0 char ofname[512]; sprintf(ofname, "%s.xml", name); CRLog::trace(" writing to file %s", ofname); LVStreamRef out = LVOpenFileStream(ofname, LVOM_WRITE); doc.saveToStream(out, "utf16"); #endif lString16 authors = extractDocAuthors( &doc, lString16("|"), false ); lString16 title = extractDocTitle( &doc ); lString16 language = extractDocLanguage( &doc ).lowercase(); lString16 series = extractDocSeries( &doc, &pBookProps->seriesNumber ); #if SERIES_IN_AUTHORS==1 if ( !series.empty() ) authors << " " << series; #endif pBookProps->title = title; pBookProps->author = authors; pBookProps->series = series; pBookProps->filesize = (long)stream->GetSize(); pBookProps->filename = lString16(name); pBookProps->filedate = getDateTimeString( t ); pBookProps->language = language; return true; }
bool ImportEpubDocument( LVStreamRef stream, ldomDocument * m_doc, LVDocViewCallback * progressCallback, CacheLoadingCallback * formatCallback ) { LVContainerRef arc = LVOpenArchieve( stream ); if ( arc.isNull() ) return false; // not a ZIP archive // check root media type lString16 rootfilePath = EpubGetRootFilePath(arc); if ( rootfilePath.empty() ) return false; EncryptedDataContainer * decryptor = new EncryptedDataContainer(arc); if (decryptor->open()) { CRLog::debug("EPUB: encrypted items detected"); } LVContainerRef m_arc = LVContainerRef(decryptor); if (decryptor->hasUnsupportedEncryption()) { // DRM!!! createEncryptedEpubWarningDocument(m_doc); return true; } m_doc->setContainer(m_arc); // read content.opf EpubItems epubItems; //EpubItem * epubToc = NULL; //TODO LVArray<EpubItem*> spineItems; lString16 codeBase; //lString16 css; // { codeBase=LVExtractPath(rootfilePath, false); CRLog::trace("codeBase=%s", LCSTR(codeBase)); } LVStreamRef content_stream = m_arc->OpenStream(rootfilePath.c_str(), LVOM_READ); if ( content_stream.isNull() ) return false; lString16 ncxHref; lString16 coverId; LVEmbeddedFontList fontList; EmbeddedFontStyleParser styleParser(fontList); // reading content stream { ldomDocument * doc = LVParseXMLStream( content_stream ); if ( !doc ) return false; CRPropRef m_doc_props = m_doc->getProps(); lString16 author = doc->textFromXPath( lString16(L"package/metadata/creator")); lString16 title = doc->textFromXPath( lString16(L"package/metadata/title")); m_doc_props->setString(DOC_PROP_TITLE, title); m_doc_props->setString(DOC_PROP_AUTHORS, author ); for ( int i=1; i<50; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/metadata/identifier[") + lString16::itoa(i) + L"]" ); if (!item) break; lString16 key = item->getText(); if (decryptor->setManglingKey(key)) { CRLog::debug("Using font mangling key %s", LCSTR(key)); break; } } CRLog::info("Author: %s Title: %s", LCSTR(author), LCSTR(title)); for ( int i=1; i<20; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/metadata/meta[") + lString16::itoa(i) + L"]" ); if ( !item ) break; lString16 name = item->getAttributeValue(L"name"); lString16 content = item->getAttributeValue(L"content"); if ( name == L"cover" ) coverId = content; else if ( name==L"calibre:series" ) m_doc_props->setString(DOC_PROP_SERIES_NAME, content ); else if ( name==L"calibre:series_index" ) m_doc_props->setInt(DOC_PROP_SERIES_NUMBER, content.atoi() ); } // items for ( int i=1; i<50000; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/manifest/item[") + lString16::itoa(i) + L"]" ); if ( !item ) break; lString16 href = item->getAttributeValue(L"href"); lString16 mediaType = item->getAttributeValue(L"media-type"); lString16 id = item->getAttributeValue(L"id"); if ( !href.empty() && !id.empty() ) { if ( id==coverId ) { // coverpage file lString16 coverFileName = codeBase + href; CRLog::info("EPUB coverpage file: %s", LCSTR(coverFileName)); LVStreamRef stream = m_arc->OpenStream(coverFileName.c_str(), LVOM_READ); if ( !stream.isNull() ) { LVImageSourceRef img = LVCreateStreamImageSource(stream); if ( !img.isNull() ) { CRLog::info("EPUB coverpage image is correct: %d x %d", img->GetWidth(), img->GetHeight() ); m_doc_props->setString(DOC_PROP_COVER_FILE, coverFileName); } } } EpubItem * epubItem = new EpubItem; epubItem->href = href; epubItem->id = id; epubItem->mediaType = mediaType; epubItems.add( epubItem ); // // register embedded document fonts // if (mediaType == L"application/vnd.ms-opentype" // || mediaType == L"application/x-font-otf" // || mediaType == L"application/x-font-ttf") { // TODO: more media types? // // TODO: // fontList.add(codeBase + href); // } } if ( mediaType==L"text/css" ) { lString16 name = LVCombinePaths(codeBase, href); LVStreamRef cssStream = m_arc->OpenStream(name.c_str(), LVOM_READ); if (!cssStream.isNull()) { lString8 cssFile = UnicodeToUtf8(LVReadTextFile(cssStream)); lString16 base = name; LVExtractLastPathElement(base); CRLog::trace("style: %s", cssFile.c_str()); styleParser.parse(base, cssFile); } } } // spine == itemrefs if ( epubItems.length()>0 ) { ldomNode * spine = doc->nodeFromXPath( lString16(L"package/spine") ); if ( spine ) { EpubItem * ncx = epubItems.findById( spine->getAttributeValue(L"toc") ); //TODO //EpubItem * ncx = epubItems.findById(lString16("ncx")); if ( ncx!=NULL ) ncxHref = codeBase + ncx->href; for ( int i=1; i<50000; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/spine/itemref[") + lString16::itoa(i) + L"]" ); if ( !item ) break; EpubItem * epubItem = epubItems.findById( item->getAttributeValue(L"idref") ); if ( epubItem ) { // TODO: add to document spineItems.add( epubItem ); } } } } delete doc; } if ( spineItems.length()==0 ) return false; #if BUILD_LITE!=1 if ( m_doc->openFromCache(formatCallback) ) { if ( progressCallback ) { progressCallback->OnLoadFileEnd( ); } return true; } #endif lUInt32 saveFlags = m_doc->getDocFlags(); m_doc->setDocFlags( saveFlags ); m_doc->setContainer( m_arc ); ldomDocumentWriter writer(m_doc); #if 0 m_doc->setNodeTypes( fb2_elem_table ); m_doc->setAttributeTypes( fb2_attr_table ); m_doc->setNameSpaceTypes( fb2_ns_table ); #endif //m_doc->setCodeBase( codeBase ); ldomDocumentFragmentWriter appender(&writer, lString16(L"body"), lString16(L"DocFragment"), lString16::empty_str ); writer.OnStart(NULL); writer.OnTagOpenNoAttr(L"", L"body"); int fragmentCount = 0; for ( int i=0; i<spineItems.length(); i++ ) { if ( spineItems[i]->mediaType==L"application/xhtml+xml" ) { lString16 name = codeBase + spineItems[i]->href; appender.addPathSubstitution( name, lString16(L"_doc_fragment_") + lString16::itoa(i) ); } } for ( int i=0; i<spineItems.length(); i++ ) { if ( spineItems[i]->mediaType==L"application/xhtml+xml" ) { lString16 name = codeBase + spineItems[i]->href; { CRLog::debug("Checking fragment: %s", LCSTR(name)); LVStreamRef stream = m_arc->OpenStream(name.c_str(), LVOM_READ); if ( !stream.isNull() ) { appender.setCodeBase( name ); lString16 base = name; LVExtractLastPathElement(base); //CRLog::trace("base: %s", LCSTR(base)); //LVXMLParser LVHTMLParser parser(stream, &appender); if ( parser.CheckFormat() && parser.Parse() ) { // valid fragmentCount++; lString8 headCss = appender.getHeadStyleText(); //CRLog::trace("style: %s", headCss.c_str()); styleParser.parse(base, headCss); } else { CRLog::error("Document type is not XML/XHTML for fragment %s", LCSTR(name)); } } } } } ldomDocument * ncxdoc = NULL; if ( !ncxHref.empty() ) { LVStreamRef stream = m_arc->OpenStream(ncxHref.c_str(), LVOM_READ); lString16 codeBase = LVExtractPath( ncxHref ); if ( codeBase.length()>0 && codeBase.lastChar()!='/' ) codeBase.append(1, L'/'); appender.setCodeBase(codeBase); if ( !stream.isNull() ) { ldomDocument * ncxdoc = LVParseXMLStream( stream ); if ( ncxdoc!=NULL ) { ldomNode * navMap = ncxdoc->nodeFromXPath( lString16(L"ncx/navMap")); if ( navMap!=NULL ) ReadEpubToc( m_doc, navMap, m_doc->getToc(), appender ); delete ncxdoc; } } } writer.OnTagClose(L"", L"body"); writer.OnStop(); CRLog::debug("EPUB: %d documents merged", fragmentCount); if (!fontList.empty()) { // set document font list, and register fonts m_doc->getEmbeddedFontList().set(fontList); m_doc->registerEmbeddedFonts(); m_doc->forceReinitStyles(); } if ( fragmentCount==0 ) return false; #if 0 // set stylesheet //m_doc->getStyleSheet()->clear(); m_doc->setStyleSheet( NULL, true ); //m_doc->getStyleSheet()->parse(m_stylesheet.c_str()); if ( !css.empty() && m_doc->getDocFlag(DOC_FLAG_ENABLE_INTERNAL_STYLES) ) { m_doc->setStyleSheet( "p.p { text-align: justify }\n" "svg { text-align: center }\n" "i { display: inline; font-style: italic }\n" "b { display: inline; font-weight: bold }\n" "abbr { display: inline }\n" "acronym { display: inline }\n" "address { display: inline }\n" "p.title-p { hyphenate: none }\n" //abbr, acronym, address, blockquote, br, cite, code, dfn, div, em, h1, h2, h3, h4, h5, h6, kbd, p, pre, q, samp, span, strong, var , false); m_doc->setStyleSheet( UnicodeToUtf8(css).c_str(), false ); //m_doc->getStyleSheet()->parse(UnicodeToUtf8(css).c_str()); } else { //m_doc->getStyleSheet()->parse(m_stylesheet.c_str()); //m_doc->setStyleSheet( m_stylesheet.c_str(), false ); } #endif #if 0 LVStreamRef out = LVOpenFileStream( L"c:\\doc.xml" , LVOM_WRITE ); if ( !out.isNull() ) m_doc->saveToStream( out, "utf-8" ); #endif // DONE! if ( progressCallback ) { progressCallback->OnLoadFileEnd( ); m_doc->compact(); m_doc->dumpStatistics(); } return true; }
LVStreamRef GetEpubCoverpage(LVContainerRef arc) { // check root media type lString16 rootfilePath = EpubGetRootFilePath(arc); if ( rootfilePath.empty() ) return LVStreamRef(); EncryptedDataContainer * decryptor = new EncryptedDataContainer(arc); if (decryptor->open()) { CRLog::debug("EPUB: encrypted items detected"); } LVContainerRef m_arc = LVContainerRef(decryptor); lString16 codeBase = LVExtractPath(rootfilePath, false); CRLog::trace("codeBase=%s", LCSTR(codeBase)); LVStreamRef content_stream = m_arc->OpenStream(rootfilePath.c_str(), LVOM_READ); if ( content_stream.isNull() ) return LVStreamRef(); LVStreamRef coverPageImageStream; // reading content stream { lString16 coverId; ldomDocument * doc = LVParseXMLStream( content_stream ); if ( !doc ) return LVStreamRef(); for ( int i=1; i<20; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/metadata/meta[") + lString16::itoa(i) + L"]" ); if ( !item ) break; lString16 name = item->getAttributeValue(L"name"); lString16 content = item->getAttributeValue(L"content"); if (name == L"cover") coverId = content; } // items for ( int i=1; i<50000; i++ ) { ldomNode * item = doc->nodeFromXPath( lString16(L"package/manifest/item[") + lString16::itoa(i) + L"]" ); if ( !item ) break; lString16 href = item->getAttributeValue(L"href"); lString16 id = item->getAttributeValue(L"id"); if ( !href.empty() && !id.empty() ) { if (id == coverId) { // coverpage file lString16 coverFileName = codeBase + href; CRLog::info("EPUB coverpage file: %s", LCSTR(coverFileName)); coverPageImageStream = m_arc->OpenStream(coverFileName.c_str(), LVOM_READ); } } } delete doc; } return coverPageImageStream; }
bool TexHyph::load( LVStreamRef stream ) { int w = isCorrectHyphFile(stream.get()); int patternCount = 0; if (w) { _hash = stream->crc32(); int i; lvsize_t dw; lvByteOrderConv cnv; int hyph_count = w; thyph hyph; lvpos_t p = 78 + (hyph_count * 8 + 2); stream->SetPos(p); if ( stream->SetPos(p)!=p ) return false; lChar16 charMap[256]; unsigned char buf[0x10000]; memset( charMap, 0, sizeof( charMap ) ); // make char map table for (i=0; i<hyph_count; i++) { if ( stream->Read( &hyph, 522, &dw )!=LVERR_OK || dw!=522 ) return false; cnv.msf( &hyph.len ); //rword(_main_hyph[i].len); lvpos_t newPos; if ( stream->Seek( hyph.len, LVSEEK_CUR, &newPos )!=LVERR_OK ) return false; cnv.msf( hyph.wl ); cnv.msf( hyph.wu ); charMap[ (unsigned char)hyph.al ] = hyph.wl; charMap[ (unsigned char)hyph.au ] = hyph.wu; // lChar16 ch = hyph.wl; // CRLog::debug("wl=%s mask=%c%c", LCSTR(lString16(&ch, 1)), hyph.mask0[0], hyph.mask0[1]); if (hyph.mask0[0]!='0'||hyph.mask0[1]!='0') { unsigned char pat[4]; pat[0] = hyph.al; pat[1] = hyph.mask0[0]; pat[2] = hyph.mask0[1]; pat[3] = 0; TexPattern * pattern = new TexPattern(pat, 1, charMap); #if DUMP_PATTERNS==1 CRLog::debug("Pattern: '%s' - %s", LCSTR(lString16(pattern->word)), pattern->attr ); #endif addPattern( pattern ); patternCount++; } } if ( stream->SetPos(p)!=p ) return false; for (i=0; i<hyph_count; i++) { stream->Read( &hyph, 522, &dw ); if (dw!=522) return false; cnv.msf( &hyph.len ); stream->Read(buf, hyph.len, &dw); if (dw!=hyph.len) return false; unsigned char * p = buf; unsigned char * end_p = p + hyph.len; while ( p < end_p ) { lUInt8 sz = *p++; if ( p + sz > end_p ) break; TexPattern * pattern = new TexPattern( p, sz, charMap ); #if DUMP_PATTERNS==1 CRLog::debug("Pattern: '%s' - %s", LCSTR(lString16(pattern->word)), pattern->attr); #endif addPattern( pattern ); patternCount++; p += sz + sz + 1; } } return patternCount>0; } else { // tex xml format as for FBReader lString16Collection data; HyphPatternReader reader( data ); LVXMLParser parser( stream, &reader ); if ( !parser.CheckFormat() ) return false; if ( !parser.Parse() ) return false; if ( !data.length() ) return false; for ( int i=0; i<(int)data.length(); i++ ) { data[i].lowercase(); TexPattern * pattern = new TexPattern( data[i] ); #if DUMP_PATTERNS==1 CRLog::debug("Pattern: (%s) '%s' - %s", LCSTR(data[i]), LCSTR(lString16(pattern->word)), pattern->attr); #endif addPattern( pattern ); patternCount++; } return patternCount>0; } }
static int findText(lua_State *L) { CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument"); const char *l_pattern = luaL_checkstring(L, 2); lString16 pattern = lString16(l_pattern); int origin = luaL_checkint(L, 3); bool reverse = luaL_checkint(L, 4); bool caseInsensitive = luaL_checkint(L, 5); if ( pattern.empty() ) return 0; LVArray<ldomWord> words; lvRect rc; doc->text_view->GetPos( rc ); int pageHeight = rc.height(); int start = -1; int end = -1; if ( reverse ) { // backward if ( origin == 0 ) { // from end of current page to first page end = rc.bottom; } else if ( origin == -1 ) { // from the last page to end of current page start = rc.bottom + 1; } else { // origin == 1 // from prev page to the first page end = rc.top - 1; } } else { // forward if ( origin == 0 ) { // from current page to the last page start = rc.top; } else if ( origin == -1 ) { // from the first page to current page end = rc.top + 1; } else { // origin == 1 // from next page to the last page start = rc.bottom + 1; } } CRLog::debug("CRViewDialog::findText: Current page: %d .. %d", rc.top, rc.bottom); CRLog::debug("CRViewDialog::findText: searching for text '%s' from %d to %d origin %d", LCSTR(pattern), start, end, origin ); if ( doc->text_view->getDocument()->findText( pattern, caseInsensitive, reverse, start, end, words, 200, pageHeight ) ) { CRLog::debug("CRViewDialog::findText: pattern found"); doc->text_view->clearSelection(); doc->text_view->selectWords( words ); ldomMarkedRangeList * ranges = doc->text_view->getMarkedRanges(); if ( ranges && ranges->length() > 0 ) { lua_newtable(L); // hold all words for (int i = 0; i < words.length(); i++) { ldomWord word = words[i]; lua_newtable(L); // new word lua_pushstring(L, "start"); lua_pushstring(L, UnicodeToLocal(word.getStartXPointer().toString()).c_str()); lua_settable(L, -3); lua_pushstring(L, "end"); lua_pushstring(L, UnicodeToLocal(word.getEndXPointer().toString()).c_str()); lua_settable(L, -3); lua_rawseti(L, -2, i + 1); } return 1; } } CRLog::debug("CRViewDialog::findText: pattern not found"); return 0; }
int CRFileHist::findEntry( const lString16 & fname, const lString16 & fpath, lvsize_t sz ) { CR_UNUSED(fpath); for ( int i=0; i<_records.length(); i++ ) { CRFileHistRecord * rec = _records[i]; if ( rec->getFileName().compare(fname) ) continue; if ( rec->getFileSize()!=sz ) { CRLog::warn("CRFileHist::findEntry() Filename matched %s but sizes are different %d!=%d", LCSTR(fname), sz, rec->getFileSize() ); continue; } return i; } return -1; }
bool TexHyph::hyphenate( const lChar16 * str, int len, lUInt16 * widths, lUInt8 * flags, lUInt16 hyphCharWidth, lUInt16 maxWidth ) { if ( len<=3 ) return false; if ( len>WORD_LENGTH ) len = WORD_LENGTH - 2; lChar16 word[WORD_LENGTH+3]; char mask[WORD_LENGTH+3]; word[0] = ' '; lStr_memcpy( word+1, str, len ); lStr_lowercase(word+1, len); word[len+1] = ' '; word[len+2] = 0; word[len+3] = 0; word[len+4] = 0; #if DUMP_HYPHENATION_WORDS==1 CRLog::trace("word to hyphenate: '%s'", LCSTR(lString16(word))); #endif memset( mask, '0', len+3 ); mask[len+3] = 0; bool found = false; for ( int i=0; i<len; i++ ) { found = match( word + i, mask + i ) || found; } if ( !found ) return false; #if DUMP_HYPHENATION_WORDS==1 lString16 buf; lString16 buf2; bool boundFound = false; for ( int i=0; i<len; i++ ) { buf << word[i+1]; buf2 << word[i+1]; buf2 << (lChar16)mask[i+2]; int nw = widths[i]+hyphCharWidth; if ( (mask[i+2]&1) ) { buf << (lChar16)'-'; buf2 << (lChar16)'-'; } if ( nw>maxWidth && !boundFound ) { buf << (lChar16)'|'; buf2 << (lChar16)'|'; boundFound = true; // buf << (lChar16)'-'; // buf2 << (lChar16)'-'; } } CRLog::trace("Hyphenate: %s %s", LCSTR(buf), LCSTR(buf2) ); #endif bool res = false; int p=0; for ( p=len-3; p>=1; p-- ) { // hyphenate //00010030100 int nw = widths[p]+hyphCharWidth; if ( (mask[p+2]&1) && nw <= maxWidth ) { //if ( checkHyphenRules( word+1, len, p ) ) { //widths[p] += hyphCharWidth; // don't add hyph width flags[p] |= LCHAR_ALLOW_HYPH_WRAP_AFTER; res = true; //} } } return res; }
bool SearchDialog::findText( lString16 pattern, int origin, bool reverse, bool caseInsensitive ) { if ( pattern.empty() ) return false; if ( pattern!=_lastPattern && origin==1 ) origin = 0; _lastPattern = pattern; LVArray<ldomWord> words; lvRect rc; _docview->getDocView()->GetPos( rc ); int pageHeight = rc.height(); int start = -1; int end = -1; if ( reverse ) { // reverse if ( origin == 0 ) { // from end current page to first page end = rc.bottom; } else if ( origin == -1 ) { // from last page to end of current page start = rc.bottom; } else { // origin == 1 // from prev page to first page end = rc.top; } } else { // forward if ( origin == 0 ) { // from current page to last page start = rc.top; } else if ( origin == -1 ) { // from first page to current page end = rc.top; } else { // origin == 1 // from next page to last start = rc.bottom; } } CRLog::debug("CRViewDialog::findText: Current page: %d .. %d", rc.top, rc.bottom); CRLog::debug("CRViewDialog::findText: searching for text '%s' from %d to %d origin %d", LCSTR(pattern), start, end, origin ); if ( _docview->getDocView()->getDocument()->findText( pattern, caseInsensitive, reverse, start, end, words, 200, pageHeight ) ) { CRLog::debug("CRViewDialog::findText: pattern found"); _docview->getDocView()->clearSelection(); _docview->getDocView()->selectWords( words ); ldomMarkedRangeList * ranges = _docview->getDocView()->getMarkedRanges(); if ( ranges ) { if ( ranges->length()>0 ) { int pos = ranges->get(0)->start.y; _docview->getDocView()->SetPos(pos); } } return true; } CRLog::debug("CRViewDialog::findText: pattern not found"); return false; }