diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue index e18bfc3e..858ebd5f 100644 --- a/client/components/Reader/TextPage/TextPage.vue +++ b/client/components/Reader/TextPage/TextPage.vue @@ -45,7 +45,7 @@ class TextPage extends Vue { this.context.textAlign = 'left'; } - updateCanvasSize() { + calcDrawProps() { this.canvas.width = this.$refs.main.clientWidth; this.canvas.height = this.$refs.main.clientHeight; this.lineHeight = this.fontSize + this.lineInterval; @@ -63,15 +63,16 @@ class TextPage extends Vue { this.linesDown = null; this.pageLineCount = 0; - //canvas props + //draw props this.textColor = 'black'; this.backgroundColor = '#478355'; this.fontStyle = '';// 'bold','italic' this.fontSize = 20;// px this.fontName = 'arial'; this.lineInterval = 5;// px + this.textAlignJustify = true; - this.updateCanvasSize(); + this.calcDrawProps(); this.drawPage();// пока не загрузили, очистим канвас if (this.lastBook) { @@ -92,13 +93,15 @@ class TextPage extends Vue { this.fb2.bookTitle ]).join(' ')); - this.updateCanvasSize(); + this.calcDrawProps(); const parsed = this.book.parsed; parsed.p = 30;// px, отступ параграфа parsed.w = this.canvas.width;// px, ширина страницы + parsed.font = this.font; parsed.measureText = (text, style) => {// eslint-disable-line no-unused-vars return this.context.measureText(text).width; - }; + }; + this.measureText = parsed.measureText; this.parsed = parsed; this.drawPage(); @@ -106,6 +109,10 @@ class TextPage extends Vue { } } + get font() { + return `${this.fontStyle} ${this.fontSize}px ${this.fontName}`; + } + drawPage() { if (!this.lastBook) return; @@ -114,15 +121,15 @@ class TextPage extends Vue { const canvas = this.canvas; const context = this.context; - context.font = `${this.fontStyle} ${this.fontSize}px ${this.fontName}`; - context.fillStyle = this.backgroundColor; context.fillRect(0, 0, canvas.width, canvas.height); if (!this.book) return; + context.font = this.font; context.fillStyle = this.textColor; + const spaceWidth = this.context.measureText(' ').width; const lines = this.parsed.getLines(this.bookPos, this.pageLineCount + 1); @@ -135,7 +142,8 @@ class TextPage extends Vue { { begin: Number, end: Number, - para: Boolean, + paraBegin: Boolean, + paraEnd: Boolean, parts: array of { style: 'bold'|'italic', text: String, @@ -148,7 +156,25 @@ class TextPage extends Vue { } y += this.lineHeight; - context.fillText(text, 0, y); + let filled = false; + if (this.textAlignJustify && !line.paraEnd) { + const words = text.split(' '); + if (words.length > 1) { + let space = canvas.width - line.width + spaceWidth*(words.length - 1); + space = space/(words.length - 1); + + let x = 0; + for (const word of words) { + context.fillText(word, x, y); + x += this.measureText(word) + space; + } + filled = true; + } + } + + if (!filled) + context.fillText(text, 0, y); + } this.linesUp = this.parsed.getLines(this.bookPos, -(this.pageLineCount + 1)); diff --git a/client/components/Reader/share/BookParser.js b/client/components/Reader/share/BookParser.js index 9a8269ef..9c606b4d 100644 --- a/client/components/Reader/share/BookParser.js +++ b/client/components/Reader/share/BookParser.js @@ -236,15 +236,16 @@ export default class BookParser { if (para.parsed && para.parsed.w === this.w && para.parsed.p === this.p && - para.parsed.textAlignJustify === this.textAlignJustify && - para.parsed.wordWrap === this.wordWrap) + para.parsed.wordWrap === this.wordWrap && + para.parsed.font === this.font + ) return para.parsed; const parsed = { w: this.w, p: this.p, - textAlignJustify: this.textAlignJustify, - wordWrap: this.wordWrap + wordWrap: this.wordWrap, + font: this.font, }; const lines = []; @@ -252,7 +253,8 @@ export default class BookParser { { begin: Number, end: Number, - para: Boolean, + paraBegin: Boolean, + paraEnd: Boolean, parts: array of { style: 'bold'|'italic', text: String, @@ -265,29 +267,36 @@ export default class BookParser { let line = {begin: para.offset, parts: []}; let prevPart = ''; let part = ''; + let prevW = 0; let k = 0; // тут начинается самый замес, перенос и стилизация for (let i = 0; i < words.length; i++) { const word = words[i]; part += word; - if (this.measureText(part) > parsed.w) { + let w = this.measureText(part); + if (w > parsed.w) { line.parts.push({style: '', text: prevPart}); line.end = line.begin + prevPart.length;//нет -1 !!! - line.para = (k == 0); + line.width = prevW; + line.paraBegin = (k == 0); + line.paraEnd = false; lines.push(line); line = {begin: line.end + 1, parts: []}; part = word; k++; } + prevW = w; prevPart = part; part += ' '; } line.parts.push({style: '', text: prevPart}); line.end = line.begin + prevPart.length - 1; - line.para = (k == 0); + line.width = prevW; + line.paraBegin = (k == 0); + line.paraEnd = true; lines.push(line); parsed.lines = lines;