fix for tilde in OpenSans now in Text, FlatTextarea, InputField and InputArea'

This commit is contained in:
John Preston 2015-10-27 23:43:42 -04:00
parent e2f83e1662
commit 81f523cd21
4 changed files with 160 additions and 72 deletions

View File

@ -909,6 +909,9 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
int32 emojiPosition = 0, emojiLen = 0; int32 emojiPosition = 0, emojiLen = 0;
const EmojiData *emoji = 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()); QTextDocument *doc(_inner.document());
QTextCursor c(_inner.textCursor()); QTextCursor c(_inner.textCursor());
c.joinPreviousEditBlock(); c.joinPreviousEditBlock();
@ -929,30 +932,59 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) {
QString t(fragment.text()); QString t(fragment.text());
const QChar *ch = t.constData(), *e = ch + t.size(); 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); emoji = emojiFromText(ch, e, emojiLen);
if (emoji) { if (emoji) {
emojiPosition = fp + (ch - t.constData()); emojiPosition = fp;
break; 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 (emojiPosition) {
if (!_inner.document()->pageSize().isNull()) { if (emoji) {
_inner.document()->setPageSize(QSizeF(0, 0)); 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);
} }
charsAdded -= emojiPosition + emojiLen - position;
QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
int32 removedUpto = c.position();
insertEmoji(emoji, c);
charsAdded -= removedUpto - position;
position = emojiPosition + 1; position = emojiPosition + 1;
emoji = 0; emoji = 0;
@ -1565,7 +1597,8 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
int32 emojiPosition = 0, emojiLen = 0; int32 emojiPosition = 0, emojiLen = 0;
const EmojiData *emoji = 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()); QTextDocument *doc(_inner.document());
QTextCursor c(_inner.textCursor()); QTextCursor c(_inner.textCursor());
@ -1587,55 +1620,81 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) {
QString t(fragment.text()); QString t(fragment.text());
const QChar *ch = t.constData(), *e = ch + t.size(); 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 // QTextBeginningOfFrame // QTextEndOfFrame
if (ch->unicode() == 0xfdd0 || ch->unicode() == 0xfdd1 || ch->unicode() == QChar::ParagraphSeparator || ch->unicode() == QChar::LineSeparator || ch->unicode() == '\n' || ch->unicode() == '\r') { 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()) { if (!_inner.document()->pageSize().isNull()) {
_inner.document()->setPageSize(QSizeF(0, 0)); _inner.document()->setPageSize(QSizeF(0, 0));
} }
int32 nlPosition = fp + (ch - t.constData()); emojiPosition = fp;
QTextCursor c(doc->docHandle(), nlPosition); emojiLen = 1;
c.setPosition(nlPosition + 1, QTextCursor::KeepAnchor); QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
c.insertText(space); c.insertText(space);
position = nlPosition + 1;
emoji = TwoSymbolEmoji; // just a flag
break; break;
} }
emoji = emojiFromText(ch, e, emojiLen); emoji = emojiFromText(ch, e, emojiLen);
if (emoji) { if (emoji) {
emojiPosition = fp + (ch - t.constData()); emojiPosition = fp;
break; 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()) { if (b.next() != doc->end()) {
int32 nlPosition = b.next().position() - 1; emojiPosition = b.next().position() - 1;
QTextCursor c(doc->docHandle(), nlPosition); emojiLen = 1;
c.setPosition(nlPosition + 1, QTextCursor::KeepAnchor); QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
c.insertText(space); c.insertText(space);
position = nlPosition + 1;
emoji = TwoSymbolEmoji; // just a flag
break; break;
} }
} }
if (emoji == TwoSymbolEmoji) { // just skip if (emojiPosition) {
emoji = 0; if (emoji) {
emojiPosition = 0; if (!_inner.document()->pageSize().isNull()) {
} else if (emoji) { _inner.document()->setPageSize(QSizeF(0, 0));
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);
} }
charsAdded -= emojiPosition + emojiLen - position;
QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
int32 removedUpto = c.position();
insertEmoji(emoji, c);
charsAdded -= removedUpto - position;
position = emojiPosition + 1; position = emojiPosition + 1;
emoji = 0; emoji = 0;

View File

@ -622,8 +622,10 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) {
int32 emojiPosition = 0, emojiLen = 0; int32 emojiPosition = 0, emojiLen = 0;
const EmojiData *emoji = 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) { while (true) {
int32 start = position, end = position + charsAdded; int32 start = position, end = position + charsAdded;
QTextBlock from = doc->findBlock(start), till = doc->findBlock(end); 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) { if (fp >= end || fe <= start) {
continue; continue;
} }
QString t(fragment.text()); QString t(fragment.text());
const QChar *ch = t.constData(), *e = ch + t.size(); 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); emoji = emojiFromText(ch, e, emojiLen);
if (emoji) { if (emoji) {
emojiPosition = fp + (ch - t.constData()); emojiPosition = fp;
break; 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 (emojiPosition) {
if (!document()->pageSize().isNull()) { if (emoji) {
document()->setPageSize(QSizeF(0, 0)); if (!document()->pageSize().isNull()) {
document()->setPageSize(QSizeF(0, 0));
}
QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
insertEmoji(emoji, c);
} }
charsAdded -= emojiPosition + emojiLen - position;
QTextCursor c(doc->docHandle(), emojiPosition);
c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor);
int32 removedUpto = c.position();
insertEmoji(emoji, c);
charsAdded -= removedUpto - position;
position = emojiPosition + 1; position = emojiPosition + 1;
emoji = 0; emoji = 0;

View File

@ -575,13 +575,12 @@ public:
if (skip) { if (skip) {
ch = 0; ch = 0;
} else { } else {
if (isTilde) { if (isTilde) { // tilde fix in OpenSans
if (!(flags & TextBlockFTilde)) { if (!(flags & TextBlockFTilde)) {
createBlock(); createBlock();
flags |= TextBlockFTilde; flags |= TextBlockFTilde;
} }
} } else {
else {
if (flags & TextBlockFTilde) { if (flags & TextBlockFTilde) {
createBlock(); createBlock();
flags &= ~TextBlockFTilde; flags &= ~TextBlockFTilde;
@ -1786,8 +1785,8 @@ public:
} }
if (flags & TextBlockFItalic) result = result->italic(); if (flags & TextBlockFItalic) result = result->italic();
if (flags & TextBlockFUnderline) result = result->underline(); if (flags & TextBlockFUnderline) result = result->underline();
if ((flags & TextBlockFTilde) && f->size() == 13) { if ((flags & TextBlockFTilde) && !cRetina() && f->size() == 13 && f->flags() == 0) { // tilde fix in OpenSans
result = style::font(f->size() + 1, result->flags(), result->family()); result = st::semiboldFont;
} }
} }
return result; 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 & TextBlockFItalic) blockFont = blockFont->italic();
if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); if (flags & TextBlockFUnderline) blockFont = blockFont->underline();
if ((flags & TextBlockFTilde) && font->size() == 13) { if ((flags & TextBlockFTilde) && !cRetina() && font->size() == 13 && font->flags() == 0) { // tilde fix in OpenSans
blockFont = style::font(font->size() + 1, blockFont->flags(), blockFont->family()); blockFont = st::semiboldFont;
} }
} }

View File

@ -128,7 +128,7 @@ enum TextBlockFlags {
TextBlockFBold = 0x01, TextBlockFBold = 0x01,
TextBlockFItalic = 0x02, TextBlockFItalic = 0x02,
TextBlockFUnderline = 0x04, TextBlockFUnderline = 0x04,
TextBlockFTilde = 0x08, // hack for ~ in OpenSans TextBlockFTilde = 0x08, // tilde fix in OpenSans
TextBlockFSemibold = 0x10, TextBlockFSemibold = 0x10,
TextBlockFCode = 0x20, TextBlockFCode = 0x20,
TextBlockFPre = 0x40, TextBlockFPre = 0x40,