@Override
  MapRects calcMap(final MapRect r, final MapList ml, final int ns, final int ne) {
    // stores all calculated rectangles
    final MapRects rects = new MapRects();

    // node iterator
    int ni = ns;
    // first node of current row
    int start = ns;

    // setting initial proportions
    final double yy = r.y;
    final double hh = r.h;
    double xx = r.x;
    double ww = r.w;

    MapRects row = new MapRects();
    int width;
    double weight = 0;
    double sumweight = 1;
    double tmpratio;
    double rowratio = Double.MAX_VALUE;

    while (ni <= ne && xx + ww <= r.x + r.w && yy + hh <= r.y + r.h) {
      weight += ml.weight[ni];
      width = (int) (weight / sumweight * ww);
      width = width > 0 ? width : 1;

      final MapRects tmp = new MapRects();

      double y = yy;
      for (int i = start; i <= ni; ++i) {
        int h = i == ni ? (int) (yy + hh - y) : (int) (ml.weight[i] / weight * hh);
        h = h > 0 ? h : 1;

        if (yy <= yy + hh) tmp.add(new MapRect((int) xx, (int) y, width, h, ml.get(i), r.level));
        else break;
        y += h;
      }
      tmpratio = lineRatio(tmp);

      // if ar has increased discard tmp and add row
      if (tmpratio > rowratio) {
        // add rects of row to solution
        rects.add(row);
        rowratio = Double.MAX_VALUE;
        // preparing next line
        ww -= row.get(0).w;
        xx += row.get(0).w;
        tmp.reset();
        row.reset();
        start = ni;
        sumweight -= weight - ml.weight[ni];
        weight = 0;
        // sometimes there has to be one rectangles to fill the left space
        if (ne == ni) {
          row.add(new MapRect((int) xx, (int) yy, (int) ww, (int) hh, ml.get(ni), r.level));
          break;
        }
      } else {
        row = tmp;
        rowratio = tmpratio;
        ++ni;
      }
    }
    // adding last row
    for (final MapRect rect : row) rect.w = (int) ww;
    rects.add(row);
    return rects;
  }
Beispiel #2
0
  @Override
  void drawRectangles(final Graphics g, final MapRects rects, final float scale) {
    // some additions to set up borders
    final MapRect l = view.layout.layout;
    l.x = (int) scale * l.x;
    l.y = (int) scale * l.y;
    l.w = (int) scale * l.w;
    l.h = (int) scale * l.h;
    final int ww = view.getWidth();
    final int hh = view.getWidth();

    final Data data = view.gui.context.data();
    final int fsz = GUIConstants.fontSize;

    final int off = gopts.get(GUIOptions.MAPOFFSETS);
    final int rs = rects.size;
    for (int ri = 0; ri < rs; ++ri) {
      // get rectangle information
      final MapRect r = rects.get(ri);
      final int pre = r.pre;

      // level 1: next context node, set marker pointer to 0
      final int lvl = r.level;

      final boolean full = r.w == ww && r.h == hh;
      Color col = color(rects, ri);
      final boolean mark = col != null;

      r.pos =
          view.gui.context.marked.ftpos != null
              ? view.gui.context.marked.ftpos.get(data, pre)
              : null;
      g.setColor(mark ? col : GUIConstants.color(lvl));

      if (r.w < l.x + l.w || r.h < l.y + l.h || off < 2 || ViewData.leaf(gopts, data, pre)) {
        g.fillRect(r.x, r.y, r.w, r.h);
      } else {
        // painting only border for non-leaf nodes..
        g.fillRect(r.x, r.y, l.x, r.h);
        g.fillRect(r.x, r.y, r.w, l.y);
        g.fillRect(r.x + r.w - l.w, r.y, l.w, r.h);
        g.fillRect(r.x, r.y + r.h - l.h, r.w, l.h);
      }

      if (!full) {
        col = mark ? GUIConstants.colormark3 : GUIConstants.color(lvl + 2);
        g.setColor(col);
        g.drawRect(r.x, r.y, r.w, r.h);
        col = mark ? GUIConstants.colormark4 : GUIConstants.color(Math.max(0, lvl - 2));
        g.setColor(col);
        g.drawLine(r.x + r.w, r.y, r.x + r.w, r.y + r.h);
        g.drawLine(r.x, r.y + r.h, r.x + r.w, r.y + r.h);
      }

      // skip drawing of string if there is no space
      if (r.w <= 3 || r.h < GUIConstants.fontSize) continue;

      r.x += 3;
      r.w -= 3;

      final int kind = data.kind(pre);
      if (kind == Data.ELEM || kind == Data.DOC) {
        g.setColor(Color.black);
        g.setFont(GUIConstants.font);
        BaseXLayout.chopString(g, ViewData.name(gopts, data, pre), r.x, r.y, r.w, fsz);
      } else {
        g.setColor(GUIConstants.color(r.level * 2 + 8));
        g.setFont(GUIConstants.mfont);
        final byte[] text = ViewData.content(data, pre, false);

        r.thumb = MapRenderer.calcHeight(g, r, text, fsz) >= r.h;
        if (r.thumb) {
          MapRenderer.drawThumbnails(g, r, text, fsz);
        } else {
          MapRenderer.drawText(g, r, text, fsz);
        }
      }
      r.x -= 3;
      r.w += 3;
    }
  }