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