Пример #1
0
void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
    int32 emojiPosition = 0, emojiLen = 0;
    const EmojiData *emoji = 0;

    QTextDocument *doc(document());

    while (true) {
        int32 start = position, end = position + charsAdded;
        QTextBlock from = doc->findBlock(start), till = doc->findBlock(end);
        if (till.isValid()) till = till.next();

        for (QTextBlock b = from; b != till; b = b.next()) {
            for (QTextBlock::Iterator iter = b.begin(); !iter.atEnd(); ++iter) {
                QTextFragment fragment(iter.fragment());
                if (!fragment.isValid()) continue;

                int32 fp = fragment.position(), fe = fp + fragment.length();
                if (fp >= end || fe <= start) {
                    continue;
                }

                QString t(fragment.text());
                const QChar *ch = t.constData(), *e = ch + t.size();
                for (; ch != e; ++ch) {
                    emoji = emojiFromText(ch, e, emojiLen);
                    if (emoji) {
                        emojiPosition = fp + (ch - t.constData());
                        break;
                    }
                    if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
                }
                if (emoji) break;
            }
            if (emoji) break;
        }
        if (emoji) {
            if (!document()->pageSize().isNull()) {
                document()->setPageSize(QSizeF(0, 0));
            }

            QTextCursor c(doc->docHandle(), emojiPosition);
            c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
            int32 removedUpto = c.position();

            insertEmoji(emoji, c);

            charsAdded -= removedUpto - position;
            position = emojiPosition + 1;

            emoji = 0;
            emojiPosition = 0;
        } else {
            break;
        }
    }
}
Пример #2
0
void InputField::processDocumentContentsChange(int position, int charsAdded) {
	int32 emojiPosition = 0, emojiLen = 0;
	const EmojiData *emoji = 0;

	static QString space(' ');

	QTextDocument *doc(_inner.document());
	QTextCursor c(_inner.textCursor());
	c.joinPreviousEditBlock();
	while (true) {
		int32 start = position, end = position + charsAdded;
		QTextBlock from = doc->findBlock(start), till = doc->findBlock(end);
		if (till.isValid()) till = till.next();

		for (QTextBlock b = from; b != till; b = b.next()) {
			for (QTextBlock::Iterator iter = b.begin(); !iter.atEnd(); ++iter) {
				QTextFragment fragment(iter.fragment());
				if (!fragment.isValid()) continue;

				int32 fp = fragment.position(), fe = fp + fragment.length();
				if (fp >= end || fe <= start) {
					continue;
				}

				QString t(fragment.text());
				const QChar *ch = t.constData(), *e = ch + t.size();
				for (; ch != e; ++ch) {
					// QTextBeginningOfFrame // QTextEndOfFrame
					if (ch->unicode() == 0xfdd0 || ch->unicode() == 0xfdd1 || ch->unicode() == QChar::ParagraphSeparator || ch->unicode() == QChar::LineSeparator || ch->unicode() == '\n' || ch->unicode() == '\r') {
						if (!_inner.document()->pageSize().isNull()) {
							_inner.document()->setPageSize(QSizeF(0, 0));
						}
						int32 nlPosition = fp + (ch - t.constData());
						QTextCursor c(doc->docHandle(), nlPosition);
						c.setPosition(nlPosition + 1, QTextCursor::KeepAnchor);
						c.insertText(space);
						position = nlPosition + 1;
						emoji = TwoSymbolEmoji; // just a flag
						break;
					}
					emoji = emojiFromText(ch, e, emojiLen);
					if (emoji) {
						emojiPosition = fp + (ch - t.constData());
						break;
					}
					if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
				}
				if (emoji) break;
			}
			if (emoji) break;
			if (b.next() != doc->end()) {
				int32 nlPosition = b.next().position() - 1;
				QTextCursor c(doc->docHandle(), nlPosition);
				c.setPosition(nlPosition + 1, QTextCursor::KeepAnchor);
				c.insertText(space);
				position = nlPosition + 1;
				emoji = TwoSymbolEmoji; // just a flag
				break;
			}
		}
		if (emoji == TwoSymbolEmoji) { // just skip
			emoji = 0;
			emojiPosition = 0;
		} else if (emoji) {
			if (!_inner.document()->pageSize().isNull()) {
				_inner.document()->setPageSize(QSizeF(0, 0));
			}

			QTextCursor c(doc->docHandle(), emojiPosition);
			c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
			int32 removedUpto = c.position();

			insertEmoji(emoji, c);

			for (Insertions::iterator i = _insertions.begin(), e = _insertions.end(); i != e; ++i) {
				if (i->first >= removedUpto) {
					i->first -= removedUpto - emojiPosition - 1;
				} else if (i->first >= emojiPosition) {
					i->second -= removedUpto - emojiPosition;
					i->first = emojiPosition + 1;
				} else if (i->first + i->second > emojiPosition + 1) {
					i->second -= qMin(removedUpto, i->first + i->second) - emojiPosition;
				}
			}

			charsAdded -= removedUpto - position;
			position = emojiPosition + 1;

			emoji = 0;
			emojiPosition = 0;
		} else {
			break;
		}
	}
	c.endEditBlock();
}
Пример #3
0
void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
	int32 replacePosition = -1, replaceLen = 0;
	const EmojiData *emoji = 0;

	static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold");
	bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), wasTildeFragment = false;

	QTextDocument *doc(document());
	while (true) {
		int32 start = position, end = position + charsAdded;
		QTextBlock from = doc->findBlock(start), till = doc->findBlock(end);
		if (till.isValid()) till = till.next();

		for (QTextBlock b = from; b != till; b = b.next()) {
			for (QTextBlock::Iterator iter = b.begin(); !iter.atEnd(); ++iter) {
				QTextFragment fragment(iter.fragment());
				if (!fragment.isValid()) continue;

				int32 fp = fragment.position(), fe = fp + fragment.length();
				if (fp >= end || fe <= start) {
					continue;
				}

				if (checkTilde) {
					wasTildeFragment = (fragment.charFormat().fontFamily() == semibold);
				}

				QString t(fragment.text());
				const QChar *ch = t.constData(), *e = ch + t.size();
				for (; ch != e; ++ch, ++fp) {
					int32 emojiLen = 0;
					emoji = emojiFromText(ch, e, &emojiLen);
					if (emoji) {
						if (replacePosition >= 0) {
							emoji = 0; // replace tilde char format first
						} else {
							replacePosition = fp;
							replaceLen = emojiLen;
						}
						break;
					}

					if (checkTilde && fp >= position) { // tilde fix in OpenSans
						bool tilde = (ch->unicode() == '~');
						if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) {
							if (replacePosition < 0) {
								replacePosition = fp;
								replaceLen = 1;
							} else {
								++replaceLen;
							}
						} else if (replacePosition >= 0) {
							break;
						}
					}

					if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) {
						++ch;
						++fp;
					}
				}
				if (replacePosition >= 0) break;
			}
			if (replacePosition >= 0) break;
		}
		if (replacePosition >= 0) {
			if (!document()->pageSize().isNull()) {
				document()->setPageSize(QSizeF(0, 0));
			}
			QTextCursor c(doc->docHandle(), replacePosition);
			c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor);
			if (emoji) {
				insertEmoji(emoji, c);
			} else {
				QTextCharFormat format;
				format.setFontFamily(wasTildeFragment ? regular : semibold);
				c.mergeCharFormat(format);
			}
			charsAdded -= replacePosition + replaceLen - position;
			position = replacePosition + (emoji ? 1 : replaceLen);

			emoji = 0;
			replacePosition = -1;
		} else {
			break;
		}
	}
}