From 966e01cf88ab5942e9e485529ff27050c881d588 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Wed, 16 Jan 2019 20:54:18 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=B2=D1=8B=D1=80=D0=B0=D0=B2=D0=BD=D0=B8=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=88=D0=B8=D1=80=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Reader/TextPage/TextPage.vue | 44 +++++++++++++++---- client/components/Reader/share/BookParser.js | 25 +++++++---- 2 files changed, 52 insertions(+), 17 deletions(-) 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;