static void GetSortedFilePaths(Vec<const WCHAR *>& filePathsSortedOut, DisplayState *toIgnore=NULL) { DisplayState *ds; for (size_t i = 0; (ds = gFileHistory.Get(i)) != NULL; i++) { if (ds->favorites->Count() > 0 && ds != toIgnore) filePathsSortedOut.Append(ds->filePath); } filePathsSortedOut.Sort(SortByBaseFileName); }
static void GetSortedFilePaths(Favorites *favorites, Vec<TCHAR*>& filePathsSortedOut, FileFavs *toIgnore) { for (size_t i = 0; i < favorites->favs.Count(); i++) { FileFavs *f = favorites->favs.At(i); if (f != toIgnore) filePathsSortedOut.Append(f->filePath); } filePathsSortedOut.Sort(SortByBaseFileName); }
UINT RenderCache::Paint(HDC hdc, RectI bounds, DisplayModel *dm, int pageNo, PageInfo *pageInfo, bool *renderOutOfDateCue) { assert(pageInfo->shown && 0.0 != pageInfo->visibleRatio); int rotation = dm->Rotation(); float zoom = dm->ZoomReal(); USHORT targetRes = GetTileRes(dm, pageNo); USHORT maxRes = GetMaxTileRes(dm, pageNo, rotation); if (maxRes < targetRes) maxRes = targetRes; Vec<TilePosition> queue; queue.Append(TilePosition(0, 0, 0)); UINT renderDelayMin = RENDER_DELAY_UNDEFINED; bool neededScaling = false; while (queue.Count() > 0) { TilePosition tile = queue.At(0); queue.RemoveAt(0); RectI tileOnScreen = GetTileOnScreen(dm->engine, pageNo, rotation, zoom, tile, pageInfo->pageOnScreen); tileOnScreen = pageInfo->pageOnScreen.Intersect(tileOnScreen); RectI isect = bounds.Intersect(tileOnScreen); if (isect.IsEmpty()) continue; bool isTargetRes = tile.res == targetRes; UINT renderDelay = PaintTile(hdc, isect, dm, pageNo, tile, tileOnScreen, isTargetRes, renderOutOfDateCue, isTargetRes ? &neededScaling : NULL); if (!(isTargetRes && 0 == renderDelay) && tile.res < maxRes) { queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2 + 1)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2 + 1)); } if (isTargetRes && renderDelay > 0) neededScaling = true; renderDelayMin = min(renderDelay, renderDelayMin); // paint tiles from left to right from top to bottom if (tile.res > 0 && queue.Count() > 0 && tile.res < queue.At(0).res) queue.Sort(cmpTilePosition); } #ifdef CONSERVE_MEMORY if (!neededScaling) { if (renderOutOfDateCue) *renderOutOfDateCue = false; // free tiles with different resolution TilePosition tile(targetRes, (USHORT)-1, 0); FreePage(dm, pageNo, &tile); } FreeNotVisible(); #endif return renderDelayMin; }
// returns a shallow copy of the file history list, sorted // by open count (which has a pre-multiplied recency factor) // and with all missing states filtered out // caller needs to delete the result (but not the contained states) void FileHistory::GetFrequencyOrder(Vec<DisplayState*>& list) { CrashIf(list.size() > 0); size_t i = 0; for (DisplayState* ds : *states) { ds->index = i++; if (!ds->isMissing || ds->isPinned) list.Append(ds); } list.Sort(cmpOpenCount); }
bool CbxEngineImpl::LoadCbrFile(const WCHAR *file) { if (!file) return false; fileName = str::Dup(file); fileExt = L".cbr"; RAROpenArchiveDataEx arcData = { 0 }; arcData.ArcNameW = (WCHAR *)file; arcData.OpenMode = RAR_OM_EXTRACT; HANDLE hArc = RAROpenArchiveEx(&arcData); if (!hArc || arcData.OpenResult != 0) return false; // UnRAR does not seem to support extracting a single file by name, // so lazy image loading doesn't seem possible Vec<ImagesPage *> found; for (;;) { RARHeaderDataEx rarHeader; int res = RARReadHeaderEx(hArc, &rarHeader); if (0 != res) break; const WCHAR *fileName = rarHeader.FileNameW; if (ImageEngine::IsSupportedFile(fileName)) { ImagesPage *page = LoadCurrentCbrPage(hArc, rarHeader); if (page) found.Append(page); } else if (str::EqI(fileName, L"ComicInfo.xml")) { ScopedMem<char> xmlData(LoadCurrentCbrFile(hArc, rarHeader, NULL)); if (xmlData) ParseComicInfoXml(xmlData); } else RARProcessFile(hArc, RAR_SKIP, NULL, NULL); } RARCloseArchive(hArc); if (found.Count() == 0) return false; found.Sort(ImagesPage::cmpPageByName); for (size_t i = 0; i < found.Count(); i++) { pages.Append(found.At(i)->bmp); found.At(i)->bmp = NULL; } mediaboxes.AppendBlanks(pages.Count()); DeleteVecMembers(found); return true; }
bool CbxEngineImpl::FinishLoadingCbz() { fileExt = L".cbz"; Vec<const WCHAR *> allFileNames; for (size_t idx = 0; idx < cbzFile->GetFileCount(); idx++) { const WCHAR *fileName = cbzFile->GetFileName(idx); // bail, if we accidentally try to load an XPS file if (fileName && str::StartsWith(fileName, L"_rels/.rels")) return false; if (fileName && ImageEngine::IsSupportedFile(fileName) && // OS X occasionally leaves metadata with image extensions !str::StartsWith(path::GetBaseName(fileName), L".")) { allFileNames.Append(fileName); } else { allFileNames.Append(NULL); } } assert(allFileNames.Count() == cbzFile->GetFileCount()); ScopedMem<char> metadata(cbzFile->GetFileData(L"ComicInfo.xml")); if (metadata) ParseComicInfoXml(metadata); metadata.Set(cbzFile->GetComment()); if (metadata) json::Parse(metadata, this); Vec<const WCHAR *> pageFileNames; for (const WCHAR **fn = allFileNames.IterStart(); fn; fn = allFileNames.IterNext()) { if (*fn) pageFileNames.Append(*fn); } pageFileNames.Sort(cmpAscii); for (const WCHAR **fn = pageFileNames.IterStart(); fn; fn = pageFileNames.IterNext()) { fileIdxs.Append(allFileNames.Find(*fn)); } assert(pageFileNames.Count() == fileIdxs.Count()); if (fileIdxs.Count() == 0) return false; pages.AppendBlanks(fileIdxs.Count()); mediaboxes.AppendBlanks(fileIdxs.Count()); return true; }
UINT RenderCache::Paint(HDC hdc, RectI bounds, DisplayModel* dm, int pageNo, PageInfo* pageInfo, bool* renderOutOfDateCue) { AssertCrash(pageInfo->shown && 0.0 != pageInfo->visibleRatio); if (!dm->ShouldCacheRendering(pageNo)) { int rotation = dm->GetRotation(); float zoom = dm->GetZoomReal(pageNo); bounds = pageInfo->pageOnScreen.Intersect(bounds); RectD area = bounds.Convert<double>(); area.Offset(-pageInfo->pageOnScreen.x, -pageInfo->pageOnScreen.y); area = dm->GetEngine()->Transform(area, pageNo, zoom, rotation, true); RenderedBitmap* bmp = dm->GetEngine()->RenderBitmap(pageNo, zoom, rotation, &area); bool success = bmp && bmp->GetBitmap() && bmp->StretchDIBits(hdc, bounds); delete bmp; return success ? 0 : RENDER_DELAY_FAILED; } int rotation = dm->GetRotation(); float zoom = dm->GetZoomReal(); USHORT targetRes = GetTileRes(dm, pageNo); USHORT maxRes = GetMaxTileRes(dm, pageNo, rotation); if (maxRes < targetRes) maxRes = targetRes; Vec<TilePosition> queue; queue.Append(TilePosition(0, 0, 0)); UINT renderDelayMin = RENDER_DELAY_UNDEFINED; bool neededScaling = false; while (queue.size() > 0) { TilePosition tile = queue.PopAt(0); RectI tileOnScreen = GetTileOnScreen(dm->GetEngine(), pageNo, rotation, zoom, tile, pageInfo->pageOnScreen); if (tileOnScreen.IsEmpty()) { // display an error message when only empty tiles should be drawn (i.e. on page loading errors) renderDelayMin = std::min(RENDER_DELAY_FAILED, renderDelayMin); continue; } tileOnScreen = pageInfo->pageOnScreen.Intersect(tileOnScreen); RectI isect = bounds.Intersect(tileOnScreen); if (isect.IsEmpty()) continue; bool isTargetRes = tile.res == targetRes; UINT renderDelay = PaintTile(hdc, isect, dm, pageNo, tile, tileOnScreen, isTargetRes, renderOutOfDateCue, isTargetRes ? &neededScaling : nullptr); if (!(isTargetRes && 0 == renderDelay) && tile.res < maxRes) { queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2, tile.col * 2 + 1)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2)); queue.Append(TilePosition(tile.res + 1, tile.row * 2 + 1, tile.col * 2 + 1)); } if (isTargetRes && renderDelay > 0) neededScaling = true; renderDelayMin = std::min(renderDelay, renderDelayMin); // paint tiles from left to right from top to bottom if (tile.res > 0 && queue.size() > 0 && tile.res < queue.at(0).res) queue.Sort(cmpTilePosition); } #ifdef CONSERVE_MEMORY if (!neededScaling) { if (renderOutOfDateCue) *renderOutOfDateCue = false; // free tiles with different resolution TilePosition tile(targetRes, (USHORT)-1, 0); FreePage(dm, pageNo, &tile); } FreeNotVisible(); #endif return renderDelayMin; }