Example #1
0
  /**
   * This function merges the glyph groups from <tt>wi<tt/> into the glyph groups that are already
   * on this line. It does no fit checking, just adds them in the proper place in the
   * <tt>newGGIS</tt> data member.
   */
  protected void mergeGlyphGroups(WordInfo wi) {
    int numGG = wi.getNumGlyphGroups();
    newSize = 0;
    if (ggis == null) {
      // first glyph group on line just add them.
      newSize = numGG;
      newGGIS = new GlyphGroupInfo[numGG];
      for (int i = 0; i < numGG; i++) newGGIS[i] = wi.getGlyphGroup(i);
    } else {
      // We need to merge the new glyph groups with the
      // existing glyph Groups.
      int s = 0;
      int i = 0;
      GlyphGroupInfo nggi = wi.getGlyphGroup(i);
      int nStart = nggi.getStart();

      GlyphGroupInfo oggi = ggis[size - 1];
      int oStart = oggi.getStart();

      newGGIS = assureSize(newGGIS, size + numGG);
      if (nStart < oStart) {
        oggi = ggis[s];
        oStart = oggi.getStart();
        while ((s < size) && (i < numGG)) {
          if (nStart < oStart) {
            newGGIS[newSize++] = nggi;
            i++;
            if (i < numGG) {
              nggi = wi.getGlyphGroup(i);
              nStart = nggi.getStart();
            }
          } else {
            newGGIS[newSize++] = oggi;
            s++;
            if (s < size) {
              oggi = ggis[s];
              oStart = oggi.getStart();
            }
          }
        }
      }
      while (s < size) {
        newGGIS[newSize++] = ggis[s++];
      }
      while (i < numGG) {
        newGGIS[newSize++] = wi.getGlyphGroup(i++);
      }
    }
    // for (int i=0; i<newSize; i++) {
    //     System.err.println("GGIS["+i+"]: " + newGGIS[i].start + " -> " +
    //                        newGGIS[i].end);
    // }
  }
Example #2
0
  public boolean assignGlyphGroupRanges(int ggSz, GlyphGroupInfo[] ggis) {
    int i = 0, r = 0;
    while (r < numRanges) {
      double range = ranges[2 * r + 1] - ranges[2 * r];
      float adv = 0;
      float rangeAdvance = 0;

      while (i < ggSz) {
        GlyphGroupInfo ggi = ggis[i];
        ggi.setRange(r);
        adv = ggi.getAdvance();
        double delta = range - (rangeAdvance + adv);
        if (delta < 0) break;

        i++;
        rangeAdvance += adv;
      }

      // Check last glyphGroup anyways...
      if (i == ggSz) {
        i--;
        rangeAdvance -= adv;
      }

      GlyphGroupInfo ggi = ggis[i];
      float ladv = ggi.getLastAdvance();
      while (rangeAdvance + ladv > range) {
        // "i" can't fit in this region see if "i-1" can.
        i--;
        ladv = 0;
        if (i < 0) break;
        ggi = ggis[i];
        if (r != ggi.getRange()) // Not from this range nothing fits.
        break;

        rangeAdvance -= ggi.getAdvance();
        ladv = ggi.getLastAdvance();
      }

      i++;
      rangeAdv[r] = rangeAdvance + ladv;
      r++;
      if (i == ggSz) return true;
    }
    return false;
  }
Example #3
0
  public void layout() {
    if (size == 0) return;

    // This is needed because we know that in most cases
    // the addition of the last word failed.  In the case of
    // BIDI this will mess up region assignments.
    // If one wanted to you could check on BIDI, and/or
    // lastPara.
    assignGlyphGroupRanges(size, ggis);

    GVTGlyphVector gv = ggis[0].getGlyphVector();
    int justType = FULL_WORD;
    double ggAdv = 0;
    double gAdv = 0;

    // Calculate the number of Glyph Groups and the number
    // of glpyhs in each range for use with full justification.
    int[] rangeGG = new int[numRanges];
    int[] rangeG = new int[numRanges];
    GlyphGroupInfo[] rangeLastGGI = new GlyphGroupInfo[numRanges];
    GlyphGroupInfo ggi = ggis[0];
    int r = ggi.getRange();
    rangeGG[r]++;
    rangeG[r] += ggi.getGlyphCount();
    for (int i = 1; i < size; i++) {
      ggi = ggis[i];
      r = ggi.getRange();
      if ((rangeLastGGI[r] == null) || !rangeLastGGI[r].getHideLast()) rangeGG[r]++;
      rangeLastGGI[r] = ggi;

      rangeG[r] += ggi.getGlyphCount();

      GlyphGroupInfo pggi = ggis[i - 1];
      int pr = pggi.getRange();
      if (r != pr) rangeG[pr] += pggi.getLastGlyphCount() - pggi.getGlyphCount();
    }
    rangeG[r] += ggi.getLastGlyphCount() - ggi.getGlyphCount();

    int currRange = -1;
    double locX = 0, range = 0, rAdv = 0;
    r = -1;
    ggi = null;
    for (int i = 0; i < size; i++) {
      GlyphGroupInfo pggi = ggi;
      int prevRange = currRange;

      ggi = ggis[i];
      currRange = ggi.getRange();

      if (currRange != prevRange) {
        locX = ranges[2 * currRange];
        range = ranges[2 * currRange + 1] - locX;
        rAdv = rangeAdv[currRange];
        int textAlign = bi.getTextAlignment();
        if ((paraEnd) && (textAlign == BlockInfo.ALIGN_FULL)) textAlign = BlockInfo.ALIGN_START;

        switch (textAlign) {
          default:
          case BlockInfo.ALIGN_FULL:
            {
              double delta = range - rAdv;
              if (justType == FULL_WORD) {
                int numSp = rangeGG[currRange] - 1;
                if (numSp >= 1) ggAdv = delta / numSp;
              } else {
                int numSp = rangeG[currRange] - 1;
                if (numSp >= 1) gAdv = delta / numSp;
              }
            }
            break;
          case BlockInfo.ALIGN_START:
            break;
          case BlockInfo.ALIGN_MIDDLE:
            locX += (range - rAdv) / 2;
            break;
          case BlockInfo.ALIGN_END:
            locX += (range - rAdv);
            break;
        }
      } else if ((pggi != null) && pggi.getHideLast()) {
        // Hide last glyph from prev glyph group (soft hyphen etc).
        gv.setGlyphVisible(pggi.getEnd(), false);
      }

      int start = ggi.getStart();
      int end = ggi.getEnd();
      boolean[] hide = ggi.getHide();
      Point2D p2d = gv.getGlyphPosition(start);
      double deltaX = p2d.getX();
      double advAdj = 0;
      for (int g = start; g <= end; g++) {
        Point2D np2d = gv.getGlyphPosition(g + 1);
        if (hide[g - start]) {
          gv.setGlyphVisible(g, false);
          advAdj += np2d.getX() - p2d.getX();
        } else {
          gv.setGlyphVisible(g, true);
        }
        p2d.setLocation(p2d.getX() - deltaX - advAdj + locX, p2d.getY() + baseline);
        gv.setGlyphPosition(g, p2d);
        p2d = np2d;
        advAdj -= gAdv;
      }
      if (ggi.getHideLast()) locX += ggi.getAdvance() - advAdj;
      else locX += ggi.getAdvance() - advAdj + ggAdv;
    }
  }