1 18 package org.apache.batik.gvt.flow; 19 20 import java.awt.Shape ; 21 import java.awt.geom.Point2D ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.Comparator ; 27 import org.apache.batik.ext.awt.geom.SegmentList; 28 import org.apache.batik.ext.awt.geom.Segment; 29 30 35 public class FlowRegions { 36 Shape flowShape; 37 SegmentList sl; 38 SegmentList.SplitResults sr; 39 List validRanges; 40 int currentRange; 41 double currentY, lineHeight; 42 43 public FlowRegions(Shape s) { 44 this(s, s.getBounds2D().getY()); 45 } 46 47 public FlowRegions(Shape s, double startY) { 48 this.flowShape = s; 49 sl = new SegmentList(s); 50 currentY = startY-1; 51 gotoY(startY); 52 } 53 54 public double getCurrentY() { return currentY; } 55 public double getLineHeight() { return lineHeight; } 56 57 public boolean gotoY(double y) { 58 if (y < currentY) 59 throw new IllegalArgumentException  60 ("New Y can not be lower than old Y\n" + 61 "Old Y: " + currentY + " New Y: " + y); 62 if (y == currentY) return false; 63 sr = sl.split(y); 64 sl = sr.getBelow(); 65 sr = null; 66 currentY = y; 67 if (sl == null) return true; 68 69 newLineHeight(lineHeight); 70 return false; 71 } 72 73 public void newLineHeight(double lineHeight) { 74 this.lineHeight = lineHeight; 75 sr = sl.split(currentY+lineHeight); 76 77 if (sr.getAbove() != null) { 78 sortRow(sr.getAbove()); 79 } 80 currentRange = 0; 81 } 82 83 public int getNumRangeOnLine() { 84 return validRanges.size(); 85 } 86 public void resetRange() { 87 currentRange = 0; 88 } 89 90 public double [] nextRange() { 91 if (currentRange >= validRanges.size()) 92 return null; 93 return (double [])validRanges.get(currentRange++); 94 } 95 public void endLine() { 96 sl = sr.getBelow(); 97 sr = null; 98 currentY += lineHeight; 99 } 100 101 public boolean newLine() { 102 return newLine(lineHeight); 103 } 104 105 public boolean newLine(double lineHeight) { 106 if (sr != null) { 107 sl = sr.getBelow(); 108 } 109 sr = null; 110 if (sl == null) return false; 111 currentY += this.lineHeight; 112 newLineHeight(lineHeight); 113 return true; 114 } 115 116 public boolean newLineAt(double y, double lineHeight) { 117 if (sr != null) { 118 sl = sr.getBelow(); 119 } 120 sr = null; 121 if (sl == null) return false; 122 currentY = y; 123 newLineHeight(lineHeight); 124 return true; 125 } 126 127 128 public boolean done() { 129 return (sl == null); 130 } 131 132 public void sortRow(SegmentList sl) { 133 Transition [] segs = new Transition[sl.size()*2]; 135 Iterator iter = sl.iterator(); 136 int i=0; 137 while (iter.hasNext()) { 138 Segment seg = (Segment)iter.next(); 139 segs[i++] = new Transition(seg.minX(), true); 140 segs[i++] = new Transition(seg.maxX(), false); 141 } 143 144 Arrays.sort(segs, TransitionComp.COMP); 145 validRanges = new ArrayList (); 146 int count = 1; 147 double openStart =0; 148 for (i=1; i<segs.length; i++) { 150 Transition t = segs[i]; 151 if (t.up) { 152 if (count == 0) { 153 double cx = (openStart + t.loc)/2; 154 double cy = currentY + lineHeight/2; 155 if (flowShape.contains(new Point2D.Double (cx, cy))) { 157 validRanges.add(new double[]{openStart, t.loc}); 158 } 159 } 160 count++; 161 } else { 162 count--; 163 if (count == 0) 164 openStart = t.loc; 165 } 166 } 167 } 168 169 static class Transition { 170 public double loc; 171 public boolean up; 172 public Transition(double loc, boolean up) { 173 this.loc = loc; 174 this.up = up; 175 } 176 } 177 178 static class TransitionComp implements Comparator { 179 public static Comparator COMP = new TransitionComp(); 180 TransitionComp() { } 181 public int compare(Object o1, Object o2) { 182 Transition t1 = (Transition)o1; 183 Transition t2 = (Transition)o2; 184 if (t1.loc < t2.loc) return -1; 185 if (t1.loc > t2.loc) return 1; 186 if (t1.up) { 188 if (t2.up) return 0; return -1; } 191 if (t2.up) return 1; 192 return 0; 193 } 194 public boolean equals(Object comp) { 195 return (this == comp); 196 } 197 } 198 } 199 200 | Popular Tags |