[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Enigma-cvs] enigma/src menus_internal.hh,1.3,1.4
From: |
Ralf Westram <address@hidden> |
Subject: |
[Enigma-cvs] enigma/src menus_internal.hh,1.3,1.4 |
Date: |
Thu, 30 Oct 2003 19:12:15 +0000 |
Update of /cvsroot/enigma/enigma/src
In directory subversions:/tmp/cvs-serv18931/src
Modified Files:
menus_internal.hh
Log Message:
- LevelPreviewCache saves generated previews and loads them if present
- added savePNG
- deletes outdated previews
Index: menus_internal.hh
===================================================================
RCS file: /cvsroot/enigma/enigma/src/menus_internal.hh,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** menus_internal.hh 20 Oct 2003 08:05:46 -0000 1.3
--- menus_internal.hh 30 Oct 2003 19:12:13 -0000 1.4
***************
*** 19,22 ****
--- 19,25 ----
*/
+ #include <png.h>
+ #include <iostream>
+
//----------------------------------------------------------------------
// Helper classes
***************
*** 49,53 ****
int m_maxheight;
public:
! VTableBuilder (Menu *menu, const px::Rect &widgetsize,
int vspacing, int hspacing, int max_height)
: m_menu(menu), m_widgetsize(widgetsize)
--- 52,56 ----
int m_maxheight;
public:
! VTableBuilder (Menu *menu, const px::Rect &widgetsize,
int vspacing, int hspacing, int max_height)
: m_menu(menu), m_widgetsize(widgetsize)
***************
*** 57,61 ****
m_maxheight = max_height;
}
!
Widget *add (Widget *w) {
m_widgets.push_back(w);
--- 60,64 ----
m_maxheight = max_height;
}
!
Widget *add (Widget *w) {
m_widgets.push_back(w);
***************
*** 69,73 ****
int nrows = (m_widgets.size() + ncolumns - 1) / ncolumns;
int i=0;
! int x=0;
for (int col = 0; col < ncolumns; col++) {
int y=0;
--- 72,76 ----
int nrows = (m_widgets.size() + ncolumns - 1) / ncolumns;
int i=0;
! int x=0;
for (int col = 0; col < ncolumns; col++) {
int y=0;
***************
*** 126,158 ****
class LevelPreviewCacheElem {
! Surface *surface;
! unsigned idx;
LevelPreviewCacheElem(const LevelPreviewCacheElem&);
LevelPreviewCacheElem& operator = (const LevelPreviewCacheElem&
other);
public:
! LevelPreviewCacheElem(LevelPack *lp, unsigned idx_, int xsize, int
ysize)
! : surface(0) , idx(idx_)
{
! surface = LevelPreview(lp, idx); // do not free, points to
BackBuffer
! if (surface) {
! const Rect& game_area = display::GetGameArea();
! Surface *game_surface = Grab(surface, game_area);
- if (game_surface) {
- surface = game_surface->zoom(xsize, ysize);
delete game_surface;
}
- else {
- surface = 0; // avoid delete
- }
}
-
- // fprintf(stderr, "Created preview for #%i. surface=%p\n", idx,
surface);
}
! ~LevelPreviewCacheElem() { delete surface; }
bool operator<(const LevelPreviewCacheElem& other) { return
idx<other.idx; }
! Surface *get_surface() { return surface; }
};
--- 129,280 ----
+ void savePNG(Surface *surface, const string& fname) {
+ int h = surface->height();
+ int w = surface->width();
+ unsigned char *rows[h];
+
+ surface->lock();
+ for (int i = 0; i<h; ++i) {
+ rows[i] = (unsigned char *)surface->scanline_pointer(i);
+ }
+
+ enigma::Log << "Caching auto-preview as '" << fname << '\'' << endl;
+
+ string error;
+ FILE *fp = fopen(fname.c_str(), "wb");
+
+ if (fp) {
+ png_structp png_ptr =
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr) {
+ error = "write struct not generated";
+ }
+ else {
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ error = "info struct not generated";
+ }
+ else {
+ static const char *what = 0;
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ error = strf("unknown error during '%s' while
creating png", what);
+ }
+ else {
+ what = "png_init_io";
+ png_init_io(png_ptr, fp);
+ what = "png_set_IHDR";
+ png_set_IHDR(png_ptr,
+ info_ptr,
+ w, h,
+ 8,
+ PNG_COLOR_TYPE_RGBA,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE,
+ PNG_FILTER_TYPE_BASE);
+ // what = "png_set_compression_level";
+ // png_set_compression_level(png_ptr, 9); // nearly
no effect
+ what = "png_write_info";
+ png_write_info(png_ptr, info_ptr);
+
+ png_write_image(png_ptr, rows);
+
+ what = "png_write_end";
+ png_write_end(png_ptr, NULL);
+ }
+ }
+ // next line frees resources - and it crashes enigma :-(
+ // png_destroy_write_struct(&png_ptr, &info_ptr);
+ }
+ fclose(fp);
+ }
+ else {
+ error = "Couldn't create file";
+ }
+
+ if (error.length() > 0) {
+ fprintf(stderr, "Error saving '%s': %s\n", fname.c_str(),
error.c_str());
+ }
+
+ surface->unlock();
+ }
+
+ string removeIllChars(const string& s) {
+ string s2 = s;
+ for (string::iterator c = s2.begin(); c != s2.end(); ++c) {
+ if (!isalnum(*c)) *c = '_';
+ }
+ return s2;
+ }
+
+ string gen_preview_name(int revision, int preview_version, const string&
name) {
+ return px::strf("thumbs/%i_%i_%s.png", revision, preview_version,
name.c_str());
+ }
+
+ void removeOldPreviews(int revision, int preview_version, const string&
name) {
+ for (int r = revision; r >= 1; --r) {
+ for (int v = preview_version; v >= 1; --v) {
+ string preview_name = gen_preview_name(r, v, name);
+ string found_name;
+ if (FindFile(preview_name, found_name)) {
+ if (remove(found_name.c_str()) == -1) {
+ enigma::Log << "Error deleting outdated preview '" <<
found_name << '\'' << endl;
+ // fprintf(stderr, "error deleting %s\n",
found_name.c_str());
+ }
+ else {
+ enigma::Log << "Deleting outdated preview '" <<
found_name << '\'' << endl;
+ }
+ }
+ }
+ }
+ }
+
+
class LevelPreviewCacheElem {
! Surface *surface; // owned by ImageCache
! Surface *zoomed_surface; // owned by LevelPreviewCacheElem
! unsigned idx;
LevelPreviewCacheElem(const LevelPreviewCacheElem&);
LevelPreviewCacheElem& operator = (const LevelPreviewCacheElem&
other);
public:
! LevelPreviewCacheElem(LevelPack *lp, unsigned idx_, int xsize, int
ysize, ImageCache& img_cache)
! : surface(0), zoomed_surface(0), idx(idx_)
{
! string cleanedName =
removeIllChars(lp->get_info(idx)->filename);
! int rev_number = lp->get_revision_number(idx);
! int preview_version = lp->get_preview_version();
! string preview_name = gen_preview_name(rev_number,
preview_version, cleanedName);
! string preview_path;
!
! if (FindFile(preview_name, preview_path))
! surface = img_cache.get(preview_path);
!
! if (!surface) {
! Surface *preview = LevelPreview(lp, idx); // do not free,
points to BackBuffer
! if (preview) {
! const Rect& game_area = display::GetGameArea();
! Surface *game_surface = Grab(preview, game_area);
!
! if (game_surface) {
! zoomed_surface = game_surface->zoom(xsize, ysize);
! string preview_dir_path =
FindDataFile("thumbs/README");
! string parent_dir;
! if (px::split_path(preview_dir_path, &parent_dir, 0))
{
! string parent_dir2;
! if (px::split_path(parent_dir, &parent_dir2, 0)) {
! preview_name = px::concat_paths(parent_dir2,
preview_name);
! }
! }
!
! removeOldPreviews(rev_number, preview_version,
cleanedName);
! savePNG(zoomed_surface, preview_name);
! }
delete game_surface;
}
}
}
! ~LevelPreviewCacheElem() { delete zoomed_surface; }
bool operator<(const LevelPreviewCacheElem& other) { return
idx<other.idx; }
! Surface *get_surface() { return surface ? surface : zoomed_surface; }
};
***************
*** 161,164 ****
--- 283,287 ----
PreviewMap cache;
+ ImageCache imgCache;
int xsize, ysize;
***************
*** 183,187 ****
assert(xsize != 0 && ysize != 0); // forgot to call set_size() ?
! LevelPreviewCacheElem *ce = new LevelPreviewCacheElem(lp, idx,
xsize, ysize);
Surface *surface = ce->get_surface();
--- 306,310 ----
assert(xsize != 0 && ysize != 0); // forgot to call set_size() ?
! LevelPreviewCacheElem *ce = new LevelPreviewCacheElem(lp, idx,
xsize, ysize, imgCache);
Surface *surface = ce->get_surface();
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Enigma-cvs] enigma/src menus_internal.hh,1.3,1.4,
Ralf Westram <address@hidden> <=