prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Crash of ImageView example in Gtk
  **Describe the bug**
  The `imageview` example crashes on Gtk because `toga_gtk.ImageView.rehint()` is called before `toga_gtk.ImageView._pixbuf` has been set by the interface layer. The following traceback is produced:
  
  ```
  Traceback (most recent call last):
    File "/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/app.py", line 93, in gtk_startup
      self.interface.startup()
    File "/media/psf/Home/Python/toga/examples/imageview/imageview/app.py", line 18, in startup
      imageview_from_path = toga.ImageView(image_from_path)
    File "/home/samschott/.local/lib/python3.8/site-packages/toga/widgets/imageview.py", line 25, in __init__
      self._impl = self.factory.ImageView(interface=self)
    File "/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/widgets/base.py", line 12, in __init__
      self.interface.style.reapply()
    File "/home/samschott/.local/lib/python3.8/site-packages/travertino/declaration.py", line 88, in reapply
      self.apply(style, getattr(self, style))
    File "/home/samschott/.local/lib/python3.8/site-packages/toga/style/pack.py", line 104, in apply
      self._applicator.set_font(
    File "/home/samschott/.local/lib/python3.8/site-packages/toga/style/applicator.py", line 25, in set_font
      self.widget._impl.rehint()
    File "/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/widgets/imageview.py", line 20, in rehint
      original_height=self._pixbuf.get_height(),
  AttributeError: 'NoneType' object has no attribute 'get_height'
  ```
  
  **To Reproduce**
  Run the imageview example:
  ```shell
  python3 -m imageview
  ```
  
  **Environment:**
   - Operating System: Ubuntu 20.04
   - Python version: Python 3.8
   - Software versions:
     - Toga: 0.3.0.dev23
  
  **Additional context**
  This is a tricky issue and I suspect it was introduced by a change to when the style is applied. Essentially, the interface does set image (pixbuf) during init. Nevertheless, the style is already applied during the init of `toga_gtk.base.Widget`, before setting the image (line 12):
  
  https://github.com/beeware/toga/blob/f8bea583c87642ad102776e1b58fd8bb9265b135/src/gtk/toga_gtk/widgets/base.py#L5-L12
  
  The quickest solution may be to guard against `pixbuf` not being set in the `rehint` implementation.
  
  </issue>
  <code>
  [start of src/gtk/toga_gtk/widgets/imageview.py]
  1 
  2 from ..libs import GdkPixbuf, Gtk
  3 from .base import Widget
  4 
  5 
  6 class ImageView(Widget):
  7 
  8     def create(self):
  9         self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
  10         self._image = Gtk.Image()
  11         self._pixbuf = None
  12         self.native.add(self._image)
  13         self.native.interface = self.interface
  14 
  15     def set_image(self, image):
  16         self._pixbuf = image._impl.native
  17 
  18     def rehint(self):
  19         height, width = self._resize_max(
  20             original_height=self._pixbuf.get_height(),
  21             original_width=self._pixbuf.get_width(),
  22             max_height=self.native.get_allocated_height(),
  23             max_width=self.native.get_allocated_width()
  24         )
  25 
  26         scaled_pixbuf = self._pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
  27         self._image.set_from_pixbuf(scaled_pixbuf)
  28 
  29     @staticmethod
  30     def _resize_max(original_height, original_width, max_height, max_width):
  31 
  32         # Check to make sure all dimensions have valid sizes
  33         if min(original_height, original_width, max_height, max_width) <= 0:
  34             return 1, 1
  35 
  36         width_ratio = max_width/original_width
  37         height_ratio = max_height/original_height
  38 
  39         height = original_height * width_ratio
  40         if height <= max_height:
  41             width = original_width * width_ratio
  42         else:
  43             height = original_height * height_ratio
  44             width = original_width * height_ratio
  45 
  46         return int(height), int(width)
  47
  [end of src/gtk/toga_gtk/widgets/imageview.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/gtk/toga_gtk/widgets/imageview.py b/src/gtk/toga_gtk/widgets/imageview.py
  --- a/src/gtk/toga_gtk/widgets/imageview.py
  +++ b/src/gtk/toga_gtk/widgets/imageview.py
  @@ -1,10 +1,8 @@
  -
  -from ..libs import GdkPixbuf, Gtk
  +from ..libs import GdkPixbuf, Gtk, Gdk
   from .base import Widget
   
   
   class ImageView(Widget):
  -
       def create(self):
           self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
           self._image = Gtk.Image()
  @@ -15,16 +13,30 @@
       def set_image(self, image):
           self._pixbuf = image._impl.native
   
  +    def set_bounds(self, x, y, width, height):
  +        super().set_bounds(x, y, width, height)
  +        # rehint to update scaling of pixbuf
  +        self.rehint()
  +
       def rehint(self):
  -        height, width = self._resize_max(
  -            original_height=self._pixbuf.get_height(),
  -            original_width=self._pixbuf.get_width(),
  -            max_height=self.native.get_allocated_height(),
  -            max_width=self.native.get_allocated_width()
  -        )
  +        if self._pixbuf:
  +            height, width = self._resize_max(
  +                original_height=self._pixbuf.get_height(),
  +                original_width=self._pixbuf.get_width(),
  +                max_height=self.native.get_allocated_height(),
  +                max_width=self.native.get_allocated_width(),
  +            )
  +
  +            dpr = self.native.get_scale_factor()
  +
  +            scaled_pixbuf = self._pixbuf.scale_simple(
  +                width * dpr, height * dpr, GdkPixbuf.InterpType.BILINEAR
  +            )
   
  -        scaled_pixbuf = self._pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
  -        self._image.set_from_pixbuf(scaled_pixbuf)
  +            surface = Gdk.cairo_surface_create_from_pixbuf(
  +                scaled_pixbuf, 0, self.native.get_window()  # scale: 0 = same as window
  +            )
  +            self._image.set_from_surface(surface)
   
       @staticmethod
       def _resize_max(original_height, original_width, max_height, max_width):
  @@ -33,8 +45,8 @@
           if min(original_height, original_width, max_height, max_width) <= 0:
               return 1, 1
   
  -        width_ratio = max_width/original_width
  -        height_ratio = max_height/original_height
  +        width_ratio = max_width / original_width
  +        height_ratio = max_height / original_height
   
           height = original_height * width_ratio
           if height <= max_height:
  
verification_info: {"golden_diff": "diff --git a/src/gtk/toga_gtk/widgets/imageview.py b/src/gtk/toga_gtk/widgets/imageview.py\n--- a/src/gtk/toga_gtk/widgets/imageview.py\n+++ b/src/gtk/toga_gtk/widgets/imageview.py\n@@ -1,10 +1,8 @@\n-\n-from ..libs import GdkPixbuf, Gtk\n+from ..libs import GdkPixbuf, Gtk, Gdk\n from .base import Widget\n \n \n class ImageView(Widget):\n-\n     def create(self):\n         self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)\n         self._image = Gtk.Image()\n@@ -15,16 +13,30 @@\n     def set_image(self, image):\n         self._pixbuf = image._impl.native\n \n+    def set_bounds(self, x, y, width, height):\n+        super().set_bounds(x, y, width, height)\n+        # rehint to update scaling of pixbuf\n+        self.rehint()\n+\n     def rehint(self):\n-        height, width = self._resize_max(\n-            original_height=self._pixbuf.get_height(),\n-            original_width=self._pixbuf.get_width(),\n-            max_height=self.native.get_allocated_height(),\n-            max_width=self.native.get_allocated_width()\n-        )\n+        if self._pixbuf:\n+            height, width = self._resize_max(\n+                original_height=self._pixbuf.get_height(),\n+                original_width=self._pixbuf.get_width(),\n+                max_height=self.native.get_allocated_height(),\n+                max_width=self.native.get_allocated_width(),\n+            )\n+\n+            dpr = self.native.get_scale_factor()\n+\n+            scaled_pixbuf = self._pixbuf.scale_simple(\n+                width * dpr, height * dpr, GdkPixbuf.InterpType.BILINEAR\n+            )\n \n-        scaled_pixbuf = self._pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)\n-        self._image.set_from_pixbuf(scaled_pixbuf)\n+            surface = Gdk.cairo_surface_create_from_pixbuf(\n+                scaled_pixbuf, 0, self.native.get_window()  # scale: 0 = same as window\n+            )\n+            self._image.set_from_surface(surface)\n \n     @staticmethod\n     def _resize_max(original_height, original_width, max_height, max_width):\n@@ -33,8 +45,8 @@\n         if min(original_height, original_width, max_height, max_width) <= 0:\n             return 1, 1\n \n-        width_ratio = max_width/original_width\n-        height_ratio = max_height/original_height\n+        width_ratio = max_width / original_width\n+        height_ratio = max_height / original_height\n \n         height = original_height * width_ratio\n         if height <= max_height:\n", "issue": "Crash of ImageView example in Gtk\n**Describe the bug**\r\nThe `imageview` example crashes on Gtk because `toga_gtk.ImageView.rehint()` is called before `toga_gtk.ImageView._pixbuf` has been set by the interface layer. The following traceback is produced:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/app.py\", line 93, in gtk_startup\r\n    self.interface.startup()\r\n  File \"/media/psf/Home/Python/toga/examples/imageview/imageview/app.py\", line 18, in startup\r\n    imageview_from_path = toga.ImageView(image_from_path)\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga/widgets/imageview.py\", line 25, in __init__\r\n    self._impl = self.factory.ImageView(interface=self)\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/widgets/base.py\", line 12, in __init__\r\n    self.interface.style.reapply()\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/travertino/declaration.py\", line 88, in reapply\r\n    self.apply(style, getattr(self, style))\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga/style/pack.py\", line 104, in apply\r\n    self._applicator.set_font(\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga/style/applicator.py\", line 25, in set_font\r\n    self.widget._impl.rehint()\r\n  File \"/home/samschott/.local/lib/python3.8/site-packages/toga_gtk/widgets/imageview.py\", line 20, in rehint\r\n    original_height=self._pixbuf.get_height(),\r\nAttributeError: 'NoneType' object has no attribute 'get_height'\r\n```\r\n\r\n**To Reproduce**\r\nRun the imageview example:\r\n```shell\r\npython3 -m imageview\r\n```\r\n\r\n**Environment:**\r\n - Operating System: Ubuntu 20.04\r\n - Python version: Python 3.8\r\n - Software versions:\r\n   - Toga: 0.3.0.dev23\r\n\r\n**Additional context**\r\nThis is a tricky issue and I suspect it was introduced by a change to when the style is applied. Essentially, the interface does set image (pixbuf) during init. Nevertheless, the style is already applied during the init of `toga_gtk.base.Widget`, before setting the image (line 12):\r\n\r\nhttps://github.com/beeware/toga/blob/f8bea583c87642ad102776e1b58fd8bb9265b135/src/gtk/toga_gtk/widgets/base.py#L5-L12\r\n\r\nThe quickest solution may be to guard against `pixbuf` not being set in the `rehint` implementation.\n", "before_files": [{"content": "\nfrom ..libs import GdkPixbuf, Gtk\nfrom .base import Widget\n\n\nclass ImageView(Widget):\n\n    def create(self):\n        self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)\n        self._image = Gtk.Image()\n        self._pixbuf = None\n        self.native.add(self._image)\n        self.native.interface = self.interface\n\n    def set_image(self, image):\n        self._pixbuf = image._impl.native\n\n    def rehint(self):\n        height, width = self._resize_max(\n            original_height=self._pixbuf.get_height(),\n            original_width=self._pixbuf.get_width(),\n            max_height=self.native.get_allocated_height(),\n            max_width=self.native.get_allocated_width()\n        )\n\n        scaled_pixbuf = self._pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)\n        self._image.set_from_pixbuf(scaled_pixbuf)\n\n    @staticmethod\n    def _resize_max(original_height, original_width, max_height, max_width):\n\n        # Check to make sure all dimensions have valid sizes\n        if min(original_height, original_width, max_height, max_width) <= 0:\n            return 1, 1\n\n        width_ratio = max_width/original_width\n        height_ratio = max_height/original_height\n\n        height = original_height * width_ratio\n        if height <= max_height:\n            width = original_width * width_ratio\n        else:\n            height = original_height * height_ratio\n            width = original_width * height_ratio\n\n        return int(height), int(width)\n", "path": "src/gtk/toga_gtk/widgets/imageview.py"}]}