Commit d0b47afc authored by dmMaze's avatar dmMaze
Browse files

fix letter spacing with auto layout

parent 2d1c963c
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -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

@@ -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
@@ -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
@@ -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()
@@ -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
@@ -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()
@@ -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 = []
@@ -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)
+25 −6
Original line number Diff line number Diff line
@@ -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):
@@ -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)
@@ -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:
@@ -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()
@@ -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):
+9 −7
Original line number Diff line number Diff line
@@ -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)
@@ -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()
@@ -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)

@@ -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(),
@@ -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):
@@ -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: