docs: public ZoomBounds set(State state) {
          float imageWidth = settings.getImageW();
          float imageHeight = settings.getImageH();
  
          float areaWidth = settings.getMovementAreaW();
          float areaHeight = settings.getMovementAreaH();
  
          if (imageWidth == 0f || imageHeight == 0f || areaWidth == 0f || areaHeight == 0f) {
              minZoom = maxZoom = fitZoom = 1f;
              return this;
          }
  
          minZoom = settings.getMinZoom();
          maxZoom = settings.getMaxZoom();
  
          final float rotation = state.getRotation();
  
          if (!State.equals(rotation, 0f)) {
              if (settings.getFitMethod() == Settings.Fit.OUTSIDE) {
                  // Computing movement area size taking rotation into account. We need to inverse
                  // rotation, since it will be applied to the area, not to the image itself.
                  tmpMatrix.setRotate(-rotation);
                  tmpRectF.set(0, 0, areaWidth, areaHeight);
                  tmpMatrix.mapRect(tmpRectF);
                  areaWidth = tmpRectF.width();
                  areaHeight = tmpRectF.height();
              } else {
                  // Computing image bounding size taking rotation into account.
                  tmpMatrix.setRotate(rotation);
                  tmpRectF.set(0, 0, imageWidth, imageHeight);
                  tmpMatrix.mapRect(tmpRectF);
                  imageWidth = tmpRectF.width();
                  imageHeight = tmpRectF.height();
              }
          }
  
          switch (settings.getFitMethod()) {
              case HORIZONTAL:
                  fitZoom = areaWidth / imageWidth;
                  break;
              case VERTICAL:
                  fitZoom = areaHeight / imageHeight;
                  break;
              case INSIDE:
                  fitZoom = Math.min(areaWidth / imageWidth, areaHeight / imageHeight);
                  break;
              case OUTSIDE:
                  fitZoom = Math.max(areaWidth / imageWidth, areaHeight / imageHeight);
                  break;
              case NONE:
              default:
                  fitZoom = minZoom > 0f ? minZoom : 1f;
          }
  
          if (minZoom <= 0f) {
              minZoom = fitZoom;
          }
          if (maxZoom <= 0f) {
              maxZoom = fitZoom;
          }
  
          if (fitZoom > maxZoom) {
              if (settings.isFillViewport()) {
                  // zooming to fill entire viewport
                  maxZoom = fitZoom;
              } else {
                  // restricting fit zoom
                  fitZoom = maxZoom;
              }
          }
          // Now we have: fitZoom <= maxZoom
  
          if (minZoom > maxZoom) {
              minZoom = maxZoom;
          }
          // Now we have: minZoom <= maxZoom
  
          if (fitZoom < minZoom) {
              if (settings.isFillViewport()) {
                  // zooming to fill entire viewport
                  minZoom = fitZoom;
              } else {
                  // restricting fit zoom
                  fitZoom = minZoom;
              }
          }
          // Now we have: minZoom <= fitZoom <= maxZoom
          return this;
      }