Skip to content
This repository has been archived by the owner on Nov 9, 2018. It is now read-only.

Commit

Permalink
Separates volume breaking and removes some (previously) disabled code
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Håkansson committed Apr 29, 2016
1 parent b025040 commit 5ca0911
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 151 deletions.
Expand Up @@ -21,16 +21,13 @@
import org.daisy.dotify.api.translator.TextBorderFactoryMakerService;
import org.daisy.dotify.api.writer.PagedMediaWriter;
import org.daisy.dotify.common.io.StateObject;
import org.daisy.dotify.common.layout.SplitPoint;
import org.daisy.dotify.common.layout.SplitPointHandler;


/**
* Breaks flow into rows, page related block properties are left to next step
* @author Joel Håkansson
*/
public class FormatterImpl implements Formatter {
//private final static char ZERO_WIDTH_SPACE = '\u200b';
private final static int DEFAULT_SPLITTER_MAX = 50;

private final HashMap<String, TableOfContentsImpl> tocs;
Expand Down Expand Up @@ -139,7 +136,6 @@ private Iterable<Volume> getVolumes() {
ArrayList<AnchorData> ad;
PageStruct ps;
VariablesHandler vh = crh.getVariables();
SplitPointHandler<Sheet> volSplitter = new SplitPointHandler<>();
//splitter.setSplitterMax(Integer.MAX_VALUE);
//FIXME: replace the following try/catch with the line above
//This code is here for compatibility with regression tests and can be removed once
Expand All @@ -154,27 +150,14 @@ private Iterable<Volume> getVolumes() {
}

while (!ok) {
//BreakPointHandler volBreaks;
List<Sheet> units;
try {
ps = contentPaginator.paginate(crh, new DefaultContext(null, null));
//String breakpoints = ps.buildBreakpointString();
//logger.fine(breakpoints.replace(ZERO_WIDTH_SPACE, '-'));
//volBreaks = new BreakPointHandler(breakpoints);
units = ps.buildSplitPoints();
//logger.fine(PageStruct.toString(units));
} catch (PaginatorException e) {
throw new RuntimeException("Error while reformatting.", e);
}
int sheetCount = 0;
int totalPageCount = 0;

//System.out.println("volcount "+volumeCount() + " sheets " + sheets);
boolean ok2 = true;
totalOverheadCount = 0;
ret = new ArrayList<>();
int pageIndex = 0;

VolumeProvider volumeProvider = new VolumeProvider(contentPaginator, crh);

for (int i=1;i<= vh.getVolumeCount();i++) {
if (j>1 && splitter.getSplitterMax()!=getVolumeMaxSize(i, vh.getVolumeCount())) {
logger.warning("Implementation does not support different target volume size. All volumes must have the same target size.");
Expand All @@ -188,61 +171,40 @@ private Iterable<Volume> getVolumes() {
totalOverheadCount += volume.getOverhead();

{
/*
int contentSheets = getBreakPoint(volBreaks,
List<Sheet> contents = volumeProvider.nextVolume(
(i==vh.getVolumeCount()?splitter.getSplitterMax():splitter.sheetsInVolume(i)),
volume.getOverhead());*/
SplitPoint<Sheet> sp = getSplitPoint(volSplitter,
(i==vh.getVolumeCount()?splitter.getSplitterMax():splitter.sheetsInVolume(i)),
volume.getOverhead(),
units);
volume.getOverhead(),
splitter.getSplitterMax(), ad
);

int contentSheets = sp.getHead().size();
int contentSheets = contents.size();
sheetCount += contentSheets;
units = sp.getTail();
setTargetVolSize(volume, contentSheets + volume.getOverhead());
logger.fine("Sheets in volume " + i + ": " + (contentSheets+volume.getOverhead()) +
", content:" + contentSheets +
", overhead:" + volume.getOverhead());

Iterable<PageSequence> body = sequencesFromSheets(sp.getHead());
int pageCount = countPages(sp.getHead());
// TODO: In a volume-by-volume scenario, how can we make this work
ps.setVolumeScope(i, pageIndex, pageIndex+pageCount);
pageIndex += pageCount;
totalPageCount += pageCount;
for (PageSequence seq : body) {
for (PageImpl p : seq.getPages()) {
for (String id : p.getIdentifiers()) {
crh.setVolumeNumber(id, i);
}
if (p.getAnchors().size()>0) {
ad.add(new AnchorData(p.getPageIndex(), p.getAnchors()));
}
}
}
volume.setBody(body);

volume.setBody(contents);
volume.setPostVolData(updateVolumeContents(i, ad, false));
crh.setAnchorData(i, ad);

ret.add(volume);
}
}
if (!units.isEmpty()) {
sheetCount += units.size();
totalPageCount += countPages(units);
int totalPageCount = volumeProvider.getTotalPageCount();
if (volumeProvider.hasNext()) {
sheetCount += volumeProvider.getRemaining().size();
totalPageCount += countPages(volumeProvider.getRemaining());
}
splitter.setSplitterMax(getVolumeMaxSize(1, vh.getVolumeCount()));
splitter.updateSheetCount(sheetCount + totalOverheadCount);
if (!units.isEmpty()) {
if (volumeProvider.hasNext()) {
ok2 = false;
logger.fine("There is more content... sheets: " + units + ", pages: " +(totalPageCount-pageIndex));
logger.fine("There is more content... sheets: " + volumeProvider.getRemaining() + ", pages: " +(totalPageCount-volumeProvider.getPageIndex()));
if (!isDirty() && j>1) {
splitter.adjustVolumeCount(sheetCount+totalOverheadCount);
}
}
if (!isDirty() && pageIndex==totalPageCount && ok2) {
if (!isDirty() && volumeProvider.getPageIndex()==totalPageCount && ok2) {
//everything fits
ok = true;
} else if (j>9) {
Expand All @@ -256,57 +218,13 @@ private Iterable<Volume> getVolumes() {
return ret;
}

private static int countPages(List<Sheet> sheets) {
static int countPages(List<Sheet> sheets) {
int ret = 0;
for (Sheet s : sheets) {
ret += s.getPages().size();
}
return ret;
}

private static Iterable<PageSequence> sequencesFromSheets(List<Sheet> sheets) {
PageStruct ret = new PageStruct();
PageSequence currentSeq = null;
for (Sheet s : sheets) {
for (PageImpl p : s.getPages()) {
if (ret.empty() || currentSeq!=p.getSequenceParent()) {
currentSeq = p.getSequenceParent();
ret.add(new PageSequence(ret, currentSeq.getLayoutMaster(), currentSeq.getPageNumberOffset()));
}
((PageSequence)ret.peek()).addPage(p);
}
}
return ret;
}

/*
private int getBreakPoint(BreakPointHandler volBreaks, int targetSheetsInVolume, int overhead) {
int contentSheets = targetSheetsInVolume-overhead;
BreakPoint bp;
{
int offset = -1;
do {
offset++;
bp = volBreaks.copy().nextRow(contentSheets+offset, false);
} while (bp.getHead().length()<contentSheets && targetSheetsInVolume+offset<splitter.getSplitterMax());
bp = volBreaks.nextRow(contentSheets + offset, true);
}
return bp.getHead().length();
}*/

private SplitPoint<Sheet> getSplitPoint(SplitPointHandler<Sheet> volBreaks, int targetSheetsInVolume, int overhead, List<Sheet> data) {
int contentSheets = targetSheetsInVolume-overhead;
SplitPoint<Sheet> bp;
{
int offset = -1;
do {
offset++;
bp = volBreaks.split(contentSheets+offset, false, data);
} while (bp.getHead().size()<contentSheets && targetSheetsInVolume+offset<splitter.getSplitterMax());
bp = volBreaks.split(contentSheets + offset, true, data);
}
return bp;
}

private PageStruct updateVolumeContents(int volumeNumber, ArrayList<AnchorData> ad, boolean pre) {
DefaultContext c = new DefaultContext(volumeNumber, crh.getVariables().getVolumeCount());
Expand Down
Expand Up @@ -12,7 +12,6 @@
* @author Joel Håkansson
*/
class PageStruct implements Iterable<PageSequence> {
//private final static char ZERO_WIDTH_SPACE = '\u200b';
private final Stack<PageSequence> seqs;
private final Stack<PageImpl> pages;
private final Map<Integer, PageView> volumeViews;
Expand Down Expand Up @@ -54,41 +53,6 @@ static int countSheets(Iterable<PageSequence> seqs) {
return sheets;
}

/**
* Builds a string with possible breakpoints for the contents of this page struct.
* Each sheet is represented by a lower case 's' and breakpoints are represented
* by zero width space (0x200b).
* @return returns a string with allowed breakpoints
*/
/*
String buildBreakpointString() {
StringBuilder res = new StringBuilder();
boolean volBreakAllowed = true;
for (PageSequence seq : seqs) {
StringBuilder sb = new StringBuilder();
LayoutMaster lm = seq.getLayoutMaster();
int pageIndex=0;
for (PageImpl p : seq.getPages()) {
if (!lm.duplex() || pageIndex%2==0) {
volBreakAllowed = true;
sb.append("s");
}
volBreakAllowed &= p.allowsVolumeBreak();
trimEnd(sb, p);
if (!lm.duplex() || pageIndex%2==1) {
if (volBreakAllowed) {
sb.append(ZERO_WIDTH_SPACE);
}
}
pageIndex++;
}
res.append(sb);
res.append(ZERO_WIDTH_SPACE);
}
return res.toString();
}
*/

List<Sheet> buildSplitPoints() {
List<Sheet.Builder> ret = new ArrayList<>();
boolean volBreakAllowed = true;
Expand Down Expand Up @@ -139,21 +103,6 @@ private List<Sheet> buildAll(List<Sheet.Builder> builders) {
}
return ret;
}
/*
private void trimEnd(StringBuilder sb, PageImpl p) {
int i = 0;
int x = sb.length()-1;
while (i<p.keepPreviousSheets() && x>0) {
if (sb.charAt(x)=='s') {
x--;
i++;
}
if (sb.charAt(x)==ZERO_WIDTH_SPACE) {
sb.deleteCharAt(x);
x--;
}
}
}*/

private void setPreviousSheet(List<Sheet.Builder> sb, PageImpl p) {
int i = 0;
Expand Down
Expand Up @@ -35,9 +35,24 @@ public Iterable<PageSequence> getBody() {
return body;
}

public void setBody(Iterable<PageSequence> body) {
public void setBody(List<Sheet> body) {
ret = null;
this.body = body;
this.body = sequencesFromSheets(body);
}

private static Iterable<PageSequence> sequencesFromSheets(List<Sheet> sheets) {
PageStruct ret = new PageStruct();
PageSequence currentSeq = null;
for (Sheet s : sheets) {
for (PageImpl p : s.getPages()) {
if (ret.empty() || currentSeq!=p.getSequenceParent()) {
currentSeq = p.getSequenceParent();
ret.add(new PageSequence(ret, currentSeq.getLayoutMaster(), currentSeq.getPageNumberOffset()));
}
((PageSequence)ret.peek()).addPage(p);
}
}
return ret;
}

public void setPreVolData(Iterable<PageSequence> preVolData) {
Expand Down
@@ -0,0 +1,96 @@
package org.daisy.dotify.formatter.impl;

import java.util.ArrayList;
import java.util.List;

import org.daisy.dotify.common.layout.SplitPoint;
import org.daisy.dotify.common.layout.SplitPointHandler;

/**
* Provides contents for a volume
* @author Joel Håkansson
*
*/
public class VolumeProvider {
private List<Sheet> units;
private final SplitPointHandler<Sheet> volSplitter = new SplitPointHandler<>();
private final CrossReferenceHandler crh;
PageStruct ps;
private int pageIndex = 0;
//private int totalPageCount = 0;
private int i=0;

public VolumeProvider(PageStructBuilder contentPaginator, CrossReferenceHandler crh) {
this.crh = crh;
try {
ps = contentPaginator.paginate(crh, new DefaultContext(null, null));
units = ps.buildSplitPoints();
} catch (PaginatorException e) {
throw new RuntimeException("Error while reformatting.", e);
}
}

List<Sheet> nextVolume(int targetSheetsInVolume, int overhead, int splitterMax, ArrayList<AnchorData> ad) {
i++;
SplitPoint<Sheet> sp = getSplitPoint(targetSheetsInVolume, overhead, splitterMax);
units = sp.getTail();
List<Sheet> contents = sp.getHead();
int pageCount = FormatterImpl.countPages(contents);
// TODO: In a volume-by-volume scenario, how can we make this work
ps.setVolumeScope(i, pageIndex, pageIndex+pageCount);
pageIndex += pageCount;
//totalPageCount += pageCount;
for (Sheet sheet : contents) {
for (PageImpl p : sheet.getPages()) {
for (String id : p.getIdentifiers()) {
crh.setVolumeNumber(id, i);
}
if (p.getAnchors().size()>0) {
ad.add(new AnchorData(p.getPageIndex(), p.getAnchors()));
}
}
}
return contents;
}

/**
* The total number of pages provided so far
* @return the number of pages
*/
int getTotalPageCount() {
//return totalPageCount;
return pageIndex;
}

/**
* Gets the current page index.
* @return
*/
int getPageIndex() {
return pageIndex;
}

private SplitPoint<Sheet> getSplitPoint(int targetSheetsInVolume, int overhead, int splitterMax) {
int contentSheets = targetSheetsInVolume-overhead;
SplitPoint<Sheet> bp;
{
int offset = -1;
do {
offset++;
bp = volSplitter.split(contentSheets+offset, false, units);
} while (bp.getHead().size()<contentSheets && targetSheetsInVolume+offset<splitterMax);
bp = volSplitter.split(contentSheets + offset, true, units);
}
return bp;
}

boolean hasNext() {
return !units.isEmpty();
}

List<Sheet> getRemaining() {
return units;
}


}

0 comments on commit 5ca0911

Please sign in to comment.