preferences bug and multimon changes

This commit is contained in:
nothings.org 2012-01-17 14:10:18 +00:00
parent 1f9416227c
commit 70ee4e752b
4 changed files with 124 additions and 29 deletions

140
imv.c
View File

@ -50,7 +50,7 @@
#endif
#ifndef ALLOW_RECOLORING
#define ALLOW_RECOLORING 1
#define ALLOW_RECOLORING 0
#endif
//#define MONO2
@ -82,6 +82,7 @@ typedef int Bool;
Bool do_show;
float delay_time = 4;
int nearest_neighbor = 0; // internal use
// all programs get the version number from the same place: version.bat
#define set static char *
@ -355,6 +356,9 @@ int mono;
#endif
void make_image(Image *z, int image_x, int image_y, uint8 *image_data, BOOL image_loaded_as_rgb, int image_n)
{
#ifdef ALLOW_RECOLORING
int ms,md, ns,nd;
#endif
int i,j,k,ymin=0,ymax=256*8-1;
z->pixels = image_data;
z->x = image_x;
@ -363,6 +367,18 @@ void make_image(Image *z, int image_x, int image_y, uint8 *image_data, BOOL imag
z->frame = 0;
z->had_alpha = (image_n==4);
if (z->had_alpha) {
int n=0;
for (n=0; n < image_x * image_y; ++n)
if (image_data[n*4+3])
break;
if (n == image_x * image_y) {
// all alpha is 0, so force to 255
for (n=0; n < image_x * image_y; ++n)
image_data[n*4+3] = 255;
}
}
#if ALLOW_RECOLORING
if (mono) {
k = 0;
@ -377,6 +393,23 @@ void make_image(Image *z, int image_x, int image_y, uint8 *image_data, BOOL imag
}
#endif
#if ALLOW_RECOLORING
if (lmin > 0)
ms = (int) (lmin * 255), md=0;
else
ms = 0, md = (int)(-lmin*255);
if (lmax < 1)
ns = (int)(lmax * 255), nd=255;
else
ns = 255, nd = (int) ((2-lmax)*255);
if (ns <= ms)
ns = ms+1;
if (nd < md)
nd = md+1;
if (ns == 256) --ns,--ms;
if (nd == 256) --nd,--md;
#endif
k=0;
for (j=0; j < image_y; ++j) {
for (i=0; i < image_x; ++i) {
@ -399,10 +432,10 @@ void make_image(Image *z, int image_x, int image_y, uint8 *image_data, BOOL imag
image_data[k+0] = p;
image_data[k+1] = p;
image_data[k+2] = p;
} else if (lmin > 0 || lmax < 1) {
} else if (lmin != 0 || lmax != 1) {
int c;
for (c=0; c < 3; ++c) {
int z = (int) stb_linear_remap(image_data[k+c], lmin*255,lmax*255, 0,255);
int z = (int) stb_linear_remap(image_data[k+c], ms,ns, md,nd);
image_data[k+c] = stb_clamp(z, 0, 255);
}
}
@ -967,15 +1000,12 @@ void GetAdjustedWindowRect(HWND win, RECT *rect)
int allow_fullsize;
// compute the size we'd prefer this window to be at for 1:1-ness
void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y)
void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y, int cx2, int cy2)
{
// @TODO: this probably isn't right if the virtual TL isn't (0,0)???
int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int cx2 = GetSystemMetrics(SM_CXSCREEN);
int cy2 = GetSystemMetrics(SM_CYSCREEN);
if (allow_fullsize || (w <= cx2 && h <= cy2)) {
// if the image fits on the primary monitor, go for it
*w_ideal = w;
@ -991,6 +1021,7 @@ void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y)
compute_size(cx+FRAME*2 ,cy+FRAME*2,w,h,&w1,&h1);
compute_size(cx2+FRAME*2,cy2+FRAME*2,w,h,&w2,&h2);
// require it be "significantly more" on the virtual
#ifdef ALLOW_MULTISCREEN
if (h1 > h2*1.25 || w1 > w2*1.25) {
*w_ideal = stb_min(cx,w1)+FRAME*2;
*h_ideal = stb_min(cy,h1)+FRAME*2;
@ -998,6 +1029,10 @@ void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y)
*w_ideal = stb_min(cx2,w2)+FRAME*2;
*h_ideal = stb_min(cy2,h2)+FRAME*2;
}
#else
*w_ideal = stb_min(cx2,w2)+FRAME*2;
*h_ideal = stb_min(cy2,h2)+FRAME*2;
#endif
// compute actual size image will be if fit to this window
compute_size(*w_ideal, *h_ideal, w,h, &w,&h);
// and add the padding in
@ -1006,6 +1041,7 @@ void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y)
}
// now find center point...
#ifdef ALLOW_MULTISCREEN
if ((cx != cx2 || cy != cy2) && w <= cx2+FRAME*2 && h <= cy2+FRAME*2) {
// if it fits on the primary, center it on the primary
*x = (cx2 - w) >> 1;
@ -1015,6 +1051,10 @@ void ideal_window_size(int w, int h, int *w_ideal, int *h_ideal, int *x, int *y)
*x = (cx - w) >> 1;
*y = (cy - h) >> 1;
}
#else
*x = (cx2 - w) >> 1;
*y = (cy2 - h) >> 1;
#endif
}
@ -1035,23 +1075,26 @@ int display_mode;
void size_to_current(int maximize)
{
int w2,h2;
int w,h,x,y;
int w,h,x,y,cx,cy;
// get the monitor it's on
HMONITOR mon = MonitorFromWindow(win, MONITOR_DEFAULTTONEAREST);
MONITORINFO minfo = { sizeof(minfo) };
GetMonitorInfo(mon, &minfo);
// the 1:1 actual size WITH frame
w2 = source->x+FRAME*2;
h2 = source->y+FRAME*2;
cx = minfo.rcMonitor.right - minfo.rcMonitor.left;
cy = minfo.rcMonitor.bottom - minfo.rcMonitor.top;
switch (display_mode) {
case DISPLAY_actual: {
int cx,cy;
RECT rect;
// given the actual size, compute the ideal window size
// (which is either 1:1 or fullscreen) and center point
ideal_window_size(w2,h2, &w,&h, &x,&y);
// get the desktop size
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
ideal_window_size(w2,h2, &w,&h, &x,&y, cx,cy);
// if the window fits on the desktop
if (w <= cx && h <= cy) {
@ -1059,8 +1102,11 @@ void size_to_current(int maximize)
GetAdjustedWindowRect(win, &rect);
x = (rect.right + rect.left - w) >> 1;
y = (rect.top + rect.bottom - h) >> 1;
x = stb_clamp(x,0,cx-w);
y = stb_clamp(y,0,cy-h);
x = stb_clamp(x,minfo.rcMonitor.left,minfo.rcMonitor.right-w);
y = stb_clamp(y,minfo.rcMonitor.top,minfo.rcMonitor.bottom-h);
} else {
x += minfo.rcMonitor.left;
y += minfo.rcMonitor.top;
}
break;
}
@ -1069,8 +1115,11 @@ void size_to_current(int maximize)
if (maximize) {
// fullscreen, plus the frame around the edge
x = y = -FRAME;
w = GetSystemMetrics(SM_CXSCREEN) + FRAME*2;
h = GetSystemMetrics(SM_CYSCREEN) + FRAME*2;
w = cx + FRAME*2;
h = cy + FRAME*2;
x += minfo.rcMonitor.left;
y += minfo.rcMonitor.top;
} else {
// just use the current window
RECT rect;
@ -2078,7 +2127,7 @@ BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT imsg, WPARAM wparam, LPARAM lparam)
unsigned char curc[6];
int new_border;
int old_cubic = upsample_cubic;
memcpy(cur, alpha_background, 6);
memcpy(curc, alpha_background, 6);
// load the settings back out of the dialog box
for (i=0; i < 6; ++i)
@ -2192,9 +2241,12 @@ void performance_test(void)
// HINSTANCE is needed to launch the preferences dialog. Oh well!
HINSTANCE inst;
int sharpen=0;
int dummy_window=1;
int WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (dummy_window) return DefWindowProc (hWnd, uMsg, wParam, lParam);
switch (uMsg) {
case WM_CREATE: {
win = hWnd;
@ -2364,10 +2416,11 @@ int WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
#if ALLOW_RECOLORING
case '[': lmax = stb_clamp(lmax-1.0f/32, 0,1); clear_cache(0); advance(0); break;
case ']': lmax = stb_clamp(lmax+1.0f/32, 0,1); clear_cache(0); advance(0); break;
case '{': lmin = stb_clamp(lmin-1.0f/32, 0,1); clear_cache(0); advance(0); break;
case '}': lmin = stb_clamp(lmin+1.0f/32, 0,1); clear_cache(0); advance(0); break;
case ']': lmax = stb_clamp(lmax-1.0f/32, 0,2); clear_cache(0); advance(0); break;
case '[': lmax = stb_clamp(lmax+1.0f/32, 0,2); clear_cache(0); advance(0); break;
case '}': lmin = stb_clamp(lmin-1.0f/32, -1,1); clear_cache(0); advance(0); break;
case '{': lmin = stb_clamp(lmin+1.0f/32, -1,1); clear_cache(0); advance(0); break;
case 'Z': lmin = 0; lmax = 1.0; clear_cache(0); advance(0); break;
case 'm': mono = !mono; clear_cache(0); advance(0); break;
#endif
@ -2774,9 +2827,36 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
int x,y;
int w2 = source->x+FRAME*2, h2 = source->y+FRAME*2;
int w,h;
int cx,cy;
HMONITOR mon;
MONITORINFO minfo = { sizeof(minfo) };
// we have to create a window first to find out the correct monitor
// because i can't find any other way to discover this
hWnd = CreateWindow(szAppName, displayName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,1,1,
//x,y, w, h,
NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
// get the monitor it's on
mon = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
GetMonitorInfo(mon, &minfo);
DestroyWindow(hWnd);
cx = minfo.rcMonitor.right - minfo.rcMonitor.left;
cy = minfo.rcMonitor.bottom - minfo.rcMonitor.top;
//cx = GetSystemMetrics(SM_CXSCREEN);
//cy = GetSystemMetrics(SM_CYSCREEN);
// determine an initial window size, and resize
ideal_window_size(w2,h2, &w,&h, &x,&y);
ideal_window_size(w2,h2, &w,&h, &x,&y, cx,cy);
// if the size exactly matches, don't resize, just copy
if (w == source->x+FRAME*2 && h == source->y+FRAME*2) {
@ -2808,14 +2888,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
h -= FRAME*2;
}
// create the window
x += minfo.rcMonitor.left;
y += minfo.rcMonitor.top;
// now create the real window
dummy_window = 0;
hWnd = CreateWindow(szAppName, displayName,
WS_POPUP,
x,y, w, h,
NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
} // open brace for defining some temporary variables
// display the window
@ -2947,6 +3028,7 @@ void *image_resize_work(ImageProcess *q)
y = q->dy * j;
iy = (int) floor(y);
fy = (int) floor(255.9f*(y - iy));
if (nearest_neighbor) fy = 0; else
if (iy >= src->y-1) {
iy = src->y-2;
fy = 255;
@ -2963,6 +3045,7 @@ void *image_resize_work(ImageProcess *q)
#if BPP == 4
uint32 c00,c01,c10,c11,rb0,rb1,rb00,rb01,rb10,rb11,rb,g;
if (nearest_neighbor) x = 0;
c00 = *(uint32 *) s0;
c01 = *(uint32 *) (s0+4);
c10 = *(uint32 *) s1;
@ -2989,6 +3072,7 @@ void *image_resize_work(ImageProcess *q)
unsigned char v00,v01,v10,v11;
int v0,v1;
if (nearest_neighbor) x = 0;
v00 = s0[0]; v01 = s0[BPP+0]; v10 = s1[0]; v11 = s1[BPP+0];
v0 = (v00<<8) + x * (v01 - v00);
v1 = (v10<<8) + x * (v11 - v10);

View File

@ -1,3 +1,9 @@
Version 1.01: Release 1.01 (2012-01-17)
* bugfix: fix crash when closing preferences
* feature: if image is entire alpha=0, assume opaque
* feature: full-size expands on whichever monitor image is current on
* change: don't stretch full-size image across multiple monitors (#define ALLOW_MULTISCREEN for old behavior)
Version 1.0: Release 1
* feature: open a directory
* feature: sharpen when upscaling

View File

@ -193,6 +193,11 @@ SOURCE=..\imv.ico
# End Source File
# Begin Source File
SOURCE=..\misc.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\notes.txt
!IF "$(CFG)" == "stb_imv - Win32 Release"

View File

@ -1 +1 @@
set VERSION="1.0"
set VERSION="1.01"