diff -ruN a/src/IDocument.cxx b/src/IDocument.cxx --- a/src/IDocument.cxx 2009-09-06 17:32:59.381071647 +0800 +++ b/src/IDocument.cxx 2009-09-06 17:39:38.517291109 +0800 @@ -27,10 +27,11 @@ G_LOCK_DEFINE_STATIC (pageSearch); // Constants. -static const gdouble ZOOM_IN_FACTOR = 1.2; -static const gdouble ZOOM_IN_MAX = 4.0; -static const gdouble ZOOM_OUT_FACTOR = (1.0 / ZOOM_IN_FACTOR); -static const gdouble ZOOM_OUT_MAX = 0.05409; +static const gint MAX_ZOOM_STEPS = 19; +static const gdouble ZOOM_FACTORS[MAX_ZOOM_STEPS] = + { 0.1, 0.13, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.8, // zoom out + 1.0, // default + 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 8.0 }; // zoom in static const guint CACHE_SIZE = 3; /// This is the error domain that will be used to report Document's errors. @@ -148,6 +149,8 @@ m_Scale = 1.0f; m_Subject = NULL; m_Title = NULL; + + m_zoomStepsPerformed = 9; } /// @@ -1216,18 +1219,18 @@ gboolean IDocument::canZoomIn (void) { - return ( getZoom () * ZOOM_IN_FACTOR <= ZOOM_IN_MAX ); + return getZoom () < ZOOM_FACTORS[MAX_ZOOM_STEPS-1]; } /// /// @brief Checks if is possible to zoom out. /// -/// Checks if after zooming out the zoom level will be above the min level. +/// Checks if after zooming out the zoom level will be below the min level. /// gboolean IDocument::canZoomOut (void) { - return ( getZoom () * ZOOM_OUT_FACTOR >= ZOOM_OUT_MAX ); + return getZoom () > ZOOM_FACTORS[0]; } /// @@ -1251,8 +1254,15 @@ { if ( ABS (zoom - m_Scale) > 0.00001 ) { + gint idx; + gint lim = MAX_ZOOM_STEPS - 1; + G_LOCK (JobRender); - m_Scale = CLAMP (zoom, ZOOM_OUT_MAX, ZOOM_IN_MAX); + m_Scale = CLAMP (zoom, ZOOM_FACTORS[0], ZOOM_FACTORS[MAX_ZOOM_STEPS-1]); + for (idx = 1; idx < lim; ++idx) + if ( CLAMP ( m_Scale, ZOOM_FACTORS[idx-1], ZOOM_FACTORS[idx] ) + == m_Scale ) + m_zoomStepsPerformed = idx - 1; refreshCache (); G_UNLOCK (JobRender); notifyPageZoomed (); @@ -1270,10 +1280,7 @@ void IDocument::zoomIn (void) { - if (canZoomIn ()) - { - setZoom (getZoom () * ZOOM_IN_FACTOR); - } + zoomInOutWrapper(0); } /// @@ -1287,10 +1294,41 @@ void IDocument::zoomOut (void) { - if (canZoomOut ()) + zoomInOutWrapper(-1); +} + +/// +/// @brief Zooms In or Out +/// +/// Common routine for zoomIn() and zoomOut() to exclude code duplication when +/// making decision on value which should be added or to substracted to the +/// current zoom level +/// +/// @param zoomDirection Points whether to zoom in or zoom out the document. +/// +/// @see zoomIn() zoomOut() +/// +void +IDocument::zoomInOutWrapper (gint zoomDirection) +{ + if ( (zoomDirection < 0) ? canZoomOut () : canZoomIn () ) + { + gdouble currentScale = getZoom (); + + if ( ZOOM_FACTORS[m_zoomStepsPerformed] == currentScale ) + m_zoomStepsPerformed += (zoomDirection == 0) ? 1 : -1; + else { - setZoom (getZoom () * ZOOM_OUT_FACTOR); + gint idx; + gint lim = MAX_ZOOM_STEPS - 1; + + for ( idx = 1; idx < lim; ++idx ) + if ( CLAMP ( currentScale, ZOOM_FACTORS[idx-1], ZOOM_FACTORS[idx] ) + == currentScale ) + m_zoomStepsPerformed = idx + zoomDirection; } + setZoom ( ZOOM_FACTORS[m_zoomStepsPerformed] ); + } } /// diff -ruN a/src/IDocument.h b/src/IDocument.h --- a/src/IDocument.h 2009-09-06 17:32:59.540845309 +0800 +++ b/src/IDocument.h 2009-09-06 17:37:03.134071681 +0800 @@ -357,7 +357,7 @@ protected: static GQuark errorQuark; - + IDocument (void); void addPageToCache (gint pageNum); PageCache *getCachedPage (gint pageNum); @@ -412,6 +412,11 @@ gchar *m_Subject; /// The document's title. gchar *m_Title; + + private: + void zoomInOutWrapper (gint zoomDirection); + + gint m_zoomStepsPerformed; }; }