# File ../lib/roller/CWRP.rb, line 1000
  def export_satellite_mask(filename, cell_width, config)
    # Convert height colour data into Fox colours.
    heights_info = config[:heights]
    heights_info.each do |height_info|
      height_info[:colour] = FXRGB(*height_info[:colour])
    end

    mask_width = map_size / cell_width

    # GUI will already be running if progress bar is shown.
    init_gui if @window.nil?
    
    @window.create_mask(mask_width)

    FXDCWindow.new(@window.image) do |dc|

      # First, differentiate land and sea types based on height.
      reset_progress "Exporting satellite mask (Terrain)", mask_width
      
      (0...mask_width).each do |y|
        (0...mask_width).each do |x|
          height = height_at(x * cell_width, y * cell_width)

          heights_info.each do |height_level|
            if height <= height_level[:upto]
              dc.foreground = height_level[:colour]
              dc.drawPoint(x, mask_width - 1 - y)
              break
            end
          end
        end
        
        increment_progress
      end

      # Draw buildings/roads and check for forests.
      urban_info = config[:urban]
      urban_sizes = urban_info[:sizes]
      urban_sizes.default = urban_info[:default_size]
      dc.foreground = FXRGB(*urban_info[:colour])
      urban_pattern = /#{urban_info[:pattern]}/

      forest_info = config[:forest]
      forest_cell_ratio = FOREST_CELL_WIDTH / cell_width

      forest_grid = Array.new(map_size / FOREST_CELL_WIDTH) do
        Array.new(map_size / FOREST_CELL_WIDTH, 0)
      end

      forest_pattern = /#{forest_info[:pattern]}/
      forest_classes = forest_info[:classes]

      reset_progress "Exporting satellite mask (Objects)", @objects.size / OBJECTS_PER_PROGRESS
      @objects.each_with_index do |object, index|
        case object.name
        when urban_pattern
          x_centre = object.position.x / cell_width
          y_centre = object.position.y / cell_width

          dir = object.dir

          size = urban_sizes[object.name]
          x_range = (-size[0] / 2)..(size[0] / 2)
          y_range = (-size[1] / 2)..(size[1] / 2)

          x_range.each do |x_model|
            y_range.each do |y_model|
              x_offset, y_offset = rotate(x_model / cell_width, y_model / cell_width, dir)
              x = [[mask_width - 1, x_centre + x_offset].min, 0].max
              y = [[mask_width - 1, y_centre + y_offset].min, 0].max

              dc.drawPoint(x, mask_width - 1 - y)

              # Any urban will prevent forest terrain.
              forest_grid[x / forest_cell_ratio][(y / forest_cell_ratio) + 1] = -10000
            end
          end

        when forest_pattern
          if forest_classes.include? object.name
            forest_grid[object.position.x / FOREST_CELL_WIDTH][object.position.y / FOREST_CELL_WIDTH] += 1
          end
        end

        increment_progress if index.modulo(OBJECTS_PER_PROGRESS) == 0
      end

      # Forests.
      reset_progress "Exporting satellite mask (Forests)", forest_grid.size
      dc.foreground = FXRGB(*forest_info[:colour])
      min_forest_cell_density = forest_info[:min_density] * (FOREST_CELL_WIDTH ** 2)
      forest_grid.each_with_index do |row, x|
        row.each_with_index do |density, y|
          if density >= min_forest_cell_density
            dc.fillRectangle(x * forest_cell_ratio,
              (forest_grid.size - 1 - y) * forest_cell_ratio,
              forest_cell_ratio,
              forest_cell_ratio)
          end
        end

        increment_progress
      end
    end

    @window.save_mask(filename)
  end