Permalink
Browse files

Partially fix bug scaling up from keywords mode.

Add error returns from SetViewModes and ScaleAndRotate.
Clarify some comments.
  • Loading branch information...
1 parent cbf802c commit 3814d4c54b0ee9a1e273bf157d64e3860ffedb9b @akkana committed Aug 19, 2011
Showing with 75 additions and 32 deletions.
  1. +14 −3 TODO
  2. +20 −8 gmain.c
  3. +9 −6 gwin.c
  4. +8 −7 pho.c
  5. +24 −8 pho.h
View
@@ -4,13 +4,24 @@ let me know!
BUGS:
-- EXIF rotation problems (maybe fixed)
+- "Error scaling up to 682788 x 512216: probably out of memory"
+ leaves pho in a state where it can't do anything else.
+ To reproduce: run in keywords mode and use = key.
+ Bad state is fixed; but why do we have an error scaling?
+ Okay, we understand that now, but it leaves a question:
+ what is the actual difference between PHO_SCALE_FIXED and
+ PHO_SCALE_SCREEN_RATIO ?
+
+- dismissing dialog on last image doesn't redraw covered area:
+ how to reproduce?
+
+- EXIF rotation problems (mostly fixed, may still be a few edge cases)
- Going from presentation mode to non-presentation mode,
we don't get an expose so we don't get a chance to check the
- frame size and adjust window size accordingly.
+ frame size and adjust window size accordingly. (fixed?)
-- Calling DrawImage too many times
+- Calling DrawImage too many times. (much improved, still not perfect)
- Show cursor in text fields in keywords dialog (gtk bug, probably can't fix)
View
@@ -34,6 +34,9 @@ static int ModeForScaling(int oldmode)
case PHO_SCALE_FULLSIZE:
return PHO_SCALE_IMG_RATIO;
+ case PHO_SCALE_FIXED:
+ return PHO_SCALE_FIXED;
+
case PHO_SCALE_NORMAL:
case PHO_SCALE_FULLSCREEN:
default:
@@ -112,6 +115,21 @@ static void RunPhoCommand()
}
}
+void TryScale(float times)
+{
+ /* Save the view modes, in case this fails */
+ int saveScaleMode = gScaleMode;
+ double saveScaleRatio = gScaleRatio;
+ int saveDisplayMode = gDisplayMode;
+
+ if (SetViewModes(gDisplayMode, ModeForScaling(gScaleMode),
+ gScaleRatio * times) == 0)
+ return;
+
+ /* Oops! It didn't work. Try to reset back to previous settings */
+ SetViewModes(saveDisplayMode, saveScaleMode, saveScaleRatio);
+}
+
gint HandleGlobalKeys(GtkWidget* widget, GdkEventKey* event)
{
if (gDebug) printf("\nKey event\n");
@@ -204,16 +222,12 @@ gint HandleGlobalKeys(GtkWidget* widget, GdkEventKey* event)
case GDK_plus:
case GDK_KP_Add:
case GDK_equal:
- SetViewModes(gDisplayMode, ModeForScaling(gScaleMode),
- gScaleRatio * 2.);
- ScaleAndRotate(gCurImage, 0);
+ TryScale(2.);
return TRUE;
case GDK_minus:
case GDK_slash:
case GDK_KP_Subtract:
- SetViewModes(gDisplayMode, ModeForScaling(gScaleMode),
- gScaleRatio / 2.);
- ScaleAndRotate(gCurImage, 0);
+ TryScale(.5);
return TRUE;
case GDK_g: /* start gimp, or some other app */
RunPhoCommand();
@@ -222,8 +236,6 @@ gint HandleGlobalKeys(GtkWidget* widget, GdkEventKey* event)
ToggleInfo();
return TRUE;
case GDK_k:
- //SetViewModes(PHO_DISPLAY_KEYWORDS, PHO_SCALE_SCREEN_RATIO, .5);
- //SetViewModes(PHO_DISPLAY_KEYWORDS, PHO_SCALE_FIXED, 0.0);
ToggleKeywordsMode();
return TRUE;
case GDK_o:
View
@@ -191,11 +191,11 @@ double FracOfScreenSize() {
/* XXX Pho really needs a state table defining which commands
* take which state to which new state!
*/
-void SetViewModes(int dispmode, int scalemode, double scalefactor)
+int SetViewModes(int dispmode, int scalemode, double scalefactor)
{
if (dispmode == gDisplayMode && scalemode == gScaleMode
&& scalefactor == gScaleRatio)
- return;
+ return 0;
if (gDebug)
printf("SetViewModes(%d, %d, %f (was %d, %d, %f)\n",
dispmode, scalemode, scalefactor,
@@ -204,13 +204,13 @@ void SetViewModes(int dispmode, int scalemode, double scalefactor)
if (dispmode == PHO_DISPLAY_KEYWORDS) {
if (gDisplayMode != PHO_DISPLAY_KEYWORDS) {
/* switching to keyword mode from some other mode */
- //gScaleMode = PHO_SCALE_SCREEN_RATIO;
- //gScaleRatio = .5;
gScaleMode = PHO_SCALE_FIXED;
gScaleRatio = FracOfScreenSize();
+ /*
if (gDebug)
printf("Showing keywords dialog from SetViewModes\n");
- //ShowKeywordsDialog();
+ ShowKeywordsDialog();
+ */
}
else {
/* staying in keywords mode but changing some other factor:
@@ -263,13 +263,16 @@ void SetViewModes(int dispmode, int scalemode, double scalefactor)
* XXX unfortunately this doesn't work when changing from keywords
* to fullscreen/normal.
*/
- ScaleAndRotate(gCurImage, 0);
+ int ret = ScaleAndRotate(gCurImage, 0);
+ if (ret != 0) return ret;
MaybeMove();
}
if (gDisplayMode == PHO_DISPLAY_KEYWORDS) {
ShowKeywordsDialog();
}
+
+ return 0;
}
/* DrawImage is called from the expose callback.
View
@@ -311,7 +311,7 @@ static void ScaleToFit(int *width, int *height,
*
* degrees is the increment from the current rotation (curRot).
*/
-void ScaleAndRotate(PhoImage* img, int degrees)
+int ScaleAndRotate(PhoImage* img, int degrees)
{
#define true_width img->trueWidth
#define true_height img->trueHeight
@@ -372,7 +372,9 @@ void ScaleAndRotate(PhoImage* img, int degrees)
max_height = gMonitorHeight;
}
- /* If we're in fixed mode, make sure we've set the scale ratio */
+ /* If we're in fixed mode, make sure we've set the "scale ratio"
+ * to the screen size:
+ */
if (gScaleMode == PHO_SCALE_FIXED && gScaleRatio == 0.0)
gScaleRatio = FracOfScreenSize();
@@ -515,8 +517,6 @@ void ScaleAndRotate(PhoImage* img, int degrees)
if (degrees != 0 &&
(new_width > img->curWidth || new_height > img->curHeight)) {
if (gDebug) printf("Rotating before scaling up\n");
- printf("Will be scaling from %dx%d to %dx%d\n",
- img->curWidth, img->curHeight, new_width, new_height);
RotateImage(img, degrees);
degrees = 0; /* finished with rotation */
}
@@ -537,13 +537,13 @@ void ScaleAndRotate(PhoImage* img, int degrees)
* Later: now it's documented. Whew.
*/
if (!newimage || gdk_pixbuf_get_width(newimage) < 1) {
- printf("\007Error scaling up to %d x %d: probably out of memory\n",
- new_width, new_height);
if (newimage)
gdk_pixbuf_unref(newimage);
+ printf("\007Error scaling from %d x %d to %d x %d: probably out of memory\n",
+ img->curWidth, img->curHeight, new_width, new_height);
Prompt("Couldn't scale up: probably out of memory", "Bummer", 0,
"\n ", "");
- return;
+ return -1;
}
if (gDebug)
printf("Scale from %dx%d = %dx%d to %dx%d = %dx%d\n",
@@ -568,6 +568,7 @@ void ScaleAndRotate(PhoImage* img, int degrees)
* changes in the window size or position.
*/
PrepareWindow();
+ return 0;
}
PhoImage* NewPhoImage(char* fnam)
View
@@ -52,33 +52,48 @@ extern GdkPixbuf* gImage;
extern int gDebug; /* debugging messages */
-/* ************** Scaling modes ************** */
+/* ************** (Way too many) Scaling Modes ************** */
+
/* Normal: show at full size if it fits on screen, otherwise size to screen. */
#define PHO_SCALE_NORMAL 0
+
/* Full Screen: make it as big as necessary to fill the screen,
- * even if that means scaling up.
+ * even if that means scaling up. Good for e.g. small comics.
*/
#define PHO_SCALE_FULLSCREEN 1
+
/* Full Size: show at full size (1:1 pixel) even if it's bigger
* than the screen.
*/
#define PHO_SCALE_FULLSIZE 2
- /* IMG_RATIO: pho will scale the image to an absolute multiple of
+
+/* IMG_RATIO: pho will scale the image to an absolute multiple of
* the true image size.
*/
#define PHO_SCALE_IMG_RATIO 4
- /* SCREEN_RATIO: pho will show the image no larger than the screen
+
+/* SCREEN_RATIO: pho will show the image no larger than the screen
* size times gScaleRatio (i.e. when ratio==1.0, same as normal mode).
*/
#define PHO_SCALE_SCREEN_RATIO 5
- /* FIXED: try to make the long dimension of the image be no bigger
+
+/* FIXED: try to make the long dimension of the image be no bigger
* than gScaleRatio. If the image is naturally smaller, show it at
* its normal size.
*/
#define PHO_SCALE_FIXED 6
extern int gScaleMode;
-extern double gScaleRatio; /* only used for PHO_SCALE_*_RATIO */
+
+/* Scale Ratio is used in two ways: for PHO_SCALE_*_RATIO, it's a
+ * ratio like 1.0, 0.5, 2.0 to indicate how we're scaling compared
+ * to screen size or original image size.
+ * But in PHO_SCALE_FIXED mode, it's overloaded to store a size
+ * slightly less than the smaller of the two screen dimensions:
+ * the size in which either dimension of the image has to fit,
+ * regardless of rotation.
+ */
+extern double gScaleRatio;
/* ************** Display modes ************** */
#define PHO_DISPLAY_NORMAL 0
@@ -90,7 +105,7 @@ extern int gDisplayMode;
* other housekeeping and is the recommended way to set ANY
* of the three.
*/
-extern void SetViewModes(int dispmode, int scalemode, double scalefactor);
+extern int SetViewModes(int dispmode, int scalemode, double scalefactor);
extern double FracOfScreenSize();
/* ************** List maintenance functions ************** */
@@ -120,12 +135,13 @@ extern void SetKeywordsDialogToggle(int which, int newval);
/* Other routines that need to be public */
extern void PrepareWindow();
extern void DrawImage();
-extern void ScaleAndRotate(PhoImage* img, int degrees);
+extern int ScaleAndRotate(PhoImage* img, int degrees);
extern PhoImage* AddImage(char* filename);
extern void DeleteImage(PhoImage* img);
extern void ClearImageList();
extern void ChangeWorkingFileSet();
+extern void ToggleKeywordsMode();
extern void Usage();
extern void VerboseHelp();

0 comments on commit 3814d4c

Please sign in to comment.