I'm creating pyqt6 app where I can replace normal fonts/text with svg fonts(.svg files like a.svg, b.svg etc). My issue is with word-wrap. In normal mode(svg mode is disabled) QTextEdit correctly moves a word to nex line if it does not fit completely in the line. But in svg mode it does not behave like that. It breaks word and pushes its some characters to the next line instead of moving the whole word to the next line. I tried replacing space(' ') with '\u200B' or ' ' + '\u200B'. But nothing works. Enter works as expected. Below is the relevant code: NON_SVG_CHARS = {' ', '\t', '\u2029', '\r', '\n'} class SvgTextObject(QObject, QTextObjectInterface): def __init__(self, char_path, parent=None): QObject.__init__(self, parent) QTextObjectInterface.__init__(self) self.char_path = char_path self.svg_renderer_cache = {} self.char_properties = {} self.normalized_svg_sizes = {} def intrinsicSize(self, doc, pos, fmt): char_name = fmt.stringProperty(SVGSettings.SVG_TEXT_FORMAT) format_id = fmt.property(SVGSettings.SVG_INSTANCE_ID) properties = self.getProperties(format_id) normalized_size = self.getNormalizedSize(char_name) if not normalized_size.isValid(): return QSizeF() font_size = properties.get(SVGSettings.PropertyStrings.FONT_SIZE, SVGSettings.FontSize.DEFAULT) letter_width_percent = properties.get(SVGSettings.PropertyStrings.LETTER_WIDTH, 100.0) letter_height_percent = properties.get(SVGSettings.PropertyStrings.LETTER_HEIGHT, 100.0) letter_spacing = properties.get(SVGSettings.PropertyStrings.LETTER_SPACING, 0.0) width_scale_factor = (100.0 + letter_width_percent) / 100.0 height_scale_factor = (100.0 + letter_height_percent) / 100.0 base_scale = font_size / normalized_size.height() width = normalized_size.width() * base_scale * width_scale_factor height = normalized_size.height() * base_scale * height_scale_factor #Add spacing to width for layout purposes if pos > 0: prev_char = doc.characterAt(pos - 1) if not prev_char.isspace() and prev_char != QChar('\n'): width += letter_spacing return QSizeF(width, height) def drawObject(self, painter: QPainter, rect, doc, pos, fmt): painter.save() char_name = fmt.stringProperty(SVGSettings.SVG_TEXT_FORMAT) format_id = fmt.property(SVGSettings.SVG_INSTANCE_ID) properties = self.getProperties(format_id) letter_slant_value = properties.get(SVGSettings.PropertyStrings.LETTER_SLANTING, 0.0) letter_base_offset = properties.get(SVGSettings.PropertyStrings.LETTER_BASE_OFFSET, 0.0) letter_spacing = properties.get(SVGSettings.PropertyStrings.LETTER_SPACING, 0.0) normalized_size = self.getNormalizedSize(char_name) if not normalized_size.isValid(): painter.restore() return font_size = properties.get(SVGSettings.PropertyStrings.FONT_SIZE, SVGSettings.FontSize.DEFAULT) letter_width_percent = properties.get(SVGSettings.PropertyStrings.LETTER_WIDTH, 100.0) letter_height_percent = properties.get(SVGSettings.PropertyStrings.LETTER_HEIGHT, 100.0) width_scale_factor = (100.0 + letter_width_percent) / 100.0 height_scale_factor = (100.0 + letter_height_percent) / 100.0 # Calculate scales and offsets based on the font size and character properties base_scale = font_size / normalized_size.height() final_scale_x = base_scale * width_scale_factor final_scale_y = base_scale * height_scale_factor painter.translate(rect.x(), rect.y()) current_x_offset = 0.0 if pos > 0: prev_char = doc.characterAt(pos - 1) if not prev_char.isspace() and prev_char != QChar('\n'): current_x_offset += letter_spacing current_y_offset = letter_base_offset intrinsic_height = self.intrinsicSize(doc, pos, fmt).height() scaled_svg_height = normalized_size.height() * final_scale_y extra_height_space = intrinsic_height - scaled_svg_height current_y_offset += extra_height_space / 2 painter.translate(current_x_offset, current_y_offset) if letter_slant_value != 0.0: transform = painter.transform() transform.shear(letter_slant_value / 100.0, 0) painter.setTransform(transform) painter.scale(final_scale_x, final_scale_y) renderer = self.svg_renderer_cache.get(char_name) if renderer and renderer.isValid(): renderer.render(painter, QRectF(0, 0, normalized_size.width(), normalized_size.height())) painter.restore() class CustomTextEdit(QGraphicsRectItem): def __init__(self, properties_provider=None, svg_font_directory=None, x=20, y=50, w=200, h=100): super().__init__(x, y, w, h) self.svg_font_directory = svg_font_directory self.svg_enabled = True self.text = EditableText(self, properties_provider) self.text.setReadOnly(True) self.text.pasteRequested.connect(self._handle_paste_request) self.text.document().contentsChange.connect(self.handle_contents_change) # self.text.textChanged.connect(self.handle_contents_change) # Register the custom SVG text object with the document's layout self.svg_object = SvgTextObject(self.svg_font_directory) # SVG directory self.text.document().documentLayout().registerHandler(SVGSettings.SVG_TEXT_FORMAT, self.svg_object) def handle_contents_change(self, position, chars_removed, chars_added): # check if replacing chars with svg chars is enabled if not self.svg_enabled: return if self.text._is_pasting: return # We only care about single-character additions if chars_removed == 0 and chars_added == 1: doc = self.text.document() new_char = doc.characterAt(position) if new_char in SVGSettings.NON_SVG_CHARS: return # already converted to unicode if new_char == '\uFFFC': return cursor = self.text.textCursor() self.text.document().blockSignals(True) # Block signals for safety cursor.beginEditBlock() cursor.setPosition(position) cursor.setPosition(position + 1, QTextCursor.MoveMode.KeepAnchor) svg_char_format = QTextCharFormat() svg_char_format.setObjectType(SVGSettings.SVG_TEXT_FORMAT) svg_char_format.setProperty(SVGSettings.SVG_TEXT_FORMAT, new_char) instance_id = str(uuid.uuid4()) svg_char_format.setProperty(SVGSettings.SVG_INSTANCE_ID, instance_id) # Retrieve properties and set them before insertion properties = {} current_properties = self.text.properties_provider.get_current_properties() for prop_name, slider_values in current_properties.items(): settings_class = SVGSettings.SLIDER_MAPPING.get(prop_name) if settings_class: step_size = settings_class.STEP properties[prop_name] = get_random_value_with_step(slider_values, step_size) else: properties[prop_name] = slider_values self.svg_object.setRandomProperties(instance_id, properties) cursor.insertText("\uFFFC", svg_char_format) cursor.endEditBlock() self.text.document().blockSignals(False) # Unblock signals Please, help me solve this issue. Thank you. Continue reading...