Пример #1
0
    def get_virtual_double_page(self, page=None):
        """Return True if the current state warrants use of virtual
        double page mode (i.e. if double page mode is on, the corresponding
        preference is set, and one of the two images that should normally
        be displayed has a width that exceeds its height), or if currently
        on the first page.
        """
        if page == None:
            page = self.get_current_page()

        if (page == 1 and
            prefs['virtual double page for fitting images'] & constants.SHOW_DOUBLE_AS_ONE_TITLE and
            self._window.filehandler.archive_type is not None):
            return True

        if (not prefs['default double page'] or
            not prefs['virtual double page for fitting images'] & constants.SHOW_DOUBLE_AS_ONE_WIDE or
            page == self.get_number_of_pages()):
            return False

        for page in (page, page + 1):
            if not self.page_is_available(page):
                return False
            pixbuf = self._get_pixbuf(page - 1)
            width, height = pixbuf.get_width(), pixbuf.get_height()
            if prefs['auto rotate from exif']:
                rotation = image_tools.get_implied_rotation(pixbuf)
                assert rotation in (0, 90, 180, 270)
                if rotation in (90, 270):
                    width, height = height, width
            if width > height:
                return True

        return False
Пример #2
0
    def get_virtual_double_page(self, page=None):
        """Return True if the current state warrants use of virtual
        double page mode (i.e. if double page mode is on, the corresponding
        preference is set, and one of the two images that should normally
        be displayed has a width that exceeds its height), or if currently
        on the first page.
        """
        if page == None:
            page = self.get_current_page()

        if (page == 1 and
            prefs['virtual double page for fitting images'] & constants.SHOW_DOUBLE_AS_ONE_TITLE and
            self._window.filehandler.archive_type is not None):
            return True

        if (not prefs['default double page'] or
            not prefs['virtual double page for fitting images'] & constants.SHOW_DOUBLE_AS_ONE_WIDE or
            page == self.get_number_of_pages()):
            return False

        for page in (page, page + 1):
            if not self.page_is_available(page):
                return False
            pixbuf = self._get_pixbuf(page - 1)
            width, height = pixbuf.get_width(), pixbuf.get_height()
            if prefs['auto rotate from exif']:
                rotation = image_tools.get_implied_rotation(pixbuf)
                assert rotation in (0, 90, 180, 270)
                if rotation in (90, 270):
                    width, height = height, width
            if width > height:
                return True

        return False
Пример #3
0
    def _get_pixbuf_rotation(self, pixbuf, no_autorotation=False):
        """ Determines if a pixbuf must be rotated before being displayed.
        Returns the degree of rotation (0, 90, 180, 270). """
        
        width, height = pixbuf.get_width(), pixbuf.get_height()
        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(pixbuf)
            rotation = rotation % 360

        if (height > width and
            not no_autorotation and
            prefs['auto rotate depending on size'] in
                (constants.AUTOROTATE_HEIGHT_90, constants.AUTOROTATE_HEIGHT_270)):

            if prefs['auto rotate depending on size'] == constants.AUTOROTATE_HEIGHT_90:
                rotation = 90
            else:
                rotation = 270
        elif (width > height and
              not no_autorotation and
              prefs['auto rotate depending on size'] in
                (constants.AUTOROTATE_WIDTH_90, constants.AUTOROTATE_WIDTH_270)):

            if prefs['auto rotate depending on size'] == constants.AUTOROTATE_WIDTH_90:
                rotation = 90
            else:
                rotation = 270

        return rotation
Пример #4
0
    def _get_pixbuf_rotation(self, pixbuf, no_autorotation=False):
        """ Determines if a pixbuf must be rotated before being displayed.
        Returns the degree of rotation (0, 90, 180, 270). """

        width, height = pixbuf.get_width(), pixbuf.get_height()
        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(pixbuf)
            rotation = rotation % 360

        if (height > width and not no_autorotation
                and prefs['auto rotate depending on size']
                in (constants.AUTOROTATE_HEIGHT_90,
                    constants.AUTOROTATE_HEIGHT_270)):

            if prefs[
                    'auto rotate depending on size'] == constants.AUTOROTATE_HEIGHT_90:
                rotation = 90
            else:
                rotation = 270
        elif (width > height and not no_autorotation
              and prefs['auto rotate depending on size']
              in (constants.AUTOROTATE_WIDTH_90,
                  constants.AUTOROTATE_WIDTH_270)):

            if prefs[
                    'auto rotate depending on size'] == constants.AUTOROTATE_WIDTH_90:
                rotation = 90
            else:
                rotation = 270

        return rotation
Пример #5
0
 def test_get_implied_rotation(self):
     for name in (
         # JPEG.
         'landscape-exif-270-rotation.jpg',
         'landscape-no-exif.jpg',
         'portrait-exif-180-rotation.jpg',
         'portrait-no-exif.jpg',
         # PNG.
         'landscape-exif-270-rotation.png',
         'landscape-no-exif.png',
         'portrait-exif-180-rotation.png',
         'portrait-no-exif.png',
     ):
         image = get_test_image(name)
         pixbuf = image_tools.load_pixbuf(get_image_path(name))
         rotation = image_tools.get_implied_rotation(pixbuf)
         self.assertEqual(rotation, image.rotation,
                          msg='get_implied_rotation(%s) failed: %u instead of %u'
                          % (image, rotation, image.rotation))
Пример #6
0
 def test_get_implied_rotation(self):
     for name in (
         # JPEG.
         'landscape-exif-270-rotation.jpg',
         'landscape-no-exif.jpg',
         'portrait-exif-180-rotation.jpg',
         'portrait-no-exif.jpg',
         # PNG.
         'landscape-exif-270-rotation.png',
         'landscape-no-exif.png',
         'portrait-exif-180-rotation.png',
         'portrait-no-exif.png',
     ):
         image = get_test_image(name)
         pixbuf = image_tools.load_pixbuf(get_image_path(name))
         rotation = image_tools.get_implied_rotation(pixbuf)
         self.assertEqual(rotation, image.rotation,
                          msg='get_implied_rotation(%s) failed: %u instead of %u'
                          % (image, rotation, image.rotation))
