package org.ebookdroid.droids.fb2.codec; import static org.ebookdroid.droids.fb2.codec.FB2Page.MARGIN_X; import static org.ebookdroid.droids.fb2.codec.FB2Page.PAGE_WIDTH; import org.ebookdroid.common.settings.AppSettings; import android.graphics.Bitmap; import android.text.TextPaint; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import java.util.TreeMap; import org.emdev.common.fonts.FontManager; import org.emdev.common.fonts.SystemFontProvider; import org.emdev.common.fonts.data.FontFamilyType; import org.emdev.common.fonts.data.FontStyle; import org.emdev.common.fonts.typeface.TypefaceEx; import org.emdev.common.textmarkup.CustomTextPaintContainer; import org.emdev.common.textmarkup.JustificationMode; import org.emdev.common.textmarkup.MarkupElement; import org.emdev.common.textmarkup.MarkupEndDocument; import org.emdev.common.textmarkup.TextStyle; import org.emdev.common.textmarkup.image.DiskImageData; import org.emdev.common.textmarkup.image.IImageData; import org.emdev.common.textmarkup.image.MemoryImageData; import org.emdev.common.textmarkup.line.Image; import org.emdev.common.textmarkup.line.LineStream; import org.emdev.utils.LengthUtils; public class ParsedContent { private static final CustomTextPaintContainer DEFAULT_PAINTS = new CustomTextPaintContainer(null); final ArrayList<MarkupElement> docMarkup = new ArrayList<MarkupElement>(); final HashMap<String, ArrayList<MarkupElement>> streams = new HashMap<String, ArrayList<MarkupElement>>(); private final TreeMap<String, Image> images = new TreeMap<String, Image>(); private final TreeMap<String, LineStream> notes = new TreeMap<String, LineStream>(); private String cover; public TypefaceEx[] fonts; public TypefaceEx mono; public final CustomTextPaintContainer paints; public ParsedContent() { paints = DEFAULT_PAINTS; } public ParsedContent(TextPaint defPaint) { paints = new CustomTextPaintContainer(defPaint); } public void loadFonts() { final String fontPack = AppSettings.current().fb2FontPack; final FontFamilyType family = FontFamilyType.SERIF; loadFonts(fontPack, family); } public void loadFonts(final String fontPack, final FontFamilyType family) { final FontStyle[] styles = FontStyle.values(); fonts = new TypefaceEx[styles.length]; for (final FontStyle style : styles) { final TypefaceEx font = FontManager.getFont(fontPack, family, style); fonts[style.ordinal()] = font; this.paints.getTextPaint(font, TextStyle.TEXT.getFontSize()); // System.out.println("Preloaded: " + font); } mono = FontManager.getFont(SystemFontProvider.SYSTEM_FONT_PACK, FontFamilyType.MONO, FontStyle.REGULAR); // System.out.println("Preloaded: " + mono); } public void clear() { docMarkup.clear(); for (final Entry<String, ArrayList<MarkupElement>> entry : streams.entrySet()) { final ArrayList<MarkupElement> value = entry.getValue(); if (value != null) { value.clear(); } } streams.clear(); } public void recycle() { for (final Image image : images.values()) { image.data.recycle(); } images.clear(); } public ArrayList<MarkupElement> getMarkupStream(final String streamName) { if (streamName == null) { return docMarkup; } ArrayList<MarkupElement> stream = streams.get(streamName); if (stream == null) { stream = new ArrayList<MarkupElement>(); streams.put(streamName, stream); } return stream; } public void addImage(final String tmpBinaryName, final String encoded) { if (tmpBinaryName != null && encoded != null) { IImageData data = new MemoryImageData(encoded); if (AppSettings.current().fb2CacheImagesOnDisk) { data = new DiskImageData((MemoryImageData) data); } images.put("I" + tmpBinaryName, new Image(data, true)); images.put("O" + tmpBinaryName, new Image(data, false)); } } public void addImage(final String tmpBinaryName, final char[] tmpBinary, final int tmpBinaryStart, final int tmpBinaryLength) { if (tmpBinaryName != null && tmpBinary != null && tmpBinaryLength > 0) { IImageData data = new MemoryImageData(tmpBinary, tmpBinaryStart, tmpBinaryLength); if (AppSettings.current().fb2CacheImagesOnDisk) { data = new DiskImageData((MemoryImageData) data); } images.put("I" + tmpBinaryName, new Image(data, true)); images.put("O" + tmpBinaryName, new Image(data, false)); } } public Image getImage(final String name, final boolean inline) { if (name == null) { return null; } Image img = images.get((inline ? "I" : "O") + name); if (img == null && name.startsWith("#")) { img = images.get((inline ? "I" : "O") + name.substring(1)); } return img; } public LineStream getNote(final String noteName, boolean hyphenEnabled) { LineStream note = notes.get(noteName); if (note != null) { return note; } ArrayList<MarkupElement> stream = getMarkupStream(noteName); if (LengthUtils.isEmpty(stream) && noteName.startsWith("#")) { stream = getMarkupStream(noteName.substring(1)); } if (stream != null) { note = createLines(stream, PAGE_WIDTH - 2 * MARGIN_X, JustificationMode.Justify, hyphenEnabled); notes.put(noteName, note); } return note; } public LineStream createLines(final List<MarkupElement> markup, final int maxLineWidth, final JustificationMode jm, final boolean hyphenEnabled) { final LineStream lines = new LineStream(this, maxLineWidth, jm, hyphenEnabled); if (LengthUtils.isNotEmpty(markup)) { for (final MarkupElement me : markup) { if (me instanceof MarkupEndDocument) { break; } me.publishToLines(lines); } } return lines; } public LineStream getStreamLines(final String streamName, final int maxWidth, final JustificationMode jm, final boolean hyphenEnabled) { final ArrayList<MarkupElement> stream = getMarkupStream(streamName); if (stream != null) { return createLines(stream, maxWidth, jm, hyphenEnabled); } return null; } public void setCover(final String value) { this.cover = value; } public Bitmap getCoverImage() { final Image image = getImage(cover, false); if (image != null) { return image.data.getBitmap(); } return null; } }