diff options
Diffstat (limited to 'windows/thumbnail.c')
-rw-r--r-- | windows/thumbnail.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/windows/thumbnail.c b/windows/thumbnail.c new file mode 100644 index 000000000..8305ee1cc --- /dev/null +++ b/windows/thumbnail.c @@ -0,0 +1,149 @@ +/* + * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "content/urldb.h" +#include "desktop/browser.h" +#include "utils/log.h" + +#include "windows/bitmap.h" +#include "windows/gui.h" +#include "windows/plot.h" + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +bool thumbnail_create(struct content *content, struct bitmap *bitmap, + const char *url) +{ + LOG(("creating thumbnail %p for url %s content %p", bitmap, url, + content)); + int width = MIN(content->width, 1024); + int height = MIN(content->height, 768); + int i; + uint8_t *pixdata; + HDC hdc, minidc; + HBITMAP bufferbm, minibm, minibm2; + BITMAPINFO *bmi = (BITMAPINFO *) malloc(sizeof(BITMAPINFOHEADER) + + (bitmap->width * bitmap->height * 4)); + BITMAPINFOHEADER bmih; + bmih.biSize = sizeof(bmih); + bmih.biWidth = bitmap->width; + bmih.biHeight = - bitmap->height; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + bmih.biSizeImage = 4 * bitmap->height * bitmap->width; + bmih.biXPelsPerMeter = 3600; /* 100 dpi */ + bmih.biYPelsPerMeter = 3600; + bmih.biClrUsed = 0; + bmih.biClrImportant = 0; + bmi->bmiHeader = bmih; + + doublebuffering = true; + + if (bufferdc != NULL) + DeleteDC(bufferdc); + hdc = GetDC(current_hwnd); + + bufferdc = CreateCompatibleDC(hdc); + if ((bufferdc == NULL) || (bmi == NULL)) { + doublebuffering = false; + ReleaseDC(current_hwnd, hdc); + return false; + } + + bufferbm = CreateCompatibleBitmap(hdc, width, height); + if (bufferbm == NULL) { + doublebuffering = false; + ReleaseDC(current_hwnd, hdc); + free(bmi); + return false; + } + SelectObject(bufferdc, bufferbm); + thumbnail = true; + content_redraw(content, 0, 0, content->width, content->height, 0, 0, + width, height, 1.0, 0xFFFFFF); + thumbnail = false; + +/* scale bufferbm to minibm */ + + minidc = CreateCompatibleDC(hdc); + if (minidc == NULL) { + doublebuffering = false; + DeleteObject(bufferbm); + ReleaseDC(current_hwnd, hdc); + free(bmi); + return false; + } + + minibm = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height); + if (minibm == NULL) { + doublebuffering = false; + DeleteObject(bufferbm); + DeleteDC(minidc); + ReleaseDC(current_hwnd, hdc); + free(bmi); + return false; + } + ReleaseDC(current_hwnd, hdc); + + SelectObject(minidc, minibm); + + StretchBlt(minidc, 0, 0, bitmap->width, bitmap->height, bufferdc, 0, 0, + width, height, SRCCOPY); + minibm2 = CreateCompatibleBitmap(minidc, bitmap->width, + bitmap->height); + if (minibm2 == NULL) { + doublebuffering = false; + DeleteObject(bufferbm); + DeleteObject(minibm); + DeleteDC(minidc); + free(bmi); + return false; + } + SelectObject(minidc, minibm2); + +/* save data from minibm bmi */ + GetDIBits(minidc, minibm, 0, 1 - bitmap->height, + bmi->bmiColors, bmi, DIB_RGB_COLORS); + + pixdata = (uint8_t *)(bitmap->pixdata); + for (i = 0; i < bitmap->width * bitmap->height; i++) { + pixdata[4 * i] = bmi->bmiColors[i].rgbRed; + pixdata[4 * i + 1] = bmi->bmiColors[i].rgbGreen; + pixdata[4 * i + 2] = bmi->bmiColors[i].rgbBlue; + pixdata[4 * i + 3] = 0xFF; + } + doublebuffering = false; + + DeleteObject(bufferbm); + DeleteObject(minibm); + DeleteObject(minibm2); + DeleteDC(minidc); + free(bmi); + if (url) + urldb_set_thumbnail(url, bitmap); + + doublebuffering = false; + return true; +} |