Пример #7
0
    def _add_subpixbuf(self, canvas, x, y, image_size, source_pixbuf):
        '''Copy a subpixbuf from <source_pixbuf> to <canvas> as it should
        be in the lens if the coordinates <x>, <y> are the mouse pointer
        position on the main window layout area.

        The displayed image (scaled from the <source_pixbuf>) must have
        size <image_size>.
        '''
        # Prevent division by zero exceptions further down
        if not image_size[0]:
            return

        # FIXME This merely prevents Errors being raised if source_pixbuf is an
        # animation. The result might be broken, though, since animation,
        # rotation etc. might not match or will be ignored:
        source_pixbuf = image_tools.static_image(source_pixbuf)

        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(source_pixbuf)
            rotation = rotation % 360

        if rotation in [90, 270]:
            scale = float(source_pixbuf.get_height()) / image_size[0]
        else:
            scale = float(source_pixbuf.get_width()) / image_size[0]

        x *= scale
        y *= scale

        source_mag = prefs['lens magnification'] / scale
        width = height = prefs['lens size'] / source_mag

        paste_left = x > width / 2
        paste_top = y > height / 2
        dest_x = max(0, int(math.ceil((width / 2 - x) * source_mag)))
        dest_y = max(0, int(math.ceil((height / 2 - y) * source_mag)))

        if rotation == 90:
            x, y = y, source_pixbuf.get_height() - x
        elif rotation == 180:
            x = source_pixbuf.get_width() - x
            y = source_pixbuf.get_height() - y
        elif rotation == 270:
            x, y = source_pixbuf.get_width() - y, x
        if prefs['horizontal flip']:
            if rotation in (90, 270):
                y = source_pixbuf.get_height() - y
            else:
                x = source_pixbuf.get_width() - x
        if prefs['vertical flip']:
            if rotation in (90, 270):
                x = source_pixbuf.get_width() - x
            else:
                y = source_pixbuf.get_height() - y

        src_x = x - width / 2
        src_y = y - height / 2
        if src_x < 0:
            width += src_x
            src_x = 0
        if src_y < 0:
            height += src_y
            src_y = 0
        width = max(0, min(source_pixbuf.get_width() - src_x, width))
        height = max(0, min(source_pixbuf.get_height() - src_y, height))
        if width < 1 or height < 1:
            return

        subpixbuf = source_pixbuf.new_subpixbuf(int(src_x), int(src_y),
                                                int(width), int(height))
        subpixbuf = subpixbuf.scale_simple(
            int(math.ceil(source_mag * subpixbuf.get_width())),
            int(math.ceil(source_mag * subpixbuf.get_height())),
            prefs['scaling quality'])

        if rotation == 90:
            subpixbuf = subpixbuf.rotate_simple(Gdk.PIXBUF_ROTATE_CLOCKWISE)
        elif rotation == 180:
            subpixbuf = subpixbuf.rotate_simple(Gdk.PIXBUF_ROTATE_UPSIDEDOWN)
        elif rotation == 270:
            subpixbuf = subpixbuf.rotate_simple(
                Gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE)
        if prefs['horizontal flip']:
            subpixbuf = subpixbuf.flip(horizontal=True)
        if prefs['vertical flip']:
            subpixbuf = subpixbuf.flip(horizontal=False)

        subpixbuf = self._window.enhancer.enhance(subpixbuf)

        if paste_left:
            dest_x = 0
        else:
            dest_x = min(canvas.get_width() - subpixbuf.get_width(), dest_x)
        if paste_top:
            dest_y = 0
        else:
            dest_y = min(canvas.get_height() - subpixbuf.get_height(), dest_y)

        if subpixbuf.get_has_alpha(
        ) and prefs['checkered bg for transparent images']:
            subpixbuf = subpixbuf.composite_color_simple(
                subpixbuf.get_width(), subpixbuf.get_height(),
                GdkPixbuf.InterpType.NEAREST, 255, 8, 0x777777, 0x999999)

        subpixbuf.copy_area(0, 0, subpixbuf.get_width(),
                            subpixbuf.get_height(), canvas, dest_x, dest_y)
Пример #8
0
    def _add_subpixbuf(self, canvas, x, y, image_size, source_pixbuf):
        """Copy a subpixbuf from <source_pixbuf> to <canvas> as it should
        be in the lens if the coordinates <x>, <y> are the mouse pointer
        position on the main window layout area.

        The displayed image (scaled from the <source_pixbuf>) must have
        size <image_size>.
        """
        # Prevent division by zero exceptions further down
        if not image_size[0]:
            return

        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(source_pixbuf)
            rotation = rotation % 360

        if rotation in [90, 270]:
            scale = float(source_pixbuf.get_height()) / image_size[0]
        else:
            scale = float(source_pixbuf.get_width()) / image_size[0]

        x *= scale
        y *= scale

        source_mag = prefs['lens magnification'] / scale
        width = height = prefs['lens size'] / source_mag

        paste_left = x > width / 2
        paste_top = y > height / 2
        dest_x = max(0, int(math.ceil((width / 2 - x) * source_mag)))
        dest_y = max(0, int(math.ceil((height / 2 - y) * source_mag)))

        if rotation == 90:
            x, y = y, source_pixbuf.get_height() - x
        elif rotation == 180:
            x = source_pixbuf.get_width() - x
            y = source_pixbuf.get_height() - y
        elif rotation == 270:
            x, y = source_pixbuf.get_width() - y, x
        if prefs['horizontal flip']:
            if rotation in (90, 270):
                y = source_pixbuf.get_height() - y
            else:
                x = source_pixbuf.get_width() - x
        if prefs['vertical flip']:
            if rotation in (90, 270):
                x = source_pixbuf.get_width() - x
            else:
                y = source_pixbuf.get_height() - y

        src_x = x - width / 2
        src_y = y - height / 2
        if src_x < 0:
            width += src_x
            src_x = 0
        if src_y < 0:
            height += src_y
            src_y = 0
        width = max(0, min(source_pixbuf.get_width() - src_x, width))
        height = max(0, min(source_pixbuf.get_height() - src_y, height))
        if width < 1 or height < 1:
            return

        subpixbuf = source_pixbuf.subpixbuf(int(src_x), int(src_y),
            int(width), int(height))
        subpixbuf = subpixbuf.scale_simple(
            int(math.ceil(source_mag * subpixbuf.get_width())),
            int(math.ceil(source_mag * subpixbuf.get_height())),
            prefs['scaling quality'])

        if rotation == 90:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_CLOCKWISE)
        elif rotation == 180:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_UPSIDEDOWN)
        elif rotation == 270:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE)
        if prefs['horizontal flip']:
            subpixbuf = subpixbuf.flip(horizontal=True)
        if prefs['vertical flip']:
            subpixbuf = subpixbuf.flip(horizontal=False)

        subpixbuf = self._window.enhancer.enhance(subpixbuf)

        if paste_left:
            dest_x = 0
        else:
            dest_x = min(canvas.get_width() - subpixbuf.get_width(), dest_x)
        if paste_top:
            dest_y = 0
        else:
            dest_y = min(canvas.get_height() - subpixbuf.get_height(), dest_y)

        if subpixbuf.get_has_alpha() and prefs['checkered bg for transparent images']:
            subpixbuf = subpixbuf.composite_color_simple(subpixbuf.get_width(), subpixbuf.get_height(),
                gtk.gdk.INTERP_NEAREST, 255, 8, 0x777777, 0x999999)

        subpixbuf.copy_area(0, 0, subpixbuf.get_width(),
            subpixbuf.get_height(), canvas, dest_x, dest_y)
Пример #9
0
    def _draw_image(self, at_bottom, scroll):
        self._display_active_widgets()

        while gtk.events_pending():
            gtk.main_iteration(False)

        if not self.filehandler.file_loaded:
            self._waiting_for_redraw = False
            return False

        area_width, area_height = self.get_visible_area_size()

        if prefs['zoom mode'] == constants.ZOOM_MODE_HEIGHT:
            scaled_width = -1
        else:
            scaled_width = area_width

        if prefs['zoom mode'] == constants.ZOOM_MODE_WIDTH:
            scaled_height = -1
        else:
            scaled_height = area_height

        scale_up = prefs['stretch']
        self.is_virtual_double_page = \
            self.imagehandler.get_virtual_double_page()

        skip_pixbuf = not self.imagehandler.page_is_available()

        if self.displayed_double() and not skip_pixbuf:
            left_pixbuf, right_pixbuf = self.imagehandler.get_pixbufs()
            if self.is_manga_mode:
                right_pixbuf, left_pixbuf = left_pixbuf, right_pixbuf
            left_unscaled_x = left_pixbuf.get_width()
            left_unscaled_y = left_pixbuf.get_height()
            right_unscaled_x = right_pixbuf.get_width()
            right_unscaled_y = right_pixbuf.get_height()

            left_rotation = prefs['rotation']
            right_rotation = prefs['rotation']

            if prefs['auto rotate from exif']:
                left_rotation += image_tools.get_implied_rotation(left_pixbuf)
                left_rotation = left_rotation % 360
                right_rotation += image_tools.get_implied_rotation(right_pixbuf)
                right_rotation = right_rotation % 360

            if prefs['zoom mode'] == constants.ZOOM_MODE_MANUAL:

                if left_rotation in (90, 270):
                    total_width = left_unscaled_y
                    total_height = left_unscaled_x
                else:
                    total_width = left_unscaled_x
                    total_height = left_unscaled_y

                if right_rotation in (90, 270):
                    total_width += right_unscaled_y
                    total_height += right_unscaled_x
                else:
                    total_width += right_unscaled_x
                    total_height += right_unscaled_y

                total_width += 2  # For the 2 px gap between images.
                scaled_width = int(self._manual_zoom * total_width / 100)
                scaled_height = int(self._manual_zoom * total_height / 100)
                scale_up = True

            left_pixbuf, right_pixbuf = image_tools.fit_2_in_rectangle(
                left_pixbuf, right_pixbuf, scaled_width, scaled_height,
                scale_up=scale_up, rotation1=left_rotation,
                rotation2=right_rotation)

            if prefs['horizontal flip']:
                left_pixbuf = left_pixbuf.flip(horizontal=True)
                right_pixbuf = right_pixbuf.flip(horizontal=True)

            if prefs['vertical flip']:
                left_pixbuf = left_pixbuf.flip(horizontal=False)
                right_pixbuf = right_pixbuf.flip(horizontal=False)

            left_pixbuf = self.enhancer.enhance(left_pixbuf)
            right_pixbuf = self.enhancer.enhance(right_pixbuf)

            self.left_image.set_from_pixbuf(left_pixbuf)
            self.right_image.set_from_pixbuf(right_pixbuf)

            x_padding = (area_width - left_pixbuf.get_width() -
                right_pixbuf.get_width()) / 2
            y_padding = (area_height - max(left_pixbuf.get_height(),
                right_pixbuf.get_height())) / 2

            if left_rotation in (90, 270):
                left_scale_percent = (100.0 * left_pixbuf.get_width() /
                    left_unscaled_y)
            else:
                left_scale_percent = (100.0 * left_pixbuf.get_width() /
                    left_unscaled_x)

            if right_rotation in (90, 270):
                right_scale_percent = (100.0 * right_pixbuf.get_width() /
                    right_unscaled_y)
            else:
                right_scale_percent = (100.0 * right_pixbuf.get_width() /
                    right_unscaled_x)

            self.statusbar.set_resolution(
                (left_unscaled_x, left_unscaled_y, left_scale_percent),
                (right_unscaled_x, right_unscaled_y, right_scale_percent))

        elif not skip_pixbuf:
            pixbuf = self.imagehandler.get_pixbufs(single=True)[ 0 ]
            unscaled_x = pixbuf.get_width()
            unscaled_y = pixbuf.get_height()

            rotation = prefs['rotation']
            if prefs['auto rotate from exif']:
                rotation += image_tools.get_implied_rotation(pixbuf)
                rotation = rotation % 360

            if prefs['zoom mode'] == constants.ZOOM_MODE_MANUAL:
                # If 'Scale small images' is true, scale up the image's base size
                scale_x = max(scale_up and scaled_width or unscaled_x, unscaled_x)
                scale_y = max(scale_up and scaled_height or unscaled_y, unscaled_y)
                scaled_width = int(self._manual_zoom * scale_x / 100)
                scaled_height = int(self._manual_zoom * scale_y / 100)

                if rotation in (90, 270):
                    scaled_width, scaled_height = scaled_height, scaled_width

                scale_up = True

            pixbuf = image_tools.fit_in_rectangle(pixbuf, scaled_width,
                scaled_height, scale_up=scale_up, rotation=rotation)

            if prefs['horizontal flip']:
                pixbuf = pixbuf.flip(horizontal=True)
            if prefs['vertical flip']:
                pixbuf = pixbuf.flip(horizontal=False)

            pixbuf = self.enhancer.enhance(pixbuf)

            self.left_image.set_from_pixbuf(pixbuf)
            self.right_image.clear()

            x_padding = (area_width - pixbuf.get_width()) / 2
            y_padding = (area_height - pixbuf.get_height()) / 2

            if rotation in (90, 270):
                scale_percent = 100.0 * pixbuf.get_width() / unscaled_y
            else:
                scale_percent = 100.0 * pixbuf.get_width() / unscaled_x

            self.statusbar.set_resolution((unscaled_x, unscaled_y,
                scale_percent))

        if prefs['smart bg'] and not skip_pixbuf:

            bg_colour = self.imagehandler.get_pixbuf_auto_background(
                    not self.displayed_double())
            self.set_bg_colour(bg_colour)

            if prefs['smart thumb bg'] and prefs['show thumbnails']:
                self.thumbnailsidebar.change_thumbnail_background_color(bg_colour)

        elif prefs['smart thumb bg'] and prefs['show thumbnails'] and not skip_pixbuf:

            bg_colour = image_tools.get_most_common_edge_colour(
                            self.left_image.get_pixbuf())

            self.thumbnailsidebar.change_thumbnail_background_color(bg_colour)

        if not skip_pixbuf:
            self._image_box.window.freeze_updates()
            self._main_layout.move(self._image_box, max(0, x_padding),
                max(0, y_padding))

            self.left_image.show()

            if self.displayed_double():
                self.right_image.show()
            else:
                self.right_image.hide()

            self._main_layout.set_size(*self._image_box.size_request())

            if scroll:
                if at_bottom:
                    self.scroll_to_fixed(horiz='endsecond', vert='bottom')
                else:
                    self.scroll_to_fixed(horiz='startfirst', vert='top')

            self._image_box.window.thaw_updates()
        else:
            # If the pixbuf for the current page(s) isn't available,
            # hide both images to clear any old pixbufs.
            self.left_image.hide()
            self.right_image.hide()

        self._update_page_information()
        self._waiting_for_redraw = False

        while gtk.events_pending():
            gtk.main_iteration(False)

        return False
