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 getDirectoryFonts( lString16Collection & pathList, lString16 ext, lString16Collection & fonts, bool absPath ) { int foundCount = 0; lString16 path; for (int di=0; di<pathList.length();di++ ) { path = pathList[di]; LVContainerRef dir = LVOpenDirectory(path.c_str()); if(!dir.isNull()) { CRLog::trace("Checking directory %s", UnicodeToUtf8(path).c_str() ); for(int i=0; i < dir->GetObjectCount(); i++ ) { const LVContainerItemInfo * item = dir->GetObjectInfo(i); lString16 fileName = item->GetName(); if ( !item->IsContainer() && fileName.length()>4 && lString16(fileName, fileName.length()-4, 4)==ext ) { lString16 fn; if ( absPath ) { fn = path; if (!fn.empty() && fn[fn.length()-1]!=PATH_SEPARATOR_CHAR) fn << PATH_SEPARATOR_CHAR; } fn << fileName; foundCount++; fonts.add(fn); } } } } return foundCount > 0; }
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; }
lString16 EpubGetRootFilePath(LVContainerRef m_arc) { // check root media type lString16 rootfilePath; lString16 rootfileMediaType; // read container.xml { LVStreamRef container_stream = m_arc->OpenStream(L"META-INF/container.xml", LVOM_READ); if ( !container_stream.isNull() ) { ldomDocument * doc = LVParseXMLStream( container_stream ); if ( doc ) { ldomNode * rootfile = doc->nodeFromXPath( lString16(L"container/rootfiles/rootfile") ); if ( rootfile && rootfile->isElement() ) { rootfilePath = rootfile->getAttributeValue(L"full-path"); rootfileMediaType = rootfile->getAttributeValue(L"media-type"); } delete doc; } } } if ( rootfilePath.empty() || rootfileMediaType!=L"application/oebps-package+xml" ) return lString16::empty_str; return rootfilePath; }
virtual LVStreamRef OpenStream( const lChar16 * fname, lvopen_mode_t mode ) { LVStreamRef res = _container->OpenStream(fname, mode); if (res.isNull()) return res; if (isEncryptedItem(fname)) return LVStreamRef(new FontDemanglingStream(res, _fontManglingKey)); return res; }
static void findImagesFromDirectory( lString16 dir, lString16Collection & files ) { LVAppendPathDelimiter(dir); if ( !LVDirectoryExists(dir) ) return; LVContainerRef cont = LVOpenDirectory(dir.c_str()); if ( !cont.isNull() ) { for ( int i=0; i<cont->GetObjectCount(); i++ ) { const LVContainerItemInfo * item = cont->GetObjectInfo(i); if ( !item->IsContainer() ) { lString16 name = item->GetName(); name.lowercase(); if ( name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".gif") || name.endsWith(".jpeg") ) { files.add(dir + item->GetName()); } } } } }
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()); } } } }
bool getDirectoryFonts( lString16Collection & pathList, lString16Collection & ext, lString16Collection & fonts, bool absPath ) { int foundCount = 0; lString16 path; for ( int di=0; di<pathList.length();di++ ) { path = pathList[di]; LVContainerRef dir = LVOpenDirectory(path.c_str()); if ( !dir.isNull() ) { CRLog::trace("Checking directory %s", UnicodeToUtf8(path).c_str() ); for ( int i=0; i < dir->GetObjectCount(); i++ ) { const LVContainerItemInfo * item = dir->GetObjectInfo(i); lString16 fileName = item->GetName(); lString8 fn = UnicodeToLocal(fileName); //printf(" test(%s) ", fn.c_str() ); if ( !item->IsContainer() ) { bool found = false; lString16 lc = fileName; lc.lowercase(); for ( int j=0; j<ext.length(); j++ ) { if ( lc.endsWith(ext[j]) ) { found = true; break; } } if ( !found ) continue; lString16 fn; if ( absPath ) { fn = path; if ( !fn.empty() && fn[fn.length()-1]!=PATH_SEPARATOR_CHAR) fn << PATH_SEPARATOR_CHAR; } fn << fileName; foundCount++; fonts.add( fn ); } } } } return foundCount > 0; }
bool open() { LVStreamRef stream = _container->OpenStream(L"META-INF/encryption.xml", LVOM_READ); if (stream.isNull()) return false; EncCallback enccallback(this); LVXMLParser parser(stream, &enccallback, false, false); if (!parser.Parse()) return false; if (_list.length()) return true; return false; }
//TODO: place TinyDictionary to separate file CRTinyDict::CRTinyDict( const lString16& config ) { lString16 path = config; LVAppendPathDelimiter( path ); LVContainerRef dir = LVOpenDirectory( config.c_str() ); if ( !dir ) dir = LVOpenDirectory( LVExtractPath(config).c_str() ); if ( !dir.isNull() ) { int count = dir->GetSize(); lString16 indexExt(".index"); for ( int i=0; i<count; i++ ) { const LVContainerItemInfo * item = dir->GetObjectInfo( i ); if ( !item->IsContainer() ) { lString16 name = item->GetName(); if ( name.endsWith( indexExt ) ) { lString16 nameBase = name.substr( 0, name.length() - indexExt.length() ); lString16 name1 = nameBase + ".dict"; lString16 name2 = nameBase + ".dict.dz"; lString16 dataName; int index = -1; for ( int n=0; n<count; n++ ) { const LVContainerItemInfo * item2 = dir->GetObjectInfo( n ); if ( !item2->IsContainer() ) { if ( item2->GetName() == name1 || item2->GetName() == name2 ) { index = n; dataName = item2->GetName(); break; } } } if ( index>=0 ) { // found pair dicts.add(UnicodeToUtf8(path + name).c_str(), UnicodeToUtf8(path + dataName).c_str()); } } } } } CRLog::info( "%d dictionaries opened", dicts.length() ); }
/* * 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; }
/* * Class: org_coolreader_crengine_Engine * Method: getArchiveItemsInternal * Signature: (Ljava/lang/String;)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_org_coolreader_crengine_Engine_getArchiveItemsInternal (JNIEnv * _env, jclass, jstring jarcName) { CRJNIEnv env(_env); lString16 arcName = env.fromJavaString(jarcName); lString16Collection list; //fontMan->getFaceList(list); LVStreamRef stream = LVOpenFileStream( arcName.c_str(), LVOM_READ ); if ( !stream.isNull() ) { LVContainerRef arc = LVOpenArchieve(stream); if ( !arc.isNull() ) { // convert for ( int i=0; i<arc->GetObjectCount(); i++ ) { const LVContainerItemInfo * item = arc->GetObjectInfo(i); if ( item->IsContainer()) continue; list.add( item->GetName() ); list.add( lString16::itoa(item->GetSize()) ); } } } return env.toJavaStringArray(list); }
/// returns object size (file size or directory entry count) virtual lverror_t GetSize( lvsize_t * pSize ) { return _container->GetSize(pSize); }
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; }
int GetBookProperties(char *name, struct BookProperties* pBookProps, int localLanguage) { CRLog::trace("GetBookProperties( %s )", name); memset(pBookProps, 0, sizeof(BookProperties) ); // open stream LVStreamRef stream = LVOpenFileStream(name, LVOM_READ); if (!stream) { CRLog::error("cannot open file %s", name); return 0; } // check archieve #ifdef USE_ZLIB LVContainerRef arc; //printf("start opening arc\n"); //for ( int i=0; i<1000; i++ ) //for ( int kk=0; kk<1000; kk++) { arc = LVOpenArchieve( stream ); //printf("end opening arc\n"); if (!arc.isNull()) { CRLog::trace("%s is archive with %d items", name, arc->GetObjectCount()); // archieve const LVContainerItemInfo * bestitem = NULL; const LVContainerItemInfo * fb2item = NULL; const LVContainerItemInfo * fbditem = NULL; for (int i=0; i<arc->GetObjectCount(); i++) { const LVContainerItemInfo * item = arc->GetObjectInfo(i); if (item) { if ( !item->IsContainer() ) { lString16 name( item->GetName() ); if ( name.length() > 5 ) { name.lowercase(); const lChar16 * pext = name.c_str() + name.length() - 4; if ( pext[0]=='.' && pext[1]=='f' && pext[2]=='b' && pext[3]=='2') { fb2item = item; } else if ( pext[0]=='.' && pext[1]=='f' && pext[2]=='b' && pext[3]=='d') { fbditem = item; } } } } } bestitem = fb2item; if ( fbditem ) bestitem = fbditem; if ( !bestitem ) return 0; CRLog::trace( "opening item %s from archive", UnicodeToUtf8(bestitem->GetName()).c_str() ); //printf("start opening stream\n"); //for ( int k=0; k<1000; k++ ) { stream = arc->OpenStream( bestitem->GetName(), LVOM_READ ); char buf[8192]; stream->Read(buf, 8192, NULL ); //} //printf("end opening stream\n"); if ( stream.isNull() ) return 0; CRLog::trace( "stream created" ); // opened archieve stream } } #endif //USE_ZLIB // 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 0; } CRLog::trace( "parsing..." ); if ( !parser.Parse() ) { return 0; } 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 title = extractDocTitle( &doc ); lString16 series = extractDocSeriesReverse( &doc ); #if SERIES_IN_AUTHORS==1 if ( !series.empty() ) authors << L" " << series; #endif SetFieldValue( pBookProps->name, title ); if ( !authors.empty() ) SetFieldValue( pBookProps->author, authors ); if ( !series.empty() ) SetFieldValue( pBookProps->series, series ); pBookProps->filesize = (long)stream->GetSize(); strncpy( pBookProps->filename, name, MAX_PROPERTY_LEN-1 ); struct stat fs; time_t t; if ( stat( name, &fs ) ) { t = (time_t)time(0); } else { t = fs.st_mtime; } SetFieldValue( pBookProps->filedate, getDateTimeString( t, localLanguage ) ); return 1; }
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; }
virtual LVContainer * GetParentContainer() { return _container->GetParentContainer(); }
//virtual const LVContainerItemInfo * GetObjectInfo(const wchar_t * pname); virtual const LVContainerItemInfo * GetObjectInfo(int index) { return _container->GetObjectInfo(index); }
virtual int GetObjectCount() const { return _container->GetObjectCount(); }
/// sets stream/container name, may be not implemented for some objects virtual void SetName(const lChar16 * name) { _container->SetName(name); }
/// returns stream/container name, may be NULL if unknown virtual const lChar16 * GetName() { return _container->GetName(); }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CRLog::setFileLogger( "crengine.log" ); CRLog::setLogLevel( CRLog::LL_TRACE ); // TODO: Place code here. MSG msg; HACCEL hAccelTable; //make_dither_table(); //TestWol(); /* LVStreamRef zipfile = LVOpenFileStream( L"zip_test.zip", LVOM_READ ); if (!zipfile.isNull()) { LVContainerRef zip = LVOpenArchieve( zipfile ); if (!zip.isNull()) { LVStreamRef log = LVOpenFileStream("ziptest.log", LVOM_WRITE); for (int i=0; i<zip->GetObjectCount(); i++) { const LVContainerItemInfo * item = zip->GetObjectInfo(i); if (item) { // *log << UnicodeToLocal( item->GetName() ); *log << lString8::itoa( (int)item->GetSize() ); LVStreamRef unpstream = zip->OpenStream( item->GetName(), LVOM_READ ); if (!unpstream.isNull()) { *log << "\n arc stream opened ok \n"; LVStreamRef outstream = LVOpenFileStream( item->GetName(), LVOM_WRITE ); if ( !outstream.isNull() ) { int copiedBytes = (int)LVPumpStream( outstream, unpstream ); *log << " copied " << lString8::itoa(copiedBytes) << " bytes\n"; } else { *log << " error opening out stream\n"; } } } } } } */ lString8 exe_dir; char exe_fn[MAX_PATH+1]; GetModuleFileNameA( NULL, exe_fn, MAX_PATH ); int last_slash = -1; int i; for (i=0; exe_fn[i]; i++) if (exe_fn[i]=='\\' || exe_fn[i]=='/') last_slash = i; if (last_slash>0) exe_dir = lString8( exe_fn, last_slash ); // init hyphenation manager initHyph( (exe_dir + "\\russian_EnUS_hyphen_(Alan).pdb").c_str() ); lString8 fontDir = exe_dir; fontDir << "\\fonts"; // init bitmap font manager InitFontManager( fontDir ); // Load font definitions into font manager // fonts are in files font1.lbf, font2.lbf, ... font32.lbf #if (USE_FREETYPE==1) LVContainerRef dir = LVOpenDirectory( LocalToUnicode(fontDir).c_str() ); if ( !dir.isNull() ) for ( i=0; i<dir->GetObjectCount(); i++ ) { const LVContainerItemInfo * item = dir->GetObjectInfo(i); lString16 fileName = item->GetName(); if ( !item->IsContainer() && fileName.length()>4 && lString16(fileName, fileName.length()-4, 4)==L".ttf" ) { lString8 fn = UnicodeToLocal(fileName); printf("loading font: %s\n", fn.c_str()); if ( !fontMan->RegisterFont(fn) ) { printf(" failed\n"); } } } //fontMan->RegisterFont(lString8("arial.ttf")); #else #if (USE_WIN32_FONTS==0) #define MAX_FONT_FILE 32 for (i=0; i<MAX_FONT_FILE; i++) { char fn[32]; sprintf( fn, "font%d.lbf", i ); fontMan->RegisterFont( lString8(fn) ); } #endif #endif //LVCHECKPOINT("WinMain start"); text_view = new LVDocView; // stylesheet can be placed to file fb2.css // if not found, default stylesheet will be used lString8 css = readFileToString( (exe_dir + "\\fb2.css").c_str() ); if (css.length() > 0) text_view->setStyleSheet( css ); //LVCHECKPOINT("WinMain before loads"); if (!fontMan->GetFontCount()) { //error char str[1000]; #if (USE_FREETYPE==1) sprintf(str, "Cannot open font file(s) fonts/*.ttf \nCannot work without font\nPlace some TTF files to font\\ directory" ); #else sprintf(str, "Cannot open font file(s) font#.lbf \nCannot work without font\nUse FontConv utility to generate .lbf fonts from TTF" ); #endif MessageBoxA( NULL, str, "CR Engine :: Fb2Test -- fatal error!", MB_OK); return 1; } lString8 cmdline(lpCmdLine); cmdline.trim(); if ( cmdline == "test_format" ) { testFormatting(); return 1; } if (cmdline.empty()) { cmdline = OpenFileDialog( NULL ); //cmdline = "example2.fb2"; } if ( cmdline.empty() ) return 2; if ( !text_view->LoadDocument( cmdline.c_str() )) { //error char str[100]; sprintf(str, "Cannot open document file %s", cmdline.c_str()); MessageBoxA( NULL, str, "CR Engine :: Fb2Test -- fatal error!", MB_OK); return 1; } //LVCHECKPOINT("WinMain after loads"); // Initialize global strings MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FONTTEST); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } delete text_view; ShutdownFontManager(); return msg.wParam; }