From e4280c88ec2ad2f81b60d0f95ec70f6c543bf8a4 Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Fri, 6 Jun 2014 05:49:11 +0100 Subject: [PATCH] overlap bottom margin area of top element with top margin area of bottom element --- .../zlibrary/text/view/ZLTextLineInfo.java | 11 +++ .../zlibrary/text/view/ZLTextView.java | 67 ++++++++++++++----- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextLineInfo.java b/src/org/geometerplus/zlibrary/text/view/ZLTextLineInfo.java index c0864253d..d71d8a494 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextLineInfo.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextLineInfo.java @@ -35,7 +35,9 @@ final class ZLTextLineInfo { int Width; int Height; int Descent; + int VSpaceBefore; int VSpaceAfter; + boolean PreviousInfoUsed; int SpaceCounter; ZLTextStyle StartStyle; @@ -57,6 +59,14 @@ final class ZLTextLineInfo { return EndElementIndex == ParagraphCursorLength; } + void adjust(ZLTextLineInfo previous) { + if (!PreviousInfoUsed && previous != null) { + Height -= Math.min(previous.VSpaceAfter, VSpaceBefore); + PreviousInfoUsed = true; + } + } + + @Override public boolean equals(Object o) { ZLTextLineInfo info = (ZLTextLineInfo)o; return @@ -65,6 +75,7 @@ final class ZLTextLineInfo { (StartCharIndex == info.StartCharIndex); } + @Override public int hashCode() { return ParagraphCursor.hashCode() + StartElementIndex + 239 * StartCharIndex; } diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java index 04fbc835a..767ece6cd 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java @@ -495,7 +495,9 @@ public abstract class ZLTextView extends ZLTextViewBase { int x = getLeftMargin(); int y = getTopMargin(); int index = 0; + ZLTextLineInfo previousInfo = null; for (ZLTextLineInfo info : lineInfos) { + info.adjust(previousInfo); prepareTextLine(page, info, x, y); y += info.Height + info.Descent + info.VSpaceAfter; labels[++index] = page.TextElementMap.size(); @@ -503,6 +505,7 @@ public abstract class ZLTextView extends ZLTextViewBase { y = getTopMargin(); x += page.getTextWidth() + getSpaceBetweenColumns(); } + previousInfo = info; } x = getLeftMargin(); @@ -967,15 +970,17 @@ public abstract class ZLTextView extends ZLTextViewBase { page.LineInfos.clear(); page.Column0Height = 0; boolean nextParagraph; + ZLTextLineInfo info = null; do { + final ZLTextLineInfo previousInfo = info; resetTextStyle(); final ZLTextParagraphCursor paragraphCursor = result.getParagraphCursor(); final int wordIndex = result.getElementIndex(); applyStyleChanges(paragraphCursor, 0, wordIndex); - ZLTextLineInfo info = new ZLTextLineInfo(paragraphCursor, wordIndex, result.getCharIndex(), getTextStyle()); + info = new ZLTextLineInfo(paragraphCursor, wordIndex, result.getCharIndex(), getTextStyle()); final int endIndex = info.ParagraphCursorLength; while (info.EndElementIndex != endIndex) { - info = processTextLine(page, paragraphCursor, info.EndElementIndex, info.EndCharIndex, endIndex); + info = processTextLine(page, paragraphCursor, info.EndElementIndex, info.EndCharIndex, endIndex, previousInfo); textAreaHeight -= info.Height + info.Descent; if (textAreaHeight < 0 && page.LineInfos.size() > page.Column0Height) { if (page.Column0Height == 0 && page.twoColumnView()) { @@ -1022,12 +1027,14 @@ public abstract class ZLTextView extends ZLTextViewBase { ZLTextParagraphCursor paragraphCursor, final int startIndex, final int startCharIndex, - final int endIndex + final int endIndex, + ZLTextLineInfo previousInfo ) { final ZLPaintContext context = getContext(); final ZLTextLineInfo info = new ZLTextLineInfo(paragraphCursor, startIndex, startCharIndex, getTextStyle()); final ZLTextLineInfo cachedInfo = myLineInfoCache.get(info); if (cachedInfo != null) { + cachedInfo.adjust(previousInfo); applyStyleChanges(paragraphCursor, startIndex, cachedInfo.EndElementIndex); return cachedInfo; } @@ -1200,7 +1207,14 @@ public abstract class ZLTextView extends ZLTextViewBase { setTextStyle(storedStyle); if (isFirstLine) { - info.Height += info.StartStyle.getSpaceBefore(metrics()); + info.VSpaceBefore = info.StartStyle.getSpaceBefore(metrics()); + if (previousInfo != null) { + info.PreviousInfoUsed = true; + info.Height += Math.max(0, info.VSpaceBefore - previousInfo.VSpaceAfter); + } else { + info.PreviousInfoUsed = false; + info.Height += info.VSpaceBefore; + } } if (info.isEndOfParagraph()) { info.VSpaceAfter = getTextStyle().getSpaceAfter(metrics()); @@ -1520,25 +1534,37 @@ public abstract class ZLTextView extends ZLTextViewBase { return (unit == SizeUnit.PIXEL_UNIT) ? (info.Height + info.Descent + info.VSpaceAfter) : (info.IsVisible ? 1 : 0); } - private int paragraphSize(ZLTextPage page, ZLTextWordCursor cursor, boolean beforeCurrentPosition, int unit) { + private static class ParagraphSize { + public int Height; + public int TopMargin; + public int BottomMargin; + } + + private ParagraphSize paragraphSize(ZLTextPage page, ZLTextWordCursor cursor, boolean beforeCurrentPosition, int unit) { + final ParagraphSize size = new ParagraphSize(); + final ZLTextParagraphCursor paragraphCursor = cursor.getParagraphCursor(); if (paragraphCursor == null) { - return 0; + return size; } final int endElementIndex = beforeCurrentPosition ? cursor.getElementIndex() : paragraphCursor.getParagraphLength(); resetTextStyle(); - int size = 0; - int wordIndex = 0; int charIndex = 0; + ZLTextLineInfo info = null; while (wordIndex != endElementIndex) { - ZLTextLineInfo info = processTextLine(page, paragraphCursor, wordIndex, charIndex, endElementIndex); + final ZLTextLineInfo prev = info; + info = processTextLine(page, paragraphCursor, wordIndex, charIndex, endElementIndex, prev); wordIndex = info.EndElementIndex; charIndex = info.EndCharIndex; - size += infoSize(info, unit); + size.Height += infoSize(info, unit); + if (prev == null) { + size.TopMargin = info.VSpaceBefore; + } + size.BottomMargin = info.VSpaceAfter; } return size; @@ -1554,8 +1580,9 @@ public abstract class ZLTextView extends ZLTextViewBase { resetTextStyle(); applyStyleChanges(paragraphCursor, 0, cursor.getElementIndex()); - while (!cursor.isEndOfParagraph() && (size > 0)) { - ZLTextLineInfo info = processTextLine(page, paragraphCursor, cursor.getElementIndex(), cursor.getCharIndex(), endElementIndex); + ZLTextLineInfo info = null; + while (!cursor.isEndOfParagraph() && size > 0) { + info = processTextLine(page, paragraphCursor, cursor.getElementIndex(), cursor.getCharIndex(), endElementIndex, info); cursor.moveTo(info.EndElementIndex, info.EndCharIndex); size -= infoSize(info, unit); } @@ -1569,12 +1596,14 @@ public abstract class ZLTextView extends ZLTextViewBase { return end; } - private ZLTextWordCursor findStart(ZLTextPage page, ZLTextWordCursor end, int unit, int size) { + private ZLTextWordCursor findStart(ZLTextPage page, ZLTextWordCursor end, int unit, int height) { final ZLTextWordCursor start = new ZLTextWordCursor(end); - size -= paragraphSize(page, start, true, unit); + ParagraphSize size = paragraphSize(page, start, true, unit); + height -= size.Height; boolean positionChanged = !start.isStartOfParagraph(); start.moveToParagraphStart(); - while (size > 0) { + while (height > 0) { + final ParagraphSize previousSize = size; if (positionChanged && start.getParagraphCursor().isEndOfSection()) { break; } @@ -1584,9 +1613,13 @@ public abstract class ZLTextView extends ZLTextViewBase { if (!start.getParagraphCursor().isEndOfSection()) { positionChanged = true; } - size -= paragraphSize(page, start, false, unit); + size = paragraphSize(page, start, false, unit); + height -= size.Height; + if (previousSize != null) { + height += Math.min(size.BottomMargin, previousSize.TopMargin); + } } - skip(page, start, unit, -size); + skip(page, start, unit, -height); if (unit == SizeUnit.PIXEL_UNIT) { boolean sameStart = start.samePositionAs(end);