From 81f523cd210a7ad731727722babb38f51d1fca16 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 27 Oct 2015 23:43:42 -0400 Subject: [PATCH] fix for tilde in OpenSans now in Text, FlatTextarea, InputField and InputArea' --- Telegram/SourceFiles/gui/flatinput.cpp | 151 +++++++++++++++------- Telegram/SourceFiles/gui/flattextarea.cpp | 66 +++++++--- Telegram/SourceFiles/gui/text.cpp | 13 +- Telegram/SourceFiles/gui/text.h | 2 +- 4 files changed, 160 insertions(+), 72 deletions(-) diff --git a/Telegram/SourceFiles/gui/flatinput.cpp b/Telegram/SourceFiles/gui/flatinput.cpp index 0a05271029..9fe3f4912e 100644 --- a/Telegram/SourceFiles/gui/flatinput.cpp +++ b/Telegram/SourceFiles/gui/flatinput.cpp @@ -909,6 +909,9 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) { int32 emojiPosition = 0, emojiLen = 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), prevTilde = false; + QTextDocument *doc(_inner.document()); QTextCursor c(_inner.textCursor()); c.joinPreviousEditBlock(); @@ -929,30 +932,59 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) { QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); - for (; ch != e; ++ch) { + for (; ch != e; ++ch, ++fp) { + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + QString fontfamily; + if (tilde) { + if (fragment.charFormat().fontFamily() != semibold) { + fontfamily = semibold; + } + } else if (prevTilde) { + if (fragment.charFormat().fontFamily() == semibold) { + fontfamily = regular; + } + } + if (!fontfamily.isEmpty()) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); + } + emojiPosition = fp; + emojiLen = 1; + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + QTextCharFormat format; + format.setFontFamily(fontfamily); + c.mergeCharFormat(format); + break; + } + prevTilde = tilde; + } + emoji = emojiFromText(ch, e, emojiLen); if (emoji) { - emojiPosition = fp + (ch - t.constData()); + emojiPosition = fp; break; } - if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch; + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { + ++ch; + ++fp; + } } - if (emoji) break; + if (emojiPosition) break; } - if (emoji) break; + if (emojiPosition) break; } - if (emoji) { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); + if (emojiPosition) { + if (emoji) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); + } + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + insertEmoji(emoji, c); } - - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - int32 removedUpto = c.position(); - - insertEmoji(emoji, c); - - charsAdded -= removedUpto - position; + charsAdded -= emojiPosition + emojiLen - position; position = emojiPosition + 1; emoji = 0; @@ -1565,7 +1597,8 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) { int32 emojiPosition = 0, emojiLen = 0; const EmojiData *emoji = 0; - static QString space(' '); + static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"), space(' '); + bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), prevTilde = false; QTextDocument *doc(_inner.document()); QTextCursor c(_inner.textCursor()); @@ -1587,55 +1620,81 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) { QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); - for (; ch != e; ++ch) { + for (; ch != e; ++ch, ++fp) { + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + QString fontfamily; + if (tilde) { + if (fragment.charFormat().fontFamily() != semibold) { + fontfamily = semibold; + } + } else if (prevTilde) { + if (fragment.charFormat().fontFamily() == semibold) { + fontfamily = regular; + } + } + if (!fontfamily.isEmpty()) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); + } + emojiPosition = fp; + emojiLen = 1; + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + QTextCharFormat format; + format.setFontFamily(fontfamily); + c.mergeCharFormat(format); + break; + } + prevTilde = tilde; + } + // 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); + emojiPosition = fp; + emojiLen = 1; + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, 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()); + emojiPosition = fp; break; } - if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch; + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { + ++ch; + ++fp; + } } - if (emoji) break; + if (emojiPosition) break; } - if (emoji) break; + if (emojiPosition) break; + if (b.next() != doc->end()) { - int32 nlPosition = b.next().position() - 1; - QTextCursor c(doc->docHandle(), nlPosition); - c.setPosition(nlPosition + 1, QTextCursor::KeepAnchor); + emojiPosition = b.next().position() - 1; + emojiLen = 1; + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, 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)); + if (emojiPosition) { + if (emoji) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); + } + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + insertEmoji(emoji, c); } - - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - int32 removedUpto = c.position(); - - insertEmoji(emoji, c); - - charsAdded -= removedUpto - position; + charsAdded -= emojiPosition + emojiLen - position; position = emojiPosition + 1; emoji = 0; diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index b2ed133915..b1acafb106 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -622,8 +622,10 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { int32 emojiPosition = 0, emojiLen = 0; const EmojiData *emoji = 0; - QTextDocument *doc(document()); + static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"); + bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), prevTilde = false; + QTextDocument *doc(document()); while (true) { int32 start = position, end = position + charsAdded; QTextBlock from = doc->findBlock(start), till = doc->findBlock(end); @@ -638,33 +640,61 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { if (fp >= end || fe <= start) { continue; } - QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); - for (; ch != e; ++ch) { + for (; ch != e; ++ch, ++fp) { + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + QString fontfamily; + if (tilde) { + if (fragment.charFormat().fontFamily() != semibold) { + fontfamily = semibold; + } + } else if (prevTilde) { + if (fragment.charFormat().fontFamily() == semibold) { + fontfamily = regular; + } + } + if (!fontfamily.isEmpty()) { + if (!document()->pageSize().isNull()) { + document()->setPageSize(QSizeF(0, 0)); + } + emojiPosition = fp; + emojiLen = 1; + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + QTextCharFormat format; + format.setFontFamily(fontfamily); + c.mergeCharFormat(format); + break; + } + prevTilde = tilde; + } + emoji = emojiFromText(ch, e, emojiLen); if (emoji) { - emojiPosition = fp + (ch - t.constData()); + emojiPosition = fp; break; } - if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch; + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { + ++ch; + ++fp; + } } - if (emoji) break; + if (emojiPosition) break; } - if (emoji) break; + if (emojiPosition) break; } - if (emoji) { - if (!document()->pageSize().isNull()) { - document()->setPageSize(QSizeF(0, 0)); + if (emojiPosition) { + if (emoji) { + if (!document()->pageSize().isNull()) { + document()->setPageSize(QSizeF(0, 0)); + } + QTextCursor c(doc->docHandle(), emojiPosition); + c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); + insertEmoji(emoji, c); } - - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - int32 removedUpto = c.position(); - - insertEmoji(emoji, c); - - charsAdded -= removedUpto - position; + charsAdded -= emojiPosition + emojiLen - position; position = emojiPosition + 1; emoji = 0; diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index bcd702205e..a7fb10ad55 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -575,13 +575,12 @@ public: if (skip) { ch = 0; } else { - if (isTilde) { + if (isTilde) { // tilde fix in OpenSans if (!(flags & TextBlockFTilde)) { createBlock(); flags |= TextBlockFTilde; } - } - else { + } else { if (flags & TextBlockFTilde) { createBlock(); flags &= ~TextBlockFTilde; @@ -1786,8 +1785,8 @@ public: } if (flags & TextBlockFItalic) result = result->italic(); if (flags & TextBlockFUnderline) result = result->underline(); - if ((flags & TextBlockFTilde) && f->size() == 13) { - result = style::font(f->size() + 1, result->flags(), result->family()); + if ((flags & TextBlockFTilde) && !cRetina() && f->size() == 13 && f->flags() == 0) { // tilde fix in OpenSans + result = st::semiboldFont; } } return result; @@ -3245,8 +3244,8 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi } if (flags & TextBlockFItalic) blockFont = blockFont->italic(); if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); - if ((flags & TextBlockFTilde) && font->size() == 13) { - blockFont = style::font(font->size() + 1, blockFont->flags(), blockFont->family()); + if ((flags & TextBlockFTilde) && !cRetina() && font->size() == 13 && font->flags() == 0) { // tilde fix in OpenSans + blockFont = st::semiboldFont; } } diff --git a/Telegram/SourceFiles/gui/text.h b/Telegram/SourceFiles/gui/text.h index 885f65ebd2..38db378ad3 100644 --- a/Telegram/SourceFiles/gui/text.h +++ b/Telegram/SourceFiles/gui/text.h @@ -128,7 +128,7 @@ enum TextBlockFlags { TextBlockFBold = 0x01, TextBlockFItalic = 0x02, TextBlockFUnderline = 0x04, - TextBlockFTilde = 0x08, // hack for ~ in OpenSans + TextBlockFTilde = 0x08, // tilde fix in OpenSans TextBlockFSemibold = 0x10, TextBlockFCode = 0x20, TextBlockFPre = 0x40,