|
|
@ -69,6 +69,8 @@ object ChapterProvider { |
|
|
|
@JvmStatic |
|
|
|
@JvmStatic |
|
|
|
lateinit var contentPaint: TextPaint |
|
|
|
lateinit var contentPaint: TextPaint |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private const val srcReplaceChar = "🖼" |
|
|
|
|
|
|
|
|
|
|
|
init { |
|
|
|
init { |
|
|
|
upStyle() |
|
|
|
upStyle() |
|
|
|
} |
|
|
|
} |
|
|
@ -81,20 +83,47 @@ object ChapterProvider { |
|
|
|
bookChapter: BookChapter, |
|
|
|
bookChapter: BookChapter, |
|
|
|
contents: List<String>, |
|
|
|
contents: List<String>, |
|
|
|
chapterSize: Int, |
|
|
|
chapterSize: Int, |
|
|
|
imageStyle: String?, |
|
|
|
|
|
|
|
): TextChapter { |
|
|
|
): TextChapter { |
|
|
|
val textPages = arrayListOf<TextPage>() |
|
|
|
val textPages = arrayListOf<TextPage>() |
|
|
|
val stringBuilder = StringBuilder() |
|
|
|
val stringBuilder = StringBuilder() |
|
|
|
var durY = 0f |
|
|
|
var durY = 0f |
|
|
|
textPages.add(TextPage()) |
|
|
|
textPages.add(TextPage()) |
|
|
|
contents.forEachIndexed { index, text -> |
|
|
|
contents.forEachIndexed { index, content -> |
|
|
|
|
|
|
|
if (book.getImageStyle() == Book.imgStyleText) { |
|
|
|
|
|
|
|
var text = content.replace(srcReplaceChar, "画") |
|
|
|
|
|
|
|
val srcList = LinkedList<String>() |
|
|
|
|
|
|
|
val sb = StringBuffer() |
|
|
|
|
|
|
|
val matcher = AppPattern.imgPattern.matcher(text) |
|
|
|
|
|
|
|
while (matcher.find()) { |
|
|
|
|
|
|
|
matcher.group(1)?.let { it -> |
|
|
|
|
|
|
|
val src = NetworkUtils.getAbsoluteURL(bookChapter.url, it) |
|
|
|
|
|
|
|
srcList.add(src) |
|
|
|
|
|
|
|
ImageProvider.getImage(book, bookChapter.index, src) |
|
|
|
|
|
|
|
matcher.appendReplacement(sb, srcReplaceChar) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
matcher.appendTail(sb) |
|
|
|
|
|
|
|
text = sb.toString() |
|
|
|
|
|
|
|
val isTitle = index == 0 |
|
|
|
|
|
|
|
val textPaint = if (isTitle) titlePaint else contentPaint |
|
|
|
|
|
|
|
if (!(isTitle && ReadBookConfig.titleMode == 2)) { |
|
|
|
|
|
|
|
durY = setTypeText( |
|
|
|
|
|
|
|
text, durY, textPages, stringBuilder, |
|
|
|
|
|
|
|
isTitle, textPaint, srcList |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (book.getImageStyle() != Book.imgStyleText) { |
|
|
|
|
|
|
|
content.replace(AppPattern.imgPattern.toRegex(), "\n\$0\n") |
|
|
|
|
|
|
|
.split("\n").forEach { text -> |
|
|
|
|
|
|
|
if (text.isNotBlank()) { |
|
|
|
val matcher = AppPattern.imgPattern.matcher(text) |
|
|
|
val matcher = AppPattern.imgPattern.matcher(text) |
|
|
|
if (matcher.find()) { |
|
|
|
if (matcher.find()) { |
|
|
|
matcher.group(1)?.let { |
|
|
|
matcher.group(1)?.let { it -> |
|
|
|
if (!book.isEpub()) { |
|
|
|
if (!book.isEpub()) { |
|
|
|
val src = NetworkUtils.getAbsoluteURL(bookChapter.url, it) |
|
|
|
val src = NetworkUtils.getAbsoluteURL(bookChapter.url, it) |
|
|
|
durY = setTypeImage( |
|
|
|
durY = setTypeImage( |
|
|
|
book, bookChapter, src, durY, textPages, imageStyle |
|
|
|
book, bookChapter, src, |
|
|
|
|
|
|
|
durY, textPages, book.getImageStyle() |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -102,7 +131,13 @@ object ChapterProvider { |
|
|
|
val isTitle = index == 0 |
|
|
|
val isTitle = index == 0 |
|
|
|
val textPaint = if (isTitle) titlePaint else contentPaint |
|
|
|
val textPaint = if (isTitle) titlePaint else contentPaint |
|
|
|
if (!(isTitle && ReadBookConfig.titleMode == 2)) { |
|
|
|
if (!(isTitle && ReadBookConfig.titleMode == 2)) { |
|
|
|
durY = setTypeText(text, durY, textPages, stringBuilder, isTitle, textPaint) |
|
|
|
durY = setTypeText( |
|
|
|
|
|
|
|
text, durY, textPages, |
|
|
|
|
|
|
|
stringBuilder, isTitle, textPaint |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -142,9 +177,12 @@ object ChapterProvider { |
|
|
|
var height = it.height |
|
|
|
var height = it.height |
|
|
|
var width = it.width |
|
|
|
var width = it.width |
|
|
|
when (imageStyle?.toUpperCase(Locale.ROOT)) { |
|
|
|
when (imageStyle?.toUpperCase(Locale.ROOT)) { |
|
|
|
"FULL" -> { |
|
|
|
Book.imgStyleFull -> { |
|
|
|
width = visibleWidth |
|
|
|
width = visibleWidth |
|
|
|
height = it.height * visibleWidth / it.width |
|
|
|
height = it.height * visibleWidth / it.width |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Book.imgStyleText -> { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else -> { |
|
|
|
else -> { |
|
|
|
if (it.width > visibleWidth) { |
|
|
|
if (it.width > visibleWidth) { |
|
|
@ -197,7 +235,8 @@ object ChapterProvider { |
|
|
|
textPages: ArrayList<TextPage>, |
|
|
|
textPages: ArrayList<TextPage>, |
|
|
|
stringBuilder: StringBuilder, |
|
|
|
stringBuilder: StringBuilder, |
|
|
|
isTitle: Boolean, |
|
|
|
isTitle: Boolean, |
|
|
|
textPaint: TextPaint |
|
|
|
textPaint: TextPaint, |
|
|
|
|
|
|
|
srcList: LinkedList<String>? = null |
|
|
|
): Float { |
|
|
|
): Float { |
|
|
|
var durY = if (isTitle) y + titleTopSpacing else y |
|
|
|
var durY = if (isTitle) y + titleTopSpacing else y |
|
|
|
val layout = if (ReadBookConfig.useZhLayout) { |
|
|
|
val layout = if (ReadBookConfig.useZhLayout) { |
|
|
@ -214,7 +253,13 @@ object ChapterProvider { |
|
|
|
if (lineIndex == 0 && layout.lineCount > 1 && !isTitle) { |
|
|
|
if (lineIndex == 0 && layout.lineCount > 1 && !isTitle) { |
|
|
|
//第一行 |
|
|
|
//第一行 |
|
|
|
textLine.text = words |
|
|
|
textLine.text = words |
|
|
|
addCharsToLineFirst(textLine, words.toStringArray(), textPaint, desiredWidth) |
|
|
|
addCharsToLineFirst( |
|
|
|
|
|
|
|
textLine, |
|
|
|
|
|
|
|
words.toStringArray(), |
|
|
|
|
|
|
|
textPaint, |
|
|
|
|
|
|
|
desiredWidth, |
|
|
|
|
|
|
|
srcList |
|
|
|
|
|
|
|
) |
|
|
|
} else if (lineIndex == layout.lineCount - 1) { |
|
|
|
} else if (lineIndex == layout.lineCount - 1) { |
|
|
|
//最后一行 |
|
|
|
//最后一行 |
|
|
|
textLine.text = "$words\n" |
|
|
|
textLine.text = "$words\n" |
|
|
@ -222,11 +267,18 @@ object ChapterProvider { |
|
|
|
val x = if (isTitle && ReadBookConfig.titleMode == 1) |
|
|
|
val x = if (isTitle && ReadBookConfig.titleMode == 1) |
|
|
|
(visibleWidth - layout.getLineWidth(lineIndex)) / 2 |
|
|
|
(visibleWidth - layout.getLineWidth(lineIndex)) / 2 |
|
|
|
else 0f |
|
|
|
else 0f |
|
|
|
addCharsToLineLast(textLine, words.toStringArray(), textPaint, x) |
|
|
|
addCharsToLineLast(textLine, words.toStringArray(), textPaint, x, srcList) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
//中间行 |
|
|
|
//中间行 |
|
|
|
textLine.text = words |
|
|
|
textLine.text = words |
|
|
|
addCharsToLineMiddle(textLine, words.toStringArray(), textPaint, desiredWidth, 0f) |
|
|
|
addCharsToLineMiddle( |
|
|
|
|
|
|
|
textLine, |
|
|
|
|
|
|
|
words.toStringArray(), |
|
|
|
|
|
|
|
textPaint, |
|
|
|
|
|
|
|
desiredWidth, |
|
|
|
|
|
|
|
0f, |
|
|
|
|
|
|
|
srcList |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
if (durY + textPaint.textHeight > visibleHeight) { |
|
|
|
if (durY + textPaint.textHeight > visibleHeight) { |
|
|
|
//当前页面结束,设置各种值 |
|
|
|
//当前页面结束,设置各种值 |
|
|
@ -257,21 +309,37 @@ object ChapterProvider { |
|
|
|
words: Array<String>, |
|
|
|
words: Array<String>, |
|
|
|
textPaint: TextPaint, |
|
|
|
textPaint: TextPaint, |
|
|
|
desiredWidth: Float, |
|
|
|
desiredWidth: Float, |
|
|
|
|
|
|
|
srcList: LinkedList<String>? |
|
|
|
) { |
|
|
|
) { |
|
|
|
var x = 0f |
|
|
|
var x = 0f |
|
|
|
if (!ReadBookConfig.textFullJustify) { |
|
|
|
if (!ReadBookConfig.textFullJustify) { |
|
|
|
addCharsToLineLast(textLine, words, textPaint, x) |
|
|
|
addCharsToLineLast(textLine, words, textPaint, x, srcList) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
val bodyIndent = ReadBookConfig.paragraphIndent |
|
|
|
val bodyIndent = ReadBookConfig.paragraphIndent |
|
|
|
val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length |
|
|
|
val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length |
|
|
|
bodyIndent.toStringArray().forEach { |
|
|
|
bodyIndent.toStringArray().forEach { |
|
|
|
val x1 = x + icw |
|
|
|
val x1 = x + icw |
|
|
|
textLine.addTextChar(charData = it, start = paddingLeft + x, end = paddingLeft + x1) |
|
|
|
if (srcList != null && it == srcReplaceChar) { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
srcList.removeFirst(), |
|
|
|
|
|
|
|
start = paddingLeft + x, |
|
|
|
|
|
|
|
end = paddingLeft + x1, |
|
|
|
|
|
|
|
isImage = true |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
it, start = paddingLeft + x, end = paddingLeft + x1 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
x = x1 |
|
|
|
x = x1 |
|
|
|
} |
|
|
|
} |
|
|
|
val words1 = words.copyOfRange(bodyIndent.length, words.size) |
|
|
|
val words1 = words.copyOfRange(bodyIndent.length, words.size) |
|
|
|
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x) |
|
|
|
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -283,9 +351,10 @@ object ChapterProvider { |
|
|
|
textPaint: TextPaint, |
|
|
|
textPaint: TextPaint, |
|
|
|
desiredWidth: Float, |
|
|
|
desiredWidth: Float, |
|
|
|
startX: Float, |
|
|
|
startX: Float, |
|
|
|
|
|
|
|
srcList: LinkedList<String>? |
|
|
|
) { |
|
|
|
) { |
|
|
|
if (!ReadBookConfig.textFullJustify) { |
|
|
|
if (!ReadBookConfig.textFullJustify) { |
|
|
|
addCharsToLineLast(textLine, words, textPaint, startX) |
|
|
|
addCharsToLineLast(textLine, words, textPaint, startX, srcList) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
val gapCount: Int = words.lastIndex |
|
|
|
val gapCount: Int = words.lastIndex |
|
|
@ -294,7 +363,22 @@ object ChapterProvider { |
|
|
|
words.forEachIndexed { index, s -> |
|
|
|
words.forEachIndexed { index, s -> |
|
|
|
val cw = StaticLayout.getDesiredWidth(s, textPaint) |
|
|
|
val cw = StaticLayout.getDesiredWidth(s, textPaint) |
|
|
|
val x1 = if (index != words.lastIndex) (x + cw + d) else (x + cw) |
|
|
|
val x1 = if (index != words.lastIndex) (x + cw + d) else (x + cw) |
|
|
|
textLine.addTextChar(charData = s, start = paddingLeft + x, end = paddingLeft + x1) |
|
|
|
if (srcList != null && s == srcReplaceChar) { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
srcList.removeFirst(), |
|
|
|
|
|
|
|
start = paddingLeft + x, |
|
|
|
|
|
|
|
end = paddingLeft + x1, |
|
|
|
|
|
|
|
isImage = true |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
s, start = paddingLeft + x, end = paddingLeft + x1 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
x = x1 |
|
|
|
x = x1 |
|
|
|
} |
|
|
|
} |
|
|
|
exceed(textLine, words) |
|
|
|
exceed(textLine, words) |
|
|
@ -308,12 +392,28 @@ object ChapterProvider { |
|
|
|
words: Array<String>, |
|
|
|
words: Array<String>, |
|
|
|
textPaint: TextPaint, |
|
|
|
textPaint: TextPaint, |
|
|
|
startX: Float, |
|
|
|
startX: Float, |
|
|
|
|
|
|
|
srcList: LinkedList<String>? |
|
|
|
) { |
|
|
|
) { |
|
|
|
var x = startX |
|
|
|
var x = startX |
|
|
|
words.forEach { |
|
|
|
words.forEach { |
|
|
|
val cw = StaticLayout.getDesiredWidth(it, textPaint) |
|
|
|
val cw = StaticLayout.getDesiredWidth(it, textPaint) |
|
|
|
val x1 = x + cw |
|
|
|
val x1 = x + cw |
|
|
|
textLine.addTextChar(charData = it, start = paddingLeft + x, end = paddingLeft + x1) |
|
|
|
if (srcList != null && it == srcReplaceChar) { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
srcList.removeFirst(), |
|
|
|
|
|
|
|
start = paddingLeft + x, |
|
|
|
|
|
|
|
end = paddingLeft + x1, |
|
|
|
|
|
|
|
isImage = true |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
textLine.textChars.add( |
|
|
|
|
|
|
|
TextChar( |
|
|
|
|
|
|
|
it, start = paddingLeft + x, end = paddingLeft + x1 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
x = x1 |
|
|
|
x = x1 |
|
|
|
} |
|
|
|
} |
|
|
|
exceed(textLine, words) |
|
|
|
exceed(textLine, words) |
|
|
|