Пример #10
0
    def _draw_image(self, scroll_to):

        self._update_toggles_visibility()

        self.osd.clear()

        if not self.filehandler.file_loaded:
            self._clear_main_area()
            self._waiting_for_redraw = False
            return False

        if self.imagehandler.page_is_available():
            distribution_axis = constants.DISTRIBUTION_AXIS
            alignment_axis = constants.ALIGNMENT_AXIS
            pixbuf_count = 2 if self.displayed_double(
            ) else 1  # XXX limited to at most 2 pages
            pixbuf_list = list(self.imagehandler.get_pixbufs(pixbuf_count))
            do_not_transform = [
                image_tools.disable_transform(x) for x in pixbuf_list
            ]
            size_list = [[pixbuf.get_width(),
                          pixbuf.get_height()] for pixbuf in pixbuf_list]

            if self.is_manga_mode:
                orientation = constants.MANGA_ORIENTATION
            else:
                orientation = constants.WESTERN_ORIENTATION

            # Rotation handling:
            # - apply Exif rotation on individual images
            # - apply automatic rotation (size based) on whole page
            # - apply manual rotation on whole page
            if prefs['auto rotate from exif']:
                rotation_list = [
                    image_tools.get_implied_rotation(pixbuf)
                    for pixbuf in pixbuf_list
                ]
            else:
                rotation_list = [0] * len(pixbuf_list)
            virtual_size = [0, 0]
            for i in range(pixbuf_count):
                if rotation_list[i] in (90, 270):
                    size_list[i].reverse()
                size = size_list[i]
                virtual_size[distribution_axis] += size[distribution_axis]
                virtual_size[alignment_axis] = max(
                    virtual_size[alignment_axis], size[alignment_axis])
            rotation = self._get_size_rotation(*virtual_size)
            rotation = (rotation + prefs['rotation']) % 360
            if rotation in (90, 270):
                distribution_axis, alignment_axis = alignment_axis, distribution_axis
                orientation = list(orientation)
                orientation.reverse()
                for i in range(pixbuf_count):
                    size_list[i].reverse()
            if rotation in (180, 270):
                orientation = tools.vector_opposite(orientation)
            for i in range(pixbuf_count):
                rotation_list[i] = (rotation_list[i] + rotation) % 360
            if prefs['vertical flip'] and rotation in (90, 270):
                orientation = tools.vector_opposite(orientation)
            if prefs['horizontal flip'] and rotation in (0, 180):
                orientation = tools.vector_opposite(orientation)

            viewport_size = ()  # dummy
            expand_area = False
            scrollbar_requests = [False] * len(self._scroll)
            # Visible area size is recomputed depending on scrollbar visibility
            while True:
                self._show_scrollbars(scrollbar_requests)
                new_viewport_size = self.get_visible_area_size()
                if new_viewport_size == viewport_size:
                    break
                viewport_size = new_viewport_size
                zoom_dummy_size = list(viewport_size)
                dasize = zoom_dummy_size[distribution_axis] - \
                    self._spacing * (pixbuf_count - 1)
                if dasize <= 0:
                    dasize = 1
                zoom_dummy_size[distribution_axis] = dasize
                scaled_sizes = self.zoom.get_zoomed_size(
                    size_list, zoom_dummy_size, distribution_axis,
                    do_not_transform)
                self.layout = layout.FiniteLayout(scaled_sizes, viewport_size,
                                                  orientation, self._spacing,
                                                  expand_area,
                                                  distribution_axis,
                                                  alignment_axis)
                union_scaled_size = self.layout.get_union_box().get_size()
                scrollbar_requests = [(old or new) for old, new in zip(
                    scrollbar_requests,
                    tools.smaller(viewport_size, union_scaled_size))]
                if len(tuple(filter(
                        None, scrollbar_requests))) > 1 and not expand_area:
                    expand_area = True
                    viewport_size = ()  # start anew

            for i in range(pixbuf_count):
                pixbuf_list[i] = image_tools.fit_pixbuf_to_rectangle(
                    pixbuf_list[i], scaled_sizes[i], rotation_list[i])

            for i in range(pixbuf_count):
                pixbuf_list[i] = image_tools.trans_pixbuf(
                    pixbuf_list[i],
                    flip=prefs['vertical flip'],
                    flop=prefs['horizontal flip'])
                pixbuf_list[i] = self.enhancer.enhance(pixbuf_list[i])

            for i in range(pixbuf_count):
                image_tools.set_from_pixbuf(self.images[i], pixbuf_list[i])

            resolutions = [
                (*size, scaled_size[0] / size[0])
                for scaled_size, size in zip(scaled_sizes, size_list)
            ]

            if self.is_manga_mode:
                resolutions.reverse()
            self.statusbar.set_resolution(resolutions)
            self.statusbar.update()

            smartbg = prefs['smart bg']
            smartthumbbg = prefs['show thumbnails'] and prefs['smart thumb bg']
            if smartbg or smartthumbbg:
                bg_color = self.imagehandler.get_pixbuf_auto_background(
                    pixbuf_count)
                if smartbg:
                    self.set_bg_color(bg_color)
                if smartthumbbg:
                    self.thumbnailsidebar.change_thumbnail_background_color(
                        bg_color)

            self._main_layout.get_bin_window().freeze_updates()

            self._main_layout.set_size(*union_scaled_size)
            content_boxes = self.layout.get_content_boxes()
            for i in range(pixbuf_count):
                self._main_layout.move(self.images[i],
                                       *content_boxes[i].get_position())

            for i in range(pixbuf_count):
                self.images[i].show()
            for i in range(pixbuf_count, len(self.images)):
                self.images[i].hide()

            # Reset orientation so scrolling behaviour is sane.
            if self.is_manga_mode:
                self.layout.set_orientation(constants.MANGA_ORIENTATION)
            else:
                self.layout.set_orientation(constants.WESTERN_ORIENTATION)

            if scroll_to is not None:
                destination = (scroll_to, ) * 2
                if constants.SCROLL_TO_START == scroll_to:
                    index = constants.FIRST_INDEX
                elif constants.SCROLL_TO_END == scroll_to:
                    index = constants.LAST_INDEX
                else:
                    index = None
                self.scroll_to_predefined(destination, index)

            self._main_layout.get_bin_window().thaw_updates()
        else:
            # Save scroll destination for when the page becomes available.
            self._last_scroll_destination = scroll_to
            # If the pixbuf for the current page(s) isn't available,
            # hide all images to clear any old pixbufs.
            # XXX How about calling self._clear_main_area?
            for i in range(len(self.images)):
                self.images[i].hide()
            self._show_scrollbars([False] * len(self._scroll))

        self._waiting_for_redraw = False

        return False
