Loading ballontranslator/ui/scene_textlayout.py +23 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ class SceneTextLayout(QAbstractTextDocumentLayout): self.block_charfmt_lst = [] self.block_ideal_width = [] self.need_ideal_width = False self.block_ideal_height = [] self.need_ideal_height = False self._map_charidx2frag = [] self._max_font_size = -1 Loading Loading @@ -192,9 +195,11 @@ class SceneTextLayout(QAbstractTextDocumentLayout): block = self.document().firstBlock() self.block_charfmt_lst = [] self.block_ideal_width = [] self.block_ideal_height = [] self._map_charidx2frag = [] while block.isValid(): charfmt_lst, ideal_width, char_idx = [], -1, 0 ideal_height = 0 charidx_map = {} it = block.begin() frag_idx = 0 Loading @@ -202,11 +207,20 @@ class SceneTextLayout(QAbstractTextDocumentLayout): fragment = it.fragment() fcmt = fragment.charFormat() cfmt = CharFontFormat(fcmt) charfmt_lst.append(cfmt) if cfmt.size > self._max_font_size: self._max_font_size = cfmt.size if ideal_width < cfmt.br.width(): ideal_width = cfmt.br.width() charfmt_lst.append(cfmt) if self.need_ideal_width: w_ = cfmt.br.width() if ideal_width < w_: ideal_width = w_ if self.need_ideal_height: h_ = cfmt.punc_rect('fg')[0].height() if ideal_height < h_: ideal_height = h_ text_len = fragment.length() for _ in range(text_len): charidx_map[char_idx] = frag_idx Loading @@ -215,6 +229,7 @@ class SceneTextLayout(QAbstractTextDocumentLayout): frag_idx += 1 self.block_charfmt_lst.append(charfmt_lst) self.block_ideal_width.append(ideal_width) self.block_ideal_height.append(ideal_height) self._map_charidx2frag.append(charidx_map) block = block.next() self.reLayout() Loading @@ -238,6 +253,7 @@ class VerticalTextDocumentLayout(SceneTextLayout): self.punc_align_center = True self.draw_shifted = 0 self.need_ideal_width = True self.line_draw = line_draw_qt6 if C.FLAG_QT6 else line_draw_qt5 @property Loading Loading @@ -608,6 +624,7 @@ class HorizontalTextDocumentLayout(SceneTextLayout): def __init__(self, doc: QTextDocument): super().__init__(doc) self.need_ideal_height = True def reLayout(self): doc = self.document() Loading Loading @@ -679,6 +696,7 @@ class HorizontalTextDocumentLayout(SceneTextLayout): fm = QFontMetrics(font) doc_margin = self.document().documentMargin() idea_height = self.block_ideal_height[block.blockNumber()] if block == doc.firstBlock(): self.x_offset_lst = [] self.y_offset_lst = [] Loading @@ -695,8 +713,8 @@ class HorizontalTextDocumentLayout(SceneTextLayout): line.setLeadingIncluded(False) line.setLineWidth(self.available_width) line.setPosition(QPointF(doc_margin, y_offset)) self.y_bottom = tbr.height() + y_offset + line.descent() #???? y_offset += tbr.height() * self.line_spacing self.y_bottom = idea_height + y_offset + line.descent() #???? y_offset += idea_height * self.line_spacing line_idx += 1 tl.endLayout() self.y_offset_lst.append(y_offset) Loading ballontranslator/ui/scenetext_manager.py +25 −6 Original line number Diff line number Diff line Loading @@ -201,18 +201,29 @@ class AutoLayoutCommand(QUndoCommand): for item in items: self.new_html_lst.append(item.toHtml()) self.new_rect_lst.append(item.absBoundingRect()) self.counter = 0 def redo(self): self.counter += 1 if self.counter <= 1: return for item, trans_widget, html, rect in zip(self.items, self.trans_widget_lst, self.new_html_lst, self.new_rect_lst): item.setHtml(html) trans_widget.setPlainText(item.toPlainText()) item.setRect(rect) item.setPlainText('') item.setRect(rect, repaint=False) item.setHtml(html) if item.letter_spacing != 1: item.setLetterSpacing(item.letter_spacing, force=True) def undo(self): for item, trans_widget, html, rect in zip(self.items, self.trans_widget_lst, self.old_html_lst, self.old_rect_lst): item.setHtml(html) trans_widget.setPlainText(item.toPlainText()) item.setRect(rect) item.setPlainText('') item.setRect(rect, repaint=False) item.setHtml(html) if item.letter_spacing != 1: item.setLetterSpacing(item.letter_spacing, force=True) class SceneTextManager(QObject): Loading Loading @@ -466,6 +477,7 @@ class SceneTextManager(QObject): blk_font = blkitem.font() fmt = blkitem.get_fontformat() blk_font.setLetterSpacing(QFont.SpacingType.PercentageSpacing, fmt.letter_spacing * 100) text_size_func = lambda text: get_text_size(QFontMetrics(blk_font), text) src_is_cjk = is_cjk(self.config.dl.translate_source) Loading Loading @@ -603,8 +615,8 @@ class SceneTextManager(QObject): if restore_charfmts: char_fmts = blkitem.get_char_fmts() blkitem.setRect(xywh, repaint=False) blkitem.setPlainText(new_text) blkitem.setRect(xywh) if len(self.pairwidget_list) > blkitem.idx: self.pairwidget_list[blkitem.idx].e_trans.setPlainText(new_text) if restore_charfmts: Loading @@ -615,6 +627,8 @@ class SceneTextManager(QObject): cpos = 0 num_text = len(new_text) num_fmt = len(char_fmts) blkitem.layout.relayout_on_changed = False blkitem.repaint_on_changed = False for fmt_i in range(num_fmt): fmt = char_fmts[fmt_i] ori_char = text[fmt_i].strip() Loading @@ -634,7 +648,12 @@ class SceneTextManager(QObject): cursor.setPosition(cpos) cursor.setPosition(cpos+1, QTextCursor.MoveMode.KeepAnchor) cursor.setCharFormat(fmt) cursor.setBlockCharFormat(fmt) cpos += 1 blkitem.repaint_on_changed = True blkitem.layout.relayout_on_changed = True blkitem.layout.reLayout() blkitem.repaint_background() def onEndCreateTextBlock(self, rect: QRectF): Loading ballontranslator/ui/textitem.py +9 −7 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ class TextBlkItem(QGraphicsTextItem): self.bound_checking = False # not used self.oldPos = QPointF() self.oldRect = QRectF() self.repaint_on_changed = True self.layout: Union[VerticalTextDocumentLayout, HorizontalTextDocumentLayout] = None self.document().setDocumentMargin(0) Loading @@ -60,6 +61,7 @@ class TextBlkItem(QGraphicsTextItem): def onDocumentContentChanged(self): if self.hasFocus(): self.content_changed.emit(self) if self.repaint_on_changed: if self.stroke_width != 0 and not self.repainting: self.repaint_background() self.update() Loading Loading @@ -305,9 +307,7 @@ class TextBlkItem(QGraphicsTextItem): self.repaint_background() if self.letter_spacing != 1: ls = self.letter_spacing self.letter_spacing = 1 self.setLetterSpacing(ls) self.setLetterSpacing(self.letter_spacing, force=True) self.doc_size_changed.emit(self.idx) Loading Loading @@ -496,6 +496,7 @@ class TextBlkItem(QGraphicsTextItem): # https://doc.qt.io/qt-5/qfont.html#Weight-enum, 50 is normal if weight == 0: weight = 50 font_format = FontFormat( font.family(), font.pointSizeF(), Loading Loading @@ -557,6 +558,7 @@ class TextBlkItem(QGraphicsTextItem): if ffmat.vertical: self.setLetterSpacing(ffmat.letter_spacing) self.letter_spacing = ffmat.letter_spacing self.setLineSpacing(ffmat.line_spacing) def updateBlkFormat(self): Loading @@ -576,8 +578,8 @@ class TextBlkItem(QGraphicsTextItem): self.layout.setLineSpacing(self.line_spacing) self.repaint_background() def setLetterSpacing(self, letter_spacing: float, repaint_background=True): if self.letter_spacing == letter_spacing: def setLetterSpacing(self, letter_spacing: float, repaint_background=True, force=False): if self.letter_spacing == letter_spacing and not force: return self.letter_spacing = letter_spacing if self.is_vertical: Loading Loading
ballontranslator/ui/scene_textlayout.py +23 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ class SceneTextLayout(QAbstractTextDocumentLayout): self.block_charfmt_lst = [] self.block_ideal_width = [] self.need_ideal_width = False self.block_ideal_height = [] self.need_ideal_height = False self._map_charidx2frag = [] self._max_font_size = -1 Loading Loading @@ -192,9 +195,11 @@ class SceneTextLayout(QAbstractTextDocumentLayout): block = self.document().firstBlock() self.block_charfmt_lst = [] self.block_ideal_width = [] self.block_ideal_height = [] self._map_charidx2frag = [] while block.isValid(): charfmt_lst, ideal_width, char_idx = [], -1, 0 ideal_height = 0 charidx_map = {} it = block.begin() frag_idx = 0 Loading @@ -202,11 +207,20 @@ class SceneTextLayout(QAbstractTextDocumentLayout): fragment = it.fragment() fcmt = fragment.charFormat() cfmt = CharFontFormat(fcmt) charfmt_lst.append(cfmt) if cfmt.size > self._max_font_size: self._max_font_size = cfmt.size if ideal_width < cfmt.br.width(): ideal_width = cfmt.br.width() charfmt_lst.append(cfmt) if self.need_ideal_width: w_ = cfmt.br.width() if ideal_width < w_: ideal_width = w_ if self.need_ideal_height: h_ = cfmt.punc_rect('fg')[0].height() if ideal_height < h_: ideal_height = h_ text_len = fragment.length() for _ in range(text_len): charidx_map[char_idx] = frag_idx Loading @@ -215,6 +229,7 @@ class SceneTextLayout(QAbstractTextDocumentLayout): frag_idx += 1 self.block_charfmt_lst.append(charfmt_lst) self.block_ideal_width.append(ideal_width) self.block_ideal_height.append(ideal_height) self._map_charidx2frag.append(charidx_map) block = block.next() self.reLayout() Loading @@ -238,6 +253,7 @@ class VerticalTextDocumentLayout(SceneTextLayout): self.punc_align_center = True self.draw_shifted = 0 self.need_ideal_width = True self.line_draw = line_draw_qt6 if C.FLAG_QT6 else line_draw_qt5 @property Loading Loading @@ -608,6 +624,7 @@ class HorizontalTextDocumentLayout(SceneTextLayout): def __init__(self, doc: QTextDocument): super().__init__(doc) self.need_ideal_height = True def reLayout(self): doc = self.document() Loading Loading @@ -679,6 +696,7 @@ class HorizontalTextDocumentLayout(SceneTextLayout): fm = QFontMetrics(font) doc_margin = self.document().documentMargin() idea_height = self.block_ideal_height[block.blockNumber()] if block == doc.firstBlock(): self.x_offset_lst = [] self.y_offset_lst = [] Loading @@ -695,8 +713,8 @@ class HorizontalTextDocumentLayout(SceneTextLayout): line.setLeadingIncluded(False) line.setLineWidth(self.available_width) line.setPosition(QPointF(doc_margin, y_offset)) self.y_bottom = tbr.height() + y_offset + line.descent() #???? y_offset += tbr.height() * self.line_spacing self.y_bottom = idea_height + y_offset + line.descent() #???? y_offset += idea_height * self.line_spacing line_idx += 1 tl.endLayout() self.y_offset_lst.append(y_offset) Loading
ballontranslator/ui/scenetext_manager.py +25 −6 Original line number Diff line number Diff line Loading @@ -201,18 +201,29 @@ class AutoLayoutCommand(QUndoCommand): for item in items: self.new_html_lst.append(item.toHtml()) self.new_rect_lst.append(item.absBoundingRect()) self.counter = 0 def redo(self): self.counter += 1 if self.counter <= 1: return for item, trans_widget, html, rect in zip(self.items, self.trans_widget_lst, self.new_html_lst, self.new_rect_lst): item.setHtml(html) trans_widget.setPlainText(item.toPlainText()) item.setRect(rect) item.setPlainText('') item.setRect(rect, repaint=False) item.setHtml(html) if item.letter_spacing != 1: item.setLetterSpacing(item.letter_spacing, force=True) def undo(self): for item, trans_widget, html, rect in zip(self.items, self.trans_widget_lst, self.old_html_lst, self.old_rect_lst): item.setHtml(html) trans_widget.setPlainText(item.toPlainText()) item.setRect(rect) item.setPlainText('') item.setRect(rect, repaint=False) item.setHtml(html) if item.letter_spacing != 1: item.setLetterSpacing(item.letter_spacing, force=True) class SceneTextManager(QObject): Loading Loading @@ -466,6 +477,7 @@ class SceneTextManager(QObject): blk_font = blkitem.font() fmt = blkitem.get_fontformat() blk_font.setLetterSpacing(QFont.SpacingType.PercentageSpacing, fmt.letter_spacing * 100) text_size_func = lambda text: get_text_size(QFontMetrics(blk_font), text) src_is_cjk = is_cjk(self.config.dl.translate_source) Loading Loading @@ -603,8 +615,8 @@ class SceneTextManager(QObject): if restore_charfmts: char_fmts = blkitem.get_char_fmts() blkitem.setRect(xywh, repaint=False) blkitem.setPlainText(new_text) blkitem.setRect(xywh) if len(self.pairwidget_list) > blkitem.idx: self.pairwidget_list[blkitem.idx].e_trans.setPlainText(new_text) if restore_charfmts: Loading @@ -615,6 +627,8 @@ class SceneTextManager(QObject): cpos = 0 num_text = len(new_text) num_fmt = len(char_fmts) blkitem.layout.relayout_on_changed = False blkitem.repaint_on_changed = False for fmt_i in range(num_fmt): fmt = char_fmts[fmt_i] ori_char = text[fmt_i].strip() Loading @@ -634,7 +648,12 @@ class SceneTextManager(QObject): cursor.setPosition(cpos) cursor.setPosition(cpos+1, QTextCursor.MoveMode.KeepAnchor) cursor.setCharFormat(fmt) cursor.setBlockCharFormat(fmt) cpos += 1 blkitem.repaint_on_changed = True blkitem.layout.relayout_on_changed = True blkitem.layout.reLayout() blkitem.repaint_background() def onEndCreateTextBlock(self, rect: QRectF): Loading
ballontranslator/ui/textitem.py +9 −7 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ class TextBlkItem(QGraphicsTextItem): self.bound_checking = False # not used self.oldPos = QPointF() self.oldRect = QRectF() self.repaint_on_changed = True self.layout: Union[VerticalTextDocumentLayout, HorizontalTextDocumentLayout] = None self.document().setDocumentMargin(0) Loading @@ -60,6 +61,7 @@ class TextBlkItem(QGraphicsTextItem): def onDocumentContentChanged(self): if self.hasFocus(): self.content_changed.emit(self) if self.repaint_on_changed: if self.stroke_width != 0 and not self.repainting: self.repaint_background() self.update() Loading Loading @@ -305,9 +307,7 @@ class TextBlkItem(QGraphicsTextItem): self.repaint_background() if self.letter_spacing != 1: ls = self.letter_spacing self.letter_spacing = 1 self.setLetterSpacing(ls) self.setLetterSpacing(self.letter_spacing, force=True) self.doc_size_changed.emit(self.idx) Loading Loading @@ -496,6 +496,7 @@ class TextBlkItem(QGraphicsTextItem): # https://doc.qt.io/qt-5/qfont.html#Weight-enum, 50 is normal if weight == 0: weight = 50 font_format = FontFormat( font.family(), font.pointSizeF(), Loading Loading @@ -557,6 +558,7 @@ class TextBlkItem(QGraphicsTextItem): if ffmat.vertical: self.setLetterSpacing(ffmat.letter_spacing) self.letter_spacing = ffmat.letter_spacing self.setLineSpacing(ffmat.line_spacing) def updateBlkFormat(self): Loading @@ -576,8 +578,8 @@ class TextBlkItem(QGraphicsTextItem): self.layout.setLineSpacing(self.line_spacing) self.repaint_background() def setLetterSpacing(self, letter_spacing: float, repaint_background=True): if self.letter_spacing == letter_spacing: def setLetterSpacing(self, letter_spacing: float, repaint_background=True, force=False): if self.letter_spacing == letter_spacing and not force: return self.letter_spacing = letter_spacing if self.is_vertical: Loading