From e0ce711b8c2fa1c732c4bdf6f35b379e395a1546 Mon Sep 17 00:00:00 2001 From: gigaherz Date: Fri, 1 Jun 2018 20:49:03 +0200 Subject: [PATCH] Initial implementation of automatic pagination --- .../guidebook/guidebook/BookDocument.java | 164 +++++++------ .../guidebook/guidebook/IBookGraphics.java | 3 +- .../{PageRef.java => SectionRef.java} | 32 +-- .../guidebook/client/BookRendering.java | 216 +++++++++++++----- .../guidebook/drawing/VisualElement.java | 2 - .../guidebook/drawing/VisualLink.java | 4 +- .../guidebook/drawing/VisualStack.java | 4 +- .../guidebook/elements/ElementImage.java | 10 +- .../guidebook/elements/ElementLink.java | 6 +- .../guidebook/elements/ElementParagraph.java | 14 +- .../guidebook/elements/ElementStack.java | 11 +- .../recipe/CraftingRecipeProvider.java | 2 +- 12 files changed, 308 insertions(+), 160 deletions(-) rename src/main/java/gigaherz/guidebook/guidebook/{PageRef.java => SectionRef.java} (79%) diff --git a/src/main/java/gigaherz/guidebook/guidebook/BookDocument.java b/src/main/java/gigaherz/guidebook/guidebook/BookDocument.java index 7bfdabd..b18c322 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/BookDocument.java +++ b/src/main/java/gigaherz/guidebook/guidebook/BookDocument.java @@ -11,6 +11,7 @@ import gigaherz.guidebook.guidebook.conditions.IDisplayCondition; import gigaherz.guidebook.guidebook.drawing.Point; import gigaherz.guidebook.guidebook.drawing.Rect; +import gigaherz.guidebook.guidebook.drawing.VisualElement; import gigaherz.guidebook.guidebook.drawing.VisualPage; import gigaherz.guidebook.guidebook.elements.*; import gigaherz.guidebook.guidebook.templates.TemplateDefinition; @@ -34,9 +35,7 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.io.InputStream; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class BookDocument { @@ -49,15 +48,14 @@ public class BookDocument private ResourceLocation bookCover; final List chapters = Lists.newArrayList(); - private Table stackLinks = HashBasedTable.create(); + private Table stackLinks = HashBasedTable.create(); final Map chaptersByName = Maps.newHashMap(); - final Map pagesByName = Maps.newHashMap(); + final Map sectionsByName = Maps.newHashMap(); private final Map templates = Maps.newHashMap(); private final Map conditions = Maps.newHashMap(); - private int totalPairs = 0; private IBookGraphics rendering; public BookDocument(ResourceLocation bookLocation) @@ -88,7 +86,7 @@ public SectionData getChapter(int i) } @Nullable - public PageRef getStackLink(ItemStack stack) + public SectionRef getStackLink(ItemStack stack) { Item item = stack.getItem(); int damage = stack.getItemDamage(); @@ -104,11 +102,6 @@ else if (stackLinks.contains(item, -1)) return null; } - public int getTotalPairCount() - { - return totalPairs; - } - public float getFontSize() { return fontSize; @@ -127,7 +120,7 @@ public void findTextures(Set textures) // TODO: Add texture locations when implemented for (SectionData chapter : chapters) { - for (PageData page : chapter.pages) + for (PageData page : chapter.sections) { for (Element element : page.elements) { @@ -142,8 +135,8 @@ public void initializeWithLoadError(String error) SectionData ch = new SectionData(0); chapters.add(ch); - PageData pg = new PageData(0); - ch.pages.add(pg); + PageData pg = new PageData(); + ch.sections.add(pg); pg.elements.add(ElementParagraph.of("Error loading book:")); pg.elements.add(ElementParagraph.of(TextFormatting.RED + error)); @@ -156,10 +149,8 @@ public boolean parseBook(InputStream stream) chapters.clear(); bookName = ""; bookCover = null; - totalPairs = 0; fontSize = DEFAULT_FONT_SIZE; chaptersByName.clear(); - pagesByName.clear(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); @@ -232,14 +223,6 @@ else if(nodeName.equals("conditions")) parseConditions(firstLevelNode); } } - - int prevCount = 0; - for (SectionData chapter : chapters) - { - chapter.startPair = prevCount; - prevCount += chapter.pagePairs; - } - totalPairs = prevCount; } catch (IOException | ParserConfigurationException | SAXException e) { @@ -357,15 +340,29 @@ private void parseChapter(Node chapterItem) { parsePage(chapter, pageItem); } + else if (nodeName.equals("section")) + { + parseSection(chapter, pageItem); + } } - - chapter.pagePairs = (chapter.pages.size() + 1) / 2; } private void parsePage(SectionData chapter, Node pageItem) { - PageData page = new PageData(chapter.pages.size()); - chapter.pages.add(page); + PageData page = new PageData(); + parseSection(chapter, pageItem, page); + } + + private void parseSection(SectionData chapter, Node pageItem) + { + PageData page = new PageGroup(); + parseSection(chapter, pageItem, page); + } + + private void parseSection(SectionData chapter, Node pageItem, PageData page) + { + int num = chapter.sections.size(); + chapter.sections.add(page); if (pageItem.hasAttributes()) { @@ -374,14 +371,15 @@ private void parsePage(SectionData chapter, Node pageItem) if (n != null) { page.id = n.getTextContent(); - pagesByName.put(page.id, new PageRef(chapter.num, page.num)); - chapter.pagesByName.put(page.id, page.num); + sectionsByName.put(page.id, new SectionRef(chapter.num, num)); + chapter.sectionsByName.put(page.id, num); } } parseChildElements(pageItem, page.elements, templates, true); } + public static void parseChildElements(Node pageItem, List elements, Map templates, boolean generateParagraphs) { NodeList elementsList = pageItem.getChildNodes(); @@ -632,7 +630,7 @@ private void parseStackLinks(Node refsItem) } String ref = refItem.getTextContent(); - stackLinks.put(item, damage_value, PageRef.fromString(ref)); + stackLinks.put(item, damage_value, SectionRef.fromString(ref)); } } } @@ -657,20 +655,33 @@ public class SectionData public String id; public IDisplayCondition condition; - public final List pages = Lists.newArrayList(); - public final Map pagesByName = Maps.newHashMap(); - - public int pagePairs; - public int startPair; + public final List sections = Lists.newArrayList(); + public final Map sectionsByName = Maps.newHashMap(); private SectionData(int num) { this.num = num; } + } + + public class PageData + { + public String id; - public int pairCount() + public final List elements = Lists.newArrayList(); + + public List reflow(Rect leftBounds, Rect rightBounds, int pageNumber) { - return pagePairs; + VisualPage page = new VisualPage(); + + Rect pageBounds = (pageNumber & 1) == 0 ? leftBounds : rightBounds; + int top = pageBounds.position.y; + for(Element element : elements) + { + top = element.reflow(page.children, getRendering(), new Rect(new Point(pageBounds.position.x, top), pageBounds.size), pageBounds); + } + + return Collections.singletonList(page); } } @@ -693,55 +704,68 @@ public int pairCount() * * */ - public class PageGroup + public class PageGroup extends PageData { - public final int num; - public String id; - - public final List elements = Lists.newArrayList(); - - private PageGroup(int num) + @Override + public List reflow(Rect leftBounds, Rect rightBounds, int pageNumber) { - this.num = num; - } + List pages = Lists.newArrayList(); - public VisualPage reflow(Rect pageBounds) - { VisualPage page = new VisualPage(); + Rect pageBounds = (pageNumber & 1) == 0 ? leftBounds : rightBounds; int top = pageBounds.position.y; - for(Element element : elements) + for (Element element : elements) { top = element.reflow(page.children, getRendering(), new Rect(new Point(pageBounds.position.x, top), pageBounds.size), pageBounds); } - return page; - } - } + boolean needsRepagination = false; + for (VisualElement child : page.children) + { + if (child.position.y + child.size.height > (pageBounds.position.y + pageBounds.size.height)) + { + needsRepagination = true; + } + } - public class PageData - { - public final int num; - public String id; + if (needsRepagination) + { + VisualPage page2 = new VisualPage(); - public final List elements = Lists.newArrayList(); + Rect pageBounds2; + int offsetY = 0; + int offsetX = 0; + for (VisualElement child : page.children) + { + int cpy = child.position.y + offsetY; + if (cpy + child.size.height > (pageBounds.position.y + pageBounds.size.height) + && child.position.y > pageBounds.position.y) + { + pages.add(page2); + page2 = new VisualPage(); - private PageData(int num) - { - this.num = num; - } + pageNumber++; + pageBounds2 = (pageNumber & 1) == 0 ? leftBounds : rightBounds; + offsetY = pageBounds.position.y - child.position.y; + offsetX = pageBounds2.position.x - pageBounds.position.x; + } - public VisualPage reflow(Rect pageBounds) - { - VisualPage page = new VisualPage(); + child.position = new Point( + child.position.x + offsetX, + child.position.y + offsetY); + page2.children.add(child); - int top = pageBounds.position.y; - for(Element element : elements) + } + + pages.add(page2); + } + else { - top = element.reflow(page.children, getRendering(), new Rect(new Point(pageBounds.position.x, top), pageBounds.size), pageBounds); + pages.add(page); } - return page; + return pages; } } } diff --git a/src/main/java/gigaherz/guidebook/guidebook/IBookGraphics.java b/src/main/java/gigaherz/guidebook/guidebook/IBookGraphics.java index ccaa6a4..6a565d7 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/IBookGraphics.java +++ b/src/main/java/gigaherz/guidebook/guidebook/IBookGraphics.java @@ -4,7 +4,6 @@ import gigaherz.guidebook.guidebook.drawing.VisualElement; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; -import org.lwjgl.util.Rectangle; import java.util.List; @@ -24,7 +23,7 @@ public interface IBookGraphics boolean canGoPrevChapter(); - void navigateTo(PageRef target); + void navigateTo(SectionRef target); void nextPage(); diff --git a/src/main/java/gigaherz/guidebook/guidebook/PageRef.java b/src/main/java/gigaherz/guidebook/guidebook/SectionRef.java similarity index 79% rename from src/main/java/gigaherz/guidebook/guidebook/PageRef.java rename to src/main/java/gigaherz/guidebook/guidebook/SectionRef.java index d286c67..cf4b7c1 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/PageRef.java +++ b/src/main/java/gigaherz/guidebook/guidebook/SectionRef.java @@ -7,7 +7,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -public class PageRef +public class SectionRef { public int chapter; public int page; @@ -16,14 +16,14 @@ public class PageRef public String chapterName; public String pageName; - public PageRef(int chapter, int page) + public SectionRef(int chapter, int page) { this.chapter = chapter; this.page = page; resolvedNames = true; } - public PageRef(String chapter, @Nullable String page) + public SectionRef(String chapter, @Nullable String page) { this.chapterName = chapter; this.pageName = page; @@ -31,7 +31,7 @@ public PageRef(String chapter, @Nullable String page) /** * @param bookDocument the book which contains the referenced page - * @return false if the {@link PageRef} has no valid target + * @return false if the {@link SectionRef} has no valid target */ public boolean resolve(BookDocument bookDocument) { @@ -60,13 +60,13 @@ public boolean resolve(BookDocument bookDocument) } else { - page = bookDocument.chapters.get(chapter).pagesByName.get(pageName); + page = bookDocument.chapters.get(chapter).sectionsByName.get(pageName); } } } else if (!Strings.isNullOrEmpty(pageName)) { - PageRef temp = bookDocument.pagesByName.get(pageName); + SectionRef temp = bookDocument.sectionsByName.get(pageName); temp.resolve(bookDocument); chapter = temp.chapter; page = temp.page; @@ -97,14 +97,14 @@ else if (!Strings.isNullOrEmpty(pageName)) return true; } - public PageRef copy() + public SectionRef copy() { - return new PageRef(chapter, page); + return new SectionRef(chapter, page); } /** - * Thrown by {@link PageRef#resolve(BookDocument)} in any case that normally wouldn't cause an exception - * but still signifies that the {@link PageRef} has no valid target and is therefore invalid. + * Thrown by {@link SectionRef#resolve(BookDocument)} in any case that normally wouldn't cause an exception + * but still signifies that the {@link SectionRef} has no valid target and is therefore invalid. */ public static class InvalidPageRefException extends Exception { @@ -115,29 +115,29 @@ public InvalidPageRefException(String s) } /** - * Parses a String into a {@link PageRef}. + * Parses a String into a {@link SectionRef}. * * @param refString the string to be parsed */ - public static PageRef fromString(@Nonnull String refString) + public static SectionRef fromString(@Nonnull String refString) { if (refString.indexOf(':') >= 0) { String[] parts = refString.split(":"); - return new PageRef(parts[0], parts[1]); + return new SectionRef(parts[0], parts[1]); } else { - return new PageRef(refString, null); + return new SectionRef(refString, null); } } @Override public boolean equals(Object obj) { - if (!(obj instanceof PageRef)) + if (!(obj instanceof SectionRef)) return false; - PageRef pr = (PageRef)obj; + SectionRef pr = (SectionRef)obj; return resolvedNames && pr.resolvedNames && pr.chapter == chapter && pr.page == page; } diff --git a/src/main/java/gigaherz/guidebook/guidebook/client/BookRendering.java b/src/main/java/gigaherz/guidebook/guidebook/client/BookRendering.java index 6add222..3f29694 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/client/BookRendering.java +++ b/src/main/java/gigaherz/guidebook/guidebook/client/BookRendering.java @@ -1,5 +1,6 @@ package gigaherz.guidebook.guidebook.client; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import gigaherz.guidebook.GuidebookMod; @@ -18,9 +19,9 @@ import org.lwjgl.opengl.GL11; import javax.annotation.Nullable; -import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class BookRendering implements IBookGraphics { @@ -31,7 +32,7 @@ public class BookRendering implements IBookGraphics public static final int DEFAULT_VERTICAL_MARGIN = 18; private BookDocument book; - private Map visualPages = Maps.newHashMap(); + int scaledWidth; int scaledHeight; @@ -46,6 +47,28 @@ public class BookRendering implements IBookGraphics private int pageWidth = bookWidth / 2 - innerMargin - outerMargin; private int pageHeight = bookHeight - verticalMargin; + private class PageRef + { + public int chapter; + public int page; + + public PageRef(int currentChapter, int currentPage) + { + chapter = currentChapter; + page = currentPage; + } + } + + private class VisualChapter + { + public final List pages = Lists.newArrayList(); + public final Map pagesByName = Maps.newHashMap(); + public int startPair; + public int totalPairs; + } + + final List chapters = Lists.newArrayList(); + final java.util.Stack history = new java.util.Stack<>(); private int currentChapter = 0; private int currentPair = 0; @@ -143,7 +166,7 @@ public boolean canGoBack() @Override public boolean canGoNextPage() { - return (currentPair + 1 < book.getChapter(currentChapter).pagePairs || currentChapter + 1 < book.chapterCount()); + return (currentPair + 1 < getVisualChapter(currentChapter).totalPairs || currentChapter + 1 < book.chapterCount()); } @Override @@ -165,19 +188,19 @@ public boolean canGoPrevChapter() } @Override - public void navigateTo(final PageRef target) + public void navigateTo(final SectionRef target) { if (!target.resolve(book)) return; pushHistory(); currentChapter = Math.max(0, Math.min(book.chapterCount() - 1, target.chapter)); - currentPair = Math.max(0, Math.min(book.getChapter(currentChapter).pagePairs - 1, target.page / 2)); + currentPair = Math.max(0, Math.min(getVisualChapter(currentChapter).totalPairs - 1, target.page / 2)); } @Override public void nextPage() { - if (currentPair + 1 < book.getChapter(currentChapter).pagePairs) + if (currentPair + 1 < getVisualChapter(currentChapter).totalPairs) { pushHistory(); currentPair++; @@ -202,7 +225,7 @@ else if (currentChapter > 0) { pushHistory(); currentChapter--; - currentPair = book.getChapter(currentChapter).pairCount() - 1; + currentPair = getVisualChapter(currentChapter).totalPairs - 1; } } @@ -234,7 +257,7 @@ public void navigateBack() if (history.size() > 0) { PageRef target = history.pop(); - target.resolve(book); + //target.resolve(book); currentChapter = target.chapter; currentPair = target.page / 2; } @@ -250,12 +273,6 @@ private void pushHistory() history.push(new PageRef(currentChapter, currentPair * 2)); } - private int getSplitWidth(FontRenderer fontRenderer, String s, float scale) - { - int height = (int)(fontRenderer.getWordWrappedHeight(s, (int)(pageWidth / scale)) * scale); - return height > (fontRenderer.FONT_HEIGHT * scale) ? pageWidth : (int)(fontRenderer.getStringWidth(s) * scale); - } - @Override public int addString(int left, int top, String s, int color, float scale) { @@ -290,16 +307,16 @@ public boolean mouseClicked(int mouseButton) if (mouseButton == 0) { - BookDocument.SectionData ch = book.getChapter(currentChapter); + VisualChapter ch = getVisualChapter(currentChapter); - final VisualPage pgLeft = getVisualPage(ch, new PageRef(currentChapter, currentPair * 2), true); + final VisualPage pgLeft = ch.pages.get(currentPair * 2); if (mouseClickPage(mouseX, mouseY, pgLeft)) return true; if (currentPair * 2 + 1 < ch.pages.size()) { - final VisualPage pgRight = getVisualPage(ch, new PageRef(currentChapter, currentPair * 2 + 1), false); + final VisualPage pgRight = ch.pages.get(currentPair * 2 + 1); if (mouseClickPage(mouseX, mouseY, pgRight)) return true; @@ -309,18 +326,34 @@ public boolean mouseClicked(int mouseButton) return false; } - private VisualPage getVisualPage(BookDocument.SectionData ch, PageRef pr, boolean isLeftPage) + private VisualChapter getVisualChapter(int chapter) { - VisualPage pg = visualPages.get(pr); - - if (pg == null) + while (chapters.size() <= chapter && chapters.size() < book.chapterCount()) { - Rect r = getPageBounds(isLeftPage); - BookDocument.PageData pd = ch.pages.get(pr.page); - pg = pd.reflow(r); - visualPages.put(pr, pg); + VisualChapter ch = new VisualChapter(); + if (chapters.size() > 0) + { + VisualChapter prev = chapters.get(chapters.size() - 1); + ch.startPair = prev.startPair + prev.totalPairs; + } + + BookDocument.SectionData bc = book.getChapter(chapters.size()); + + Rect rl = getPageBounds(true); + Rect rr = getPageBounds(false); + for(BookDocument.PageData section : bc.sections) + { + if(!Strings.isNullOrEmpty(section.id)) + ch.pagesByName.put(section.id, ch.pages.size()); + + ch.pages.addAll(section.reflow(rl,rr,ch.pages.size())); + } + + ch.totalPairs = (ch.pages.size()+1)/2; + chapters.add(ch); } - return pg; + + return chapters.get(chapter); } private boolean mouseClickPage(int mX, int mY, VisualPage pg) @@ -343,9 +376,9 @@ private boolean mouseClickPage(int mX, int mY, VisualPage pg) @Override public boolean mouseHover(int mouseX, int mouseY) { - BookDocument.SectionData ch = book.getChapter(currentChapter); + VisualChapter ch = getVisualChapter(currentChapter); - final VisualPage pgLeft = getVisualPage(ch, new PageRef(currentChapter, currentPair * 2), true); + final VisualPage pgLeft = ch.pages.get(currentPair * 2); VisualElement hovering = mouseHoverPage(pgLeft); @@ -353,7 +386,7 @@ public boolean mouseHover(int mouseX, int mouseY) { if (currentPair * 2 + 1 < ch.pages.size()) { - final VisualPage pgRight = getVisualPage(ch, new PageRef(currentChapter, currentPair * 2 + 1), false); + final VisualPage pgRight = ch.pages.get(currentPair * 2 + 1); hovering = mouseHoverPage(pgRight); } @@ -441,10 +474,10 @@ public void drawCurrentPages() int top = (guiHeight - pageHeight) / 2 - 9; int bottom = top + pageHeight - 3; - drawPage(currentPair * 2, true); - drawPage(currentPair * 2 + 1, false); + drawPage(currentPair * 2); + drawPage(currentPair * 2 + 1); - String cnt = "" + ((book.getChapter(currentChapter).startPair + currentPair) * 2 + 1) + "/" + (book.getTotalPairCount() * 2); + String cnt = "" + ((getVisualChapter(currentChapter).startPair + currentPair) * 2 + 1) + "/" + (getTotalPairCount() * 2); Size sz = measure(cnt); addString(left + (pageWidth-sz.width)/2, bottom, cnt, 0xFF000000, 1.0f); @@ -455,13 +488,19 @@ public void drawCurrentPages() } } - private void drawPage(int page, boolean isLeftPage) + private int getTotalPairCount() + { + VisualChapter last = chapters.get(chapters.size() - 1); + return last.startPair + last.totalPairs; + } + + private void drawPage(int page) { - BookDocument.SectionData ch = book.getChapter(currentChapter); + VisualChapter ch = getVisualChapter(currentChapter); if (page >= ch.pages.size()) return; - VisualPage pg = getVisualPage(ch, new PageRef(currentChapter, page), isLeftPage); + VisualPage pg = ch.pages.get(page); for (VisualElement e : pg.children) { @@ -539,34 +578,103 @@ public Size measure(String text) return new Size(width, font.FONT_HEIGHT); } - @Override - public List measure(String text, int width, int firstLineWidth, float scale) + private static boolean isFormatColor(char colorChar) { - //TODO: Actually measure the string width taking into account the first line in an efficient way. - FontRenderer font = gui.getFontRenderer(); - String format = FontRenderer.getFormatFromString(text); - List lines = font.listFormattedStringToWidth(text, firstLineWidth); - if (lines.size() > 1) + return colorChar >= '0' && colorChar <= '9' || colorChar >= 'a' && colorChar <= 'f' || colorChar >= 'A' && colorChar <= 'F'; + } + + private static int sizeStringToWidth(FontRenderer font, String str, int wrapWidth) + { + int i = str.length(); + int j = 0; + int k = 0; + int l = -1; + + for (boolean flag = false; k < i; ++k) { - List sizes = Lists.newArrayList(); + char c0 = str.charAt(k); + + switch (c0) + { + case '\n': + --k; + break; + case ' ': + l = k; + default: + j += font.getCharWidth(c0); + + if (flag) + { + ++j; + } + + break; + case '\u00a7': + + if (k < i - 1) + { + ++k; + char c1 = str.charAt(k); + + if (c1 != 'l' && c1 != 'L') + { + if (c1 == 'r' || c1 == 'R' || isFormatColor(c1)) + { + flag = false; + } + } + else + { + flag = true; + } + } + } - String firstLine = lines.get(0); - int width1 = font.getStringWidth(firstLine); - sizes.add(new VisualText(firstLine, new Size(width1, font.FONT_HEIGHT), scale)); + if (c0 == '\n') + { + ++k; + l = k; + break; + } - String remaining = text.substring(firstLine.length()).trim(); - List lines2 = font.listFormattedStringToWidth(format + remaining, width); - for (String s : lines2) + if (j > wrapWidth) { - int width2 = font.getStringWidth(s); - sizes.add(new VisualText(s, new Size(width2, font.FONT_HEIGHT), scale)); + break; } - return sizes; + } + + return k != i && l != -1 && l < k ? l : k; + } + + private static void wrapFormattedStringToWidth(FontRenderer font, Consumer dest, String str, int wrapWidth, int wrapWidthFirstLine, boolean firstLine) + { + int i = sizeStringToWidth(font, str, firstLine ? wrapWidthFirstLine : wrapWidth); + + if (str.length() <= i) + { + dest.accept(str); } else { - int width1 = font.getStringWidth(text); - return Collections.singletonList(new VisualText(text, new Size(width1, font.FONT_HEIGHT * lines.size()), scale)); + String s = str.substring(0, i); + dest.accept(s); + char c0 = str.charAt(i); + boolean flag = c0 == ' ' || c0 == '\n'; + String s1 = FontRenderer.getFormatFromString(s) + str.substring(i + (flag ? 1 : 0)); + wrapFormattedStringToWidth(font, dest, s1, wrapWidth, wrapWidthFirstLine, false); } } + + @Override + public List measure(String text, int width, int firstLineWidth, float scale) + { + FontRenderer font = gui.getFontRenderer(); + List sizes = Lists.newArrayList(); + wrapFormattedStringToWidth(font, (s) -> { + int width2 = font.getStringWidth(s); + sizes.add(new VisualText(s, new Size(width2, font.FONT_HEIGHT), scale)); + }, text, width, firstLineWidth, true); + return sizes; + } } diff --git a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualElement.java b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualElement.java index 7cc8d89..b4d302e 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualElement.java +++ b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualElement.java @@ -1,8 +1,6 @@ package gigaherz.guidebook.guidebook.drawing; import gigaherz.guidebook.guidebook.IBookGraphics; -import gigaherz.guidebook.guidebook.PageRef; -import net.minecraft.item.ItemStack; public abstract class VisualElement extends Rect { diff --git a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualLink.java b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualLink.java index 54bf788..16606f9 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualLink.java +++ b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualLink.java @@ -3,7 +3,7 @@ import com.google.common.collect.Sets; import gigaherz.guidebook.GuidebookMod; import gigaherz.guidebook.guidebook.IBookGraphics; -import gigaherz.guidebook.guidebook.PageRef; +import gigaherz.guidebook.guidebook.SectionRef; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiConfirmOpenLink; import net.minecraft.client.gui.GuiScreen; @@ -24,7 +24,7 @@ public static class SharedHoverContext } public String webTarget; - public PageRef target; + public SectionRef target; public int colorHover = 0xFF77cc66; public SharedHoverContext hoverContext = new SharedHoverContext(); diff --git a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualStack.java b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualStack.java index dc78380..2241aa3 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualStack.java +++ b/src/main/java/gigaherz/guidebook/guidebook/drawing/VisualStack.java @@ -1,7 +1,7 @@ package gigaherz.guidebook.guidebook.drawing; import gigaherz.guidebook.guidebook.IBookGraphics; -import gigaherz.guidebook.guidebook.PageRef; +import gigaherz.guidebook.guidebook.SectionRef; import net.minecraft.item.ItemStack; public class VisualStack extends VisualElement @@ -57,7 +57,7 @@ public void mouseOver(IBookGraphics nav, int x, int y) @Override public void click(IBookGraphics nav) { - PageRef ref = nav.getBook().getStackLink(getCurrentStack()); + SectionRef ref = nav.getBook().getStackLink(getCurrentStack()); if (ref != null) nav.navigateTo(ref); } diff --git a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementImage.java b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementImage.java index ed7baa1..4b2b304 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementImage.java +++ b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementImage.java @@ -1,6 +1,5 @@ package gigaherz.guidebook.guidebook.elements; -import com.google.common.primitives.Floats; import com.google.common.primitives.Ints; import gigaherz.guidebook.guidebook.IBookGraphics; import gigaherz.guidebook.guidebook.drawing.*; @@ -20,11 +19,16 @@ public class ElementImage extends Element public int tw = 0; public int th = 0; - private VisualImage getVisual() + private Size getVisualSize() { int width = (int) (w * scale); int height = (int) (h * scale); - return new VisualImage(new Size(width,height), textureLocation, tx, ty, tw, th); + return new Size(width,height); + } + + private VisualImage getVisual() + { + return new VisualImage(getVisualSize(), textureLocation, tx, ty, tw, th); } @Override diff --git a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementLink.java b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementLink.java index ce78384..8bcfa24 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementLink.java +++ b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementLink.java @@ -2,7 +2,7 @@ import com.google.common.collect.Lists; import gigaherz.guidebook.guidebook.IBookGraphics; -import gigaherz.guidebook.guidebook.PageRef; +import gigaherz.guidebook.guidebook.SectionRef; import gigaherz.guidebook.guidebook.drawing.VisualElement; import gigaherz.guidebook.guidebook.drawing.VisualLink; import gigaherz.guidebook.guidebook.drawing.VisualText; @@ -14,7 +14,7 @@ public class ElementLink extends ElementSpan { public String webTarget; - public PageRef target; + public SectionRef target; public int colorHover = 0xFF77cc66; public ElementLink(String text) @@ -58,7 +58,7 @@ public void parse(NamedNodeMap attributes) if (attr != null) { String ref = attr.getTextContent(); - target = PageRef.fromString(ref); + target = SectionRef.fromString(ref); } attr = attributes.getNamedItem("href"); diff --git a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementParagraph.java b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementParagraph.java index 501e2c1..a8fb1a8 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementParagraph.java +++ b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementParagraph.java @@ -35,9 +35,10 @@ public int reflow(List paragraph, IBookGraphics nav, Rect bounds, for(Element element : spans) { + int firstLineWidth = bounds.size.width - currentLineLeft - indent - indentFirstLine; List pieces = element.measure(nav, bounds.size.width - indent, - bounds.size.width - currentLineLeft - indent - indentFirstLine); + firstLineWidth); if (pieces.size() < 1) continue; @@ -47,7 +48,7 @@ public int reflow(List paragraph, IBookGraphics nav, Rect bounds, VisualElement current = pieces.get(i); Size size = current.size; - if (currentLineLeft + size.width > bounds.size.width && currentLineLeft > 0) + if ((currentLineLeft + size.width > bounds.size.width && currentLineLeft > 0)) { if (paragraph.size() > firstInLine && alignment != 0) processAlignment(paragraph, bounds.size.width - indent, currentLineLeft, spaceSize, firstInLine); @@ -67,6 +68,15 @@ public int reflow(List paragraph, IBookGraphics nav, Rect bounds, if (size.width > 0) currentLineLeft += size.width + spaceSize.width; + if (currentLineLeft > bounds.size.width) + { + currentLineTop += currentLineHeight; + currentLineLeft = 0; + currentLineHeight = 0; + + firstInLine = paragraph.size(); + } + paragraph.add(current); } } diff --git a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementStack.java b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementStack.java index 0b3dcac..03f1e33 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/elements/ElementStack.java +++ b/src/main/java/gigaherz/guidebook/guidebook/elements/ElementStack.java @@ -25,11 +25,16 @@ public class ElementStack extends Element public ItemStack[] stacks; + private Size getVisualSize() + { + int width = (int) (w * scale); + int height = (int) (h * scale); + return new Size(width,height); + } + private VisualStack getVisual() { - int width = (int) (16 * scale); - int height = (int) (16 * scale); - return new VisualStack(stacks, new Size(width,height), scale, z); + return new VisualStack(stacks, getVisualSize(), scale, z); } @Override diff --git a/src/main/java/gigaherz/guidebook/guidebook/recipe/CraftingRecipeProvider.java b/src/main/java/gigaherz/guidebook/guidebook/recipe/CraftingRecipeProvider.java index 5f7f531..2c15b41 100644 --- a/src/main/java/gigaherz/guidebook/guidebook/recipe/CraftingRecipeProvider.java +++ b/src/main/java/gigaherz/guidebook/guidebook/recipe/CraftingRecipeProvider.java @@ -121,7 +121,7 @@ private void reloadCaches() { shapelessRecipes = new ArrayList<>(); shapedRecipes = new ArrayList<>(); - for (IRecipe recipe : ForgeRegistries.RECIPES.getValues()) + for (IRecipe recipe : ForgeRegistries.RECIPES.getValuesCollection()) { if (recipe instanceof ShapelessOreRecipe) shapelessRecipes.add(recipe); if (recipe instanceof ShapelessRecipes) shapelessRecipes.add(recipe);