Пример #11
0
    def _add_subpixbuf(self, canvas, x, y, image_size, source_pixbuf,
        other_image_width=0, left=True):
        """Copy a subpixbuf from <source_pixbuf> to <canvas> as it should
        be in the lens if the coordinates <x>, <y> are the mouse pointer
        position on the main window layout area.

        The displayed image (scaled from the <source_pixbuf>) must have
        size <image_size>.

        If <other_image_width> is given, it is the width of the "other" image
        in double page mode.

        The image we are getting the coordinates for is the left one unless
        <left> is False.
        """
        # Prevent division by zero exceptions further down
        if not image_size[0]:
            return

        area_x, area_y = self._window.get_visible_area_size()
        if left:
            padding_x = max(0,
                (area_x - other_image_width - image_size[0]) // 2)
        else:
            padding_x = \
                (max(0, (area_x - other_image_width - image_size[0]) // 2) +
                other_image_width + 2)
        padding_y = max(0, (area_y - image_size[1]) // 2)
        x -= padding_x
        y -= padding_y

        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(source_pixbuf)
            rotation = rotation % 360

        if rotation in [90, 270]:
            scale = float(source_pixbuf.get_height()) / image_size[0]
        else:
            scale = float(source_pixbuf.get_width()) / image_size[0]

        x *= scale
        y *= scale

        source_mag = prefs['lens magnification'] / scale
        width = height = prefs['lens size'] / source_mag

        paste_left = x > width / 2
        paste_top = y > height / 2
        dest_x = max(0, int(math.ceil((width / 2 - x) * source_mag)))
        dest_y = max(0, int(math.ceil((height / 2 - y) * source_mag)))

        if rotation == 90:
            x, y = y, source_pixbuf.get_height() - x
        elif rotation == 180:
            x = source_pixbuf.get_width() - x
            y = source_pixbuf.get_height() - y
        elif rotation == 270:
            x, y = source_pixbuf.get_width() - y, x
        if prefs['horizontal flip']:
            if rotation in (90, 270):
                y = source_pixbuf.get_height() - y
            else:
                x = source_pixbuf.get_width() - x
        if prefs['vertical flip']:
            if rotation in (90, 270):
                x = source_pixbuf.get_width() - x
            else:
                y = source_pixbuf.get_height() - y

        src_x = x - width / 2
        src_y = y - height / 2
        if src_x < 0:
            width += src_x
            src_x = 0
        if src_y < 0:
            height += src_y
            src_y = 0
        width = max(0, min(source_pixbuf.get_width() - src_x, width))
        height = max(0, min(source_pixbuf.get_height() - src_y, height))
        if width < 1 or height < 1:
            return

        subpixbuf = source_pixbuf.subpixbuf(int(src_x), int(src_y),
            int(width), int(height))
        subpixbuf = subpixbuf.scale_simple(
            int(math.ceil(source_mag * subpixbuf.get_width())),
            int(math.ceil(source_mag * subpixbuf.get_height())),
            prefs['scaling quality'])

        if rotation == 90:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_CLOCKWISE)
        elif rotation == 180:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_UPSIDEDOWN)
        elif rotation == 270:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE)
        if prefs['horizontal flip']:
            subpixbuf = subpixbuf.flip(horizontal=True)
        if prefs['vertical flip']:
            subpixbuf = subpixbuf.flip(horizontal=False)

        if paste_left:
            dest_x = 0
        else:
            dest_x = min(canvas.get_width() - subpixbuf.get_width(), dest_x)
        if paste_top:
            dest_y = 0
        else:
            dest_y = min(canvas.get_height() - subpixbuf.get_height(), dest_y)

        subpixbuf.copy_area(0, 0, subpixbuf.get_width(),
            subpixbuf.get_height(), canvas, dest_x, dest_y)
Пример #12
0
    def _add_subpixbuf(self, canvas, x, y, image_size, source_pixbuf,
        other_image_width=0, left=True):
        """Copy a subpixbuf from <source_pixbuf> to <canvas> as it should
        be in the lens if the coordinates <x>, <y> are the mouse pointer
        position on the main window layout area.

        The displayed image (scaled from the <source_pixbuf>) must have
        size <image_size>.

        If <other_image_width> is given, it is the width of the "other" image
        in double page mode.

        The image we are getting the coordinates for is the left one unless
        <left> is False.
        """
        # Prevent division by zero exceptions further down
        if not image_size[0]:
            return

        area_x, area_y = self._window.get_visible_area_size()
        if left:
            padding_x = max(0,
                (area_x - other_image_width - image_size[0]) // 2)
        else:
            padding_x = \
                (max(0, (area_x - other_image_width - image_size[0]) // 2) +
                other_image_width + 2)
        padding_y = max(0, (area_y - image_size[1]) // 2)
        x -= padding_x
        y -= padding_y

        rotation = prefs['rotation']
        if prefs['auto rotate from exif']:
            rotation += image_tools.get_implied_rotation(source_pixbuf)
            rotation = rotation % 360

        if rotation in [90, 270]:
            scale = float(source_pixbuf.get_height()) / image_size[0]
        else:
            scale = float(source_pixbuf.get_width()) / image_size[0]

        x *= scale
        y *= scale

        source_mag = prefs['lens magnification'] / scale
        width = height = prefs['lens size'] / source_mag

        paste_left = x > width / 2
        paste_top = y > height / 2
        dest_x = max(0, int(math.ceil((width / 2 - x) * source_mag)))
        dest_y = max(0, int(math.ceil((height / 2 - y) * source_mag)))

        if rotation == 90:
            x, y = y, source_pixbuf.get_height() - x
        elif rotation == 180:
            x = source_pixbuf.get_width() - x
            y = source_pixbuf.get_height() - y
        elif rotation == 270:
            x, y = source_pixbuf.get_width() - y, x
        if prefs['horizontal flip']:
            if rotation in (90, 270):
                y = source_pixbuf.get_height() - y
            else:
                x = source_pixbuf.get_width() - x
        if prefs['vertical flip']:
            if rotation in (90, 270):
                x = source_pixbuf.get_width() - x
            else:
                y = source_pixbuf.get_height() - y

        src_x = x - width / 2
        src_y = y - height / 2
        if src_x < 0:
            width += src_x
            src_x = 0
        if src_y < 0:
            height += src_y
            src_y = 0
        width = max(0, min(source_pixbuf.get_width() - src_x, width))
        height = max(0, min(source_pixbuf.get_height() - src_y, height))
        if width < 1 or height < 1:
            return

        subpixbuf = source_pixbuf.subpixbuf(int(src_x), int(src_y),
            int(width), int(height))
        subpixbuf = subpixbuf.scale_simple(
            int(math.ceil(source_mag * subpixbuf.get_width())),
            int(math.ceil(source_mag * subpixbuf.get_height())),
            gtk.gdk.INTERP_TILES)

        if rotation == 90:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_CLOCKWISE)
        elif rotation == 180:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_UPSIDEDOWN)
        elif rotation == 270:
            subpixbuf = subpixbuf.rotate_simple(
                gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE)
        if prefs['horizontal flip']:
            subpixbuf = subpixbuf.flip(horizontal=True)
        if prefs['vertical flip']:
            subpixbuf = subpixbuf.flip(horizontal=False)

        if paste_left:
            dest_x = 0
        else:
            dest_x = min(canvas.get_width() - subpixbuf.get_width(), dest_x)
        if paste_top:
            dest_y = 0
        else:
            dest_y = min(canvas.get_height() - subpixbuf.get_height(), dest_y)

        subpixbuf.copy_area(0, 0, subpixbuf.get_width(),
            subpixbuf.get_height(), canvas, dest_x, dest_y)
Пример #13
0
    def _draw_image(self, scroll_to):

        self._update_toggles_visibility()

        if not self.filehandler.file_loaded:
            self._clear_main_area()
            self._waiting_for_redraw = False
            return False

        if self.imagehandler.page_is_available():
            distribution_axis = constants.DISTRIBUTION_AXIS
            alignment_axis = constants.ALIGNMENT_AXIS
            pixbuf_count = 2 if self.displayed_double() else 1 # XXX limited to at most 2 pages
            pixbuf_list = list(self.imagehandler.get_pixbufs(pixbuf_count))
            size_list = [[pixbuf.get_width(), pixbuf.get_height()]
                         for pixbuf in pixbuf_list]

            if self.is_manga_mode:
                orientation = constants.MANGA_ORIENTATION
            else:
                orientation = constants.WESTERN_ORIENTATION

            # Rotation handling:
            # - apply Exif rotation on individual images
            # - apply automatic rotation (size based) on whole page
            # - apply manual rotation on whole page
            if prefs['auto rotate from exif']:
                rotation_list = [image_tools.get_implied_rotation(pixbuf)
                                 for pixbuf in pixbuf_list]
            else:
                rotation_list = [0] * len(pixbuf_list)
            virtual_size = [0, 0]
            for i in range(pixbuf_count):
                if rotation_list[i] in (90, 270):
                    size_list[i].reverse()
                size = size_list[i]
                virtual_size[distribution_axis] += size[distribution_axis]
                virtual_size[alignment_axis] = max(virtual_size[alignment_axis],
                                                   size[alignment_axis])
            rotation = self._get_size_rotation(*virtual_size)
            rotation = (rotation + prefs['rotation']) % 360
            if rotation in (90, 270):
                distribution_axis, alignment_axis = alignment_axis, distribution_axis
                orientation = list(orientation)
                orientation.reverse()
                for i in range(pixbuf_count):
                    size_list[i].reverse()
            if rotation in (180, 270):
                orientation = tools.vector_opposite(orientation)
            for i in range(pixbuf_count):
                rotation_list[i] = (rotation_list[i] + rotation) % 360
            if prefs['vertical flip'] and rotation in (90, 270):
                orientation = tools.vector_opposite(orientation)
            if prefs['horizontal flip'] and rotation in (0, 180):
                orientation = tools.vector_opposite(orientation)

            viewport_size = () # dummy
            expand_area = False
            scrollbar_requests = [False] * len(self._scroll)
            # Visible area size is recomputed depending on scrollbar visibility
            while True:
                self._show_scrollbars(scrollbar_requests)
                new_viewport_size = self.get_visible_area_size()
                if new_viewport_size == viewport_size:
                    break
                viewport_size = new_viewport_size
                zoom_dummy_size = list(viewport_size)
                dasize = zoom_dummy_size[distribution_axis] - \
                    self._spacing * (pixbuf_count - 1)
                if dasize <= 0:
                    dasize = 1
                zoom_dummy_size[distribution_axis] = dasize
                scaled_sizes = self.zoom.get_zoomed_size(size_list, zoom_dummy_size,
                    distribution_axis)
                self.layout = layout.FiniteLayout(scaled_sizes,
                                                  viewport_size,
                                                  orientation,
                                                  self._spacing,
                                                  expand_area,
                                                  distribution_axis,
                                                  alignment_axis)
                union_scaled_size = self.layout.get_union_box().get_size()
                scrollbar_requests = map(operator.or_, scrollbar_requests,
                    tools.smaller(viewport_size, union_scaled_size))
                if len(filter(None, scrollbar_requests)) > 1 and not expand_area:
                    expand_area = True
                    viewport_size = () # start anew

            for i in range(pixbuf_count):
                pixbuf_list[i] = image_tools.fit_pixbuf_to_rectangle(
                    pixbuf_list[i], scaled_sizes[i], rotation_list[i])

            for i in range(pixbuf_count):
                if prefs['horizontal flip']:
                    pixbuf_list[i] = pixbuf_list[i].flip(horizontal=True)
                if prefs['vertical flip']:
                    pixbuf_list[i] = pixbuf_list[i].flip(horizontal=False)
                pixbuf_list[i] = self.enhancer.enhance(pixbuf_list[i])

            for i in range(pixbuf_count):
                image_tools.set_from_pixbuf(self.images[i], pixbuf_list[i])

            scales = tuple(map(lambda x, y: math.sqrt(tools.div(
                tools.volume(x), tools.volume(y))), scaled_sizes, size_list))

            resolutions = tuple(map(lambda x, y: x + [y,], size_list, scales))
            if self.is_manga_mode:
                resolutions = tuple(reversed(resolutions))
            self.statusbar.set_resolution(resolutions)
            self.statusbar.update()

            smartbg = prefs['smart bg']
            smartthumbbg = prefs['smart thumb bg'] and prefs['show thumbnails']
            if smartbg or smartthumbbg:
                bg_colour = self.imagehandler.get_pixbuf_auto_background(pixbuf_count)
            if smartbg:
                self.set_bg_colour(bg_colour)
            if smartthumbbg:
                self.thumbnailsidebar.change_thumbnail_background_color(bg_colour)

            self._main_layout.window.freeze_updates()

            self._main_layout.set_size(*union_scaled_size)
            content_boxes = self.layout.get_content_boxes()
            for i in range(pixbuf_count):
                self._main_layout.move(self.images[i],
                    *content_boxes[i].get_position())

            for i in range(pixbuf_count):
                self.images[i].show()
            for i in range(pixbuf_count, len(self.images)):
                self.images[i].hide()

            # Reset orientation so scrolling behaviour is sane.
            if self.is_manga_mode:
                self.layout.set_orientation(constants.MANGA_ORIENTATION)
            else:
                self.layout.set_orientation(constants.WESTERN_ORIENTATION)

            if scroll_to is not None:
                destination = (scroll_to,) * 2
                if constants.SCROLL_TO_START == scroll_to:
                    index = constants.FIRST_INDEX
                elif constants.SCROLL_TO_END == scroll_to:
                    index = constants.LAST_INDEX
                else:
                    index = None
                self.scroll_to_predefined(destination, index)

            self._main_layout.window.thaw_updates()
        else:
            # Save scroll destination for when the page becomes available.
            self._last_scroll_destination = scroll_to
            # If the pixbuf for the current page(s) isn't available,
            # hide all images to clear any old pixbufs.
            # XXX How about calling self._clear_main_area?
            for i in range(len(self.images)):
                self.images[i].hide()
            self._show_scrollbars([False] * len(self._scroll))

        self._waiting_for_redraw = False

        return False
Пример #14
0
    def _draw_image(self, at_bottom, scroll):
        self._display_active_widgets()

        while gtk.events_pending():
            gtk.main_iteration(False)

        if not self.filehandler.file_loaded:
            self._waiting_for_redraw = False
            return False

        area_width, area_height = self.get_visible_area_size()

        if prefs['zoom mode'] == constants.ZOOM_MODE_HEIGHT:
            scaled_width = -1
        else:
            scaled_width = area_width

        if prefs['zoom mode'] == constants.ZOOM_MODE_WIDTH:
            scaled_height = -1
        else:
            scaled_height = area_height

        scale_up = prefs['stretch']
        self.is_virtual_double_page = \
            self.imagehandler.get_virtual_double_page()

        skip_pixbuf = not self.imagehandler.page_is_available()

        if self.displayed_double() and not skip_pixbuf:
            left_pixbuf, right_pixbuf = self.imagehandler.get_pixbufs()
            if self.is_manga_mode:
                right_pixbuf, left_pixbuf = left_pixbuf, right_pixbuf
            left_unscaled_x = left_pixbuf.get_width()
            left_unscaled_y = left_pixbuf.get_height()
            right_unscaled_x = right_pixbuf.get_width()
            right_unscaled_y = right_pixbuf.get_height()

            left_rotation = prefs['rotation']
            right_rotation = prefs['rotation']

            if prefs['auto rotate from exif']:
                left_rotation += image_tools.get_implied_rotation(left_pixbuf)
                left_rotation = left_rotation % 360
                right_rotation += image_tools.get_implied_rotation(
                    right_pixbuf)
                right_rotation = right_rotation % 360

            if prefs['zoom mode'] == constants.ZOOM_MODE_MANUAL:

                if left_rotation in (90, 270):
                    total_width = left_unscaled_y
                    total_height = left_unscaled_x
                else:
                    total_width = left_unscaled_x
                    total_height = left_unscaled_y

                if right_rotation in (90, 270):
                    total_width += right_unscaled_y
                    total_height += right_unscaled_x
                else:
                    total_width += right_unscaled_x
                    total_height += right_unscaled_y

                total_width += 2  # For the 2 px gap between images.
                scaled_width = int(self._manual_zoom * total_width / 100)
                scaled_height = int(self._manual_zoom * total_height / 100)
                scale_up = True

            left_pixbuf, right_pixbuf = image_tools.fit_2_in_rectangle(
                left_pixbuf,
                right_pixbuf,
                scaled_width,
                scaled_height,
                scale_up=scale_up,
                rotation1=left_rotation,
                rotation2=right_rotation)

            if prefs['horizontal flip']:
                left_pixbuf = left_pixbuf.flip(horizontal=True)
                right_pixbuf = right_pixbuf.flip(horizontal=True)

            if prefs['vertical flip']:
                left_pixbuf = left_pixbuf.flip(horizontal=False)
                right_pixbuf = right_pixbuf.flip(horizontal=False)

            left_pixbuf = self.enhancer.enhance(left_pixbuf)
            right_pixbuf = self.enhancer.enhance(right_pixbuf)

            self.left_image.set_from_pixbuf(left_pixbuf)
            self.right_image.set_from_pixbuf(right_pixbuf)

            x_padding = (area_width - left_pixbuf.get_width() -
                         right_pixbuf.get_width()) / 2
            y_padding = (area_height - max(left_pixbuf.get_height(),
                                           right_pixbuf.get_height())) / 2

            if left_rotation in (90, 270):
                left_scale_percent = (100.0 * left_pixbuf.get_width() /
                                      left_unscaled_y)
            else:
                left_scale_percent = (100.0 * left_pixbuf.get_width() /
                                      left_unscaled_x)

            if right_rotation in (90, 270):
                right_scale_percent = (100.0 * right_pixbuf.get_width() /
                                       right_unscaled_y)
            else:
                right_scale_percent = (100.0 * right_pixbuf.get_width() /
                                       right_unscaled_x)

            self.statusbar.set_resolution(
                (left_unscaled_x, left_unscaled_y, left_scale_percent),
                (right_unscaled_x, right_unscaled_y, right_scale_percent))

        elif not skip_pixbuf:
            pixbuf = self.imagehandler.get_pixbufs(single=True)[0]
            unscaled_x = pixbuf.get_width()
            unscaled_y = pixbuf.get_height()

            rotation = prefs['rotation']
            if prefs['auto rotate from exif']:
                rotation += image_tools.get_implied_rotation(pixbuf)
                rotation = rotation % 360

            if prefs['zoom mode'] == constants.ZOOM_MODE_MANUAL:
                # If 'Scale small images' is true, scale up the image's base size
                scale_x = max(scale_up and scaled_width or unscaled_x,
                              unscaled_x)
                scale_y = max(scale_up and scaled_height or unscaled_y,
                              unscaled_y)
                scaled_width = int(self._manual_zoom * scale_x / 100)
                scaled_height = int(self._manual_zoom * scale_y / 100)

                if rotation in (90, 270):
                    scaled_width, scaled_height = scaled_height, scaled_width

                scale_up = True

            pixbuf = image_tools.fit_in_rectangle(pixbuf,
                                                  scaled_width,
                                                  scaled_height,
                                                  scale_up=scale_up,
                                                  rotation=rotation)

            if prefs['horizontal flip']:
                pixbuf = pixbuf.flip(horizontal=True)
            if prefs['vertical flip']:
                pixbuf = pixbuf.flip(horizontal=False)

            pixbuf = self.enhancer.enhance(pixbuf)

            self.left_image.set_from_pixbuf(pixbuf)
            self.right_image.clear()

            x_padding = (area_width - pixbuf.get_width()) / 2
            y_padding = (area_height - pixbuf.get_height()) / 2

            if rotation in (90, 270):
                scale_percent = 100.0 * pixbuf.get_width() / unscaled_y
            else:
                scale_percent = 100.0 * pixbuf.get_width() / unscaled_x

            self.statusbar.set_resolution(
                (unscaled_x, unscaled_y, scale_percent))

        if prefs['smart bg'] and not skip_pixbuf:

            bg_colour = self.imagehandler.get_pixbuf_auto_background(
                not self.displayed_double())
            self.set_bg_colour(bg_colour)

            if prefs['smart thumb bg'] and prefs['show thumbnails']:
                self.thumbnailsidebar.change_thumbnail_background_color(
                    bg_colour)

        elif prefs['smart thumb bg'] and prefs[
                'show thumbnails'] and not skip_pixbuf:

            bg_colour = image_tools.get_most_common_edge_colour(
                self.left_image.get_pixbuf())

            self.thumbnailsidebar.change_thumbnail_background_color(bg_colour)

        if not skip_pixbuf:
            self._image_box.window.freeze_updates()
            self._main_layout.move(self._image_box, max(0, x_padding),
                                   max(0, y_padding))

            self.left_image.show()

            if self.displayed_double():
                self.right_image.show()
            else:
                self.right_image.hide()

            self._main_layout.set_size(*self._image_box.size_request())

            if scroll:
                if at_bottom:
                    self.scroll_to_fixed(horiz='endsecond', vert='bottom')
                else:
                    self.scroll_to_fixed(horiz='startfirst', vert='top')

            self._image_box.window.thaw_updates()
        else:
            # If the pixbuf for the current page(s) isn't available,
            # hide both images to clear any old pixbufs.
            self.left_image.hide()
            self.right_image.hide()

        self._update_page_information()
        self._waiting_for_redraw = False

        while gtk.events_pending():
            gtk.main_iteration(False)

        return False