public void setPage(int pageNum) {
   page = pageNum;
   DjVuPage newPage = app.getPageCache().fetchPage(pageNum);
   if (newPage != null) {
     pageInfo = newPage.getInfo();
     app.getToolbar().setZoomOptions(findZoomOptions());
     viewChanged();
   } else {
     pageInfo = null;
   }
   redraw();
   if (changeListener != null) changeListener.pageChanged(pageNum);
   scheduleURLUpdate();
 }
  private ArrayList<Integer> findZoomOptions() {
    ArrayList<Integer> result = new ArrayList<>();
    result.add(100);
    final int screenDPI = app.getScreenDPI();
    zoom100 = 1.0 * screenDPI / pageInfo.dpi;
    int subsample = toSubsample(zoom100);
    if (toZoom(subsample) / zoom100 > zoom100 / toZoom(subsample + 1)) subsample++;
    zoom100 = toZoom(subsample);

    if (zoom == 0) zoom = zoom100;

    double z = zoom100;
    for (int i = subsample + 1; i <= MAX_SUBSAMPLE; i++) {
      double z2 = toZoom(i);
      if (z / z2 > 1.2) {
        z = z2;
        result.add((int) (z / zoom100 * 100 + 0.5));
      }
    }

    z = zoom100;
    for (int i = subsample - 1; i >= 1; i--) {
      double z2 = toZoom(i);
      if (z2 / z > 1.2) {
        z = z2;
        result.add(0, (int) (z / zoom100 * 100 + 0.5));
      }
    }
    return result;
  }
  public SinglePageLayout(Djvu_html5 app) {
    this.app = app;
    this.tileCache = app.getTileCache();
    this.pageCache = app.getPageCache();

    pageCache.addFullDecodeListener(this);
    tileCache.addTileCacheListener(this);

    this.canvas = app.getCanvas();

    this.background = app.getBackground();
    this.pageMargin = app.getPageMargin();

    new PanController();

    boolean pageParam = false;
    try {
      page = Integer.parseInt(Window.Location.getParameter("p")) - 1;
      pageParam = true;
    } catch (Exception e) {
      page = 0;
    }
    locationUpdateEnabled = pageParam || app.getLocationUpdateEnabled();
    pageCache.fetchPage(page);
  }
  private void viewChanged() {
    if (pageInfo == null) return;
    int w = canvas.getCoordinateSpaceWidth(), h = canvas.getCoordinateSpaceHeight();
    int pw = (int) (pageInfo.width * zoom), ph = (int) (pageInfo.height * zoom);
    if (pw < w) {
      centerX = pw / 2;
    } else {
      centerX = Math.max(centerX, w / 2 - pageMargin);
      centerX = Math.min(centerX, pw - w / 2 + pageMargin);
    }

    if (ph < h) {
      centerY = ph / 2;
    } else {
      centerY = Math.max(centerY, h / 2 - pageMargin);
      centerY = Math.min(centerY, ph - h / 2 + pageMargin);
    }

    double pw2 = pw + 2 * pageMargin, ph2 = ph + 2 * pageMargin;
    app.getHorizontalScrollbar().setThumb((centerX + pageMargin) / pw2, w / pw2);
    app.getVerticalScrollbar().setThumb((centerY + pageMargin) / ph2, h / ph2);
    if (app.getTextLayer() != null)
      app.getTextLayer().setViewPosition(page, w / 2 - centerX, h / 2 - centerY, zoom);
  }