1 | package org.expeditee.items.MagneticConstraint.Utilities;
|
---|
2 |
|
---|
3 | import java.util.LinkedList;
|
---|
4 |
|
---|
5 | import org.expeditee.core.Point;
|
---|
6 | import org.expeditee.core.bounds.AxisAlignedBoxBounds;
|
---|
7 | import org.expeditee.items.Text;
|
---|
8 |
|
---|
9 | @SuppressWarnings("serial")
|
---|
10 | public class Paragraph extends LinkedList<Line> {
|
---|
11 | private Paragraph() {
|
---|
12 | super();
|
---|
13 | }
|
---|
14 |
|
---|
15 | private Paragraph(final Paragraph toCopy) {
|
---|
16 | super(toCopy);
|
---|
17 | }
|
---|
18 |
|
---|
19 | public static Paragraph getParagraphFromLine(final Line line) {
|
---|
20 | final int lineHeight = Paragraph.getLineHeight(line);
|
---|
21 | return getParagraphFromLine(line, lineHeight, new Paragraph());
|
---|
22 | }
|
---|
23 |
|
---|
24 | public Paragraph deltaX(final int delta) {
|
---|
25 | for(final Line ln : this) ln.deltaX(delta);
|
---|
26 | return this;
|
---|
27 | }
|
---|
28 |
|
---|
29 | public Paragraph deltaY(final int delta) {
|
---|
30 | for(final Line ln : this) ln.deltaY(delta);
|
---|
31 | return this;
|
---|
32 | }
|
---|
33 |
|
---|
34 | public AxisAlignedBoxBounds getBoundingBox() {
|
---|
35 | AxisAlignedBoxBounds rect = null;
|
---|
36 | for(final Line ln : this) {
|
---|
37 | if (rect == null) rect = ln.getBoundingBox();
|
---|
38 | else rect.combineWith(ln.getBoundingBox());
|
---|
39 | }
|
---|
40 | return rect;
|
---|
41 | }
|
---|
42 |
|
---|
43 | public Paragraph next() {
|
---|
44 | final Line lastLineInParagraph = this.get(this.size() - 1);
|
---|
45 | final Line firstLineNotInParagraph = lastLineInParagraph.next();
|
---|
46 | if(firstLineNotInParagraph == null) return null;
|
---|
47 | else return Paragraph.getParagraphFromLine(firstLineNotInParagraph);
|
---|
48 | }
|
---|
49 |
|
---|
50 | public Point split(final Line splitAt) {
|
---|
51 | final int lineHeight = Paragraph.getLineHeight(splitAt);
|
---|
52 | //1. Get next line
|
---|
53 | final Line nextLine = splitAt.next();
|
---|
54 | //2. Is there a next line?
|
---|
55 | if(nextLine == null) {
|
---|
56 | //2a. No; then we simply need to calculate the position of where it would be and return that.
|
---|
57 | final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
|
---|
58 | return new Point((int)boundingBox.getMinX(), (int)boundingBox.getMaxY() + lineHeight);
|
---|
59 | }
|
---|
60 | //3. Get paragraph starting from the next line
|
---|
61 | final Paragraph paragraphStartingAtNextLine = getParagraphFromLine(nextLine);
|
---|
62 | //4. Are we still working for the same paragraph?
|
---|
63 | if(!this.containsAll(paragraphStartingAtNextLine)) {
|
---|
64 | //4b. No; then we simply need to calculate the position of the next line and return that.
|
---|
65 | final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
|
---|
66 | return new Point(((Text) splitAt.getFirst()).getX(), (int)boundingBox.getMaxY() + lineHeight);
|
---|
67 | }
|
---|
68 | //NB at this point we know that there are lines below our 'splitAt' line in the same paragraph so they need to be moved down.
|
---|
69 | //5. Move lines below 'splitAt' down by 'lineHeight'
|
---|
70 | paragraphStartingAtNextLine.deltaY(lineHeight);
|
---|
71 | //6. Return the position of the new line we have made space for.
|
---|
72 |
|
---|
73 | final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
|
---|
74 | final int x = ((Text) splitAt.getFirst()).getX();
|
---|
75 | return new Point(x, (int)boundingBox.getMaxY() + lineHeight);
|
---|
76 | }
|
---|
77 |
|
---|
78 | private static int getLineHeight(final Line line) {
|
---|
79 | return (int) (line.get(0).getBoundingBox().getHeight() * 1.2);
|
---|
80 | }
|
---|
81 |
|
---|
82 | private static Paragraph getParagraphFromLine(final Line line, final int lineHeight, final Paragraph acc) {
|
---|
83 | final Line nextLine = line.next();
|
---|
84 | if(nextLine == null || !isInSameParagraph(line, nextLine, lineHeight)) {
|
---|
85 | acc.add(line);
|
---|
86 | return acc;
|
---|
87 | } else {
|
---|
88 | final Paragraph paragraphSoFar = new Paragraph(acc);
|
---|
89 | paragraphSoFar.add(line);
|
---|
90 | return getParagraphFromLine(nextLine, lineHeight, paragraphSoFar);
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | private static boolean isInSameParagraph(final Line thisLine, final Line nextLine, final int lineHeight) {
|
---|
95 | if(!XGroupLogic.areInSameXGroup(thisLine.get(0), nextLine.get(0))) return false;
|
---|
96 | final AxisAlignedBoxBounds thisLineBoundingBox = thisLine.getBoundingBox();
|
---|
97 | final AxisAlignedBoxBounds nextLineBoundingBox = nextLine.getBoundingBox();
|
---|
98 | final Point toAdd = new Point(Math.min((int)thisLineBoundingBox.getMinX(),(int) nextLineBoundingBox.getMinX()), (int)thisLineBoundingBox.getMaxY() + lineHeight);
|
---|
99 | final AxisAlignedBoxBounds overlappingSection = new AxisAlignedBoxBounds(thisLineBoundingBox);
|
---|
100 | overlappingSection.combineWith(toAdd);
|
---|
101 | return overlappingSection.intersects(nextLineBoundingBox);
|
---|
102 | }
|
---|
103 | }
|
---|