diff --git a/Telegram/Packer.vcxproj b/Telegram/Packer.vcxproj
index 2df088b9b..738a43ab7 100644
--- a/Telegram/Packer.vcxproj
+++ b/Telegram/Packer.vcxproj
@@ -77,8 +77,8 @@
Console
$(OutDir)\$(ProjectName).exe
- .\..\..\Libraries\lzma\C\Util\LzmaLib\Debug;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatDebug;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;%(AdditionalLibraryDirectories)
- kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmaind.lib;zlibstat.lib;libeay32MTd.lib;Qt5Cored.lib;LzmaLib.lib;%(AdditionalDependencies)
+ .\..\..\Libraries\lzma\C\Util\LzmaLib\Debug;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatDebug;.\..\..\Libraries\openssl_debug\Debug\lib;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;zlibstat.lib;libeay32.lib;LzmaLib.lib;qtmaind.lib;qtpcred.lib;Qt5Cored.lib;%(AdditionalDependencies)
true
@@ -94,8 +94,8 @@
Console
$(OutDir)\$(ProjectName).exe
- .\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;%(AdditionalLibraryDirectories)
- kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32MT.lib;Qt5Core.lib;LzmaLib.lib;%(AdditionalDependencies)
+ .\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\openssl\Release\lib;%(AdditionalLibraryDirectories)
+ kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;zlibstat.lib;libeay32.lib;LzmaLib.lib;qtmain.lib;qtpcre.lib;Qt5Core.lib;%(AdditionalDependencies)
false
@@ -113,7 +113,7 @@
Console
$(OutDir)\$(ProjectName).exe
.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\openssl\Release\lib;%(AdditionalLibraryDirectories)
- kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32.lib;Qt5Core.lib;qtpcre.lib;LzmaLib.lib;%(AdditionalDependencies)
+ kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;zlibstat.lib;libeay32.lib;LzmaLib.lib;qtmain.lib;qtpcre.lib;Qt5Core.lib;%(AdditionalDependencies)
false
diff --git a/Telegram/Patches/qtbase_5_6_0.diff b/Telegram/Patches/qtbase_5_6_0.diff
index 2bb9052fb..8b3ba042c 100644
--- a/Telegram/Patches/qtbase_5_6_0.diff
+++ b/Telegram/Patches/qtbase_5_6_0.diff
@@ -16,21 +16,6 @@ index eec9e1f..ec3015e 100644
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_LTCG = -GL
QMAKE_CFLAGS_SSE2 = -arch:SSE2
-diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
-index f1a6019..a53a6c4 100644
---- a/src/corelib/io/qfilesystemengine_win.cpp
-+++ b/src/corelib/io/qfilesystemengine_win.cpp
-@@ -1416,8 +1416,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
- COPYFILE2_EXTENDED_PARAMETERS copyParams = {
- sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
- };
-+ // CopyFile2 returns HRESULT, not BOOL, so it should be tested for S_OK, not 0.
- bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
-- (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0;
-+ (const wchar_t*)target.nativeFilePath().utf16(), ©Params) == S_OK;
- #endif // Q_OS_WINRT
- if(!ret)
- error = QSystemError(::GetLastError(), QSystemError::NativeError);
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index 14e4fd1..c31c62b 100644
--- a/src/corelib/tools/qunicodetables.cpp
@@ -114,7 +99,7 @@ index 39c228f..b72fdc0 100644
public:
inline QTextItemInt()
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
-index 9e2a23a..861f202 100644
+index 9e2a23a..4466a4e 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -694,6 +694,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
@@ -136,6 +121,47 @@ index 9e2a23a..861f202 100644
}
return oldPos;
+@@ -1644,6 +1645,7 @@ namespace {
+ int maxGlyphs;
+ int currentPosition;
+ glyph_t previousGlyph;
++ QFontEngine *previousGlyphFontEngine;
+
+ QFixed minw;
+ QFixed softHyphenWidth;
+@@ -1677,13 +1679,14 @@ namespace {
+ if (currentPosition > 0 &&
+ logClusters[currentPosition - 1] < glyphs.numGlyphs) {
+ previousGlyph = currentGlyph(); // needed to calculate right bearing later
++ previousGlyphFontEngine = fontEngine;
+ }
+ }
+
+- inline void calculateRightBearing(glyph_t glyph)
++ inline void calculateRightBearing(QFontEngine *engine, glyph_t glyph)
+ {
+ qreal rb;
+- fontEngine->getGlyphBearings(glyph, 0, &rb);
++ engine->getGlyphBearings(glyph, 0, &rb);
+
+ // We only care about negative right bearings, so we limit the range
+ // of the bearing here so that we can assume it's negative in the rest
+@@ -1696,13 +1699,13 @@ namespace {
+ {
+ if (currentPosition <= 0)
+ return;
+- calculateRightBearing(currentGlyph());
++ calculateRightBearing(fontEngine, currentGlyph());
+ }
+
+ inline void calculateRightBearingForPreviousGlyph()
+ {
+ if (previousGlyph > 0)
+- calculateRightBearing(previousGlyph);
++ calculateRightBearing(previousGlyphFontEngine, previousGlyph);
+ }
+
+ static const QFixed RightBearingNotCalculated;
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index f74d4d4..57d449a 100644
--- a/src/gui/text/qtextlayout.h
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index 74fb00be9..6352baeaf 100644
--- a/Telegram/Resources/winrc/Telegram.rc
+++ b/Telegram/Resources/winrc/Telegram.rc
@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,46,0
- PRODUCTVERSION 0,9,46,0
+ FILEVERSION 0,9,47,0
+ PRODUCTVERSION 0,9,47,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
- VALUE "FileVersion", "0.9.46.0"
+ VALUE "FileVersion", "0.9.47.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "0.9.46.0"
+ VALUE "ProductVersion", "0.9.47.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc
index e6fe4379f..182787008 100644
--- a/Telegram/Resources/winrc/Updater.rc
+++ b/Telegram/Resources/winrc/Updater.rc
@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,46,0
- PRODUCTVERSION 0,9,46,0
+ FILEVERSION 0,9,47,0
+ PRODUCTVERSION 0,9,47,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -43,10 +43,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Updater"
- VALUE "FileVersion", "0.9.46.0"
+ VALUE "FileVersion", "0.9.47.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
- VALUE "ProductVersion", "0.9.46.0"
+ VALUE "ProductVersion", "0.9.47.0"
END
END
BLOCK "VarFileInfo"
diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h
index 8d9baf02c..cce86ebad 100644
--- a/Telegram/SourceFiles/core/version.h
+++ b/Telegram/SourceFiles/core/version.h
@@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#define BETA_VERSION_MACRO (0ULL)
-constexpr int AppVersion = 9046;
-constexpr str_const AppVersionStr = "0.9.46";
-constexpr bool AppAlphaVersion = true;
-constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
+static constexpr int AppVersion = 9047;
+static constexpr str_const AppVersionStr = "0.9.47";
+static constexpr bool AppAlphaVersion = true;
+static constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp
index 6a8aae41b..ea54fa5e0 100644
--- a/Telegram/SourceFiles/logs.cpp
+++ b/Telegram/SourceFiles/logs.cpp
@@ -944,10 +944,14 @@ namespace internal {
#ifdef Q_OS_WIN
internal::BreakpadExceptionHandler = new google_breakpad::ExceptionHandler(
dumpspath.toStdWString(),
- /*FilterCallback*/ 0,
+ google_breakpad::ExceptionHandler::FilterCallback(nullptr),
internal::DumpCallback,
- /*context*/ 0,
- true
+ (void*)nullptr, // callback_context
+ google_breakpad::ExceptionHandler::HANDLER_ALL,
+ MINIDUMP_TYPE(MiniDumpNormal),
+ // MINIDUMP_TYPE(MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithThreadInfo | MiniDumpWithProcessThreadData | MiniDumpWithFullMemoryInfo | MiniDumpWithUnloadedModules | MiniDumpWithFullAuxiliaryState | MiniDumpIgnoreInaccessibleMemory | MiniDumpWithTokenInformation),
+ (const wchar_t*)nullptr, // pipe_name
+ (const google_breakpad::CustomClientInfo*)nullptr
);
#elif defined Q_OS_MAC // Q_OS_WIN
@@ -968,11 +972,11 @@ namespace internal {
std::string handler = (cExeDir() + cExeName() + qsl("/Contents/Helpers/crashpad_handler")).toUtf8().constData();
std::string database = QFile::encodeName(dumpspath).constData();
if (crashpad_client.StartHandler(base::FilePath(handler),
- base::FilePath(database),
- std::string(),
- ProcessAnnotations,
- std::vector(),
- false)) {
+ base::FilePath(database),
+ std::string(),
+ ProcessAnnotations,
+ std::vector(),
+ false)) {
crashpad_client.UseHandler();
}
#endif // else for MAC_USE_BREAKPAD
diff --git a/Telegram/SourceFiles/ui/text/text.cpp b/Telegram/SourceFiles/ui/text/text.cpp
index 291280ceb..ed72e2a50 100644
--- a/Telegram/SourceFiles/ui/text/text.cpp
+++ b/Telegram/SourceFiles/ui/text/text.cpp
@@ -34,18 +34,14 @@ namespace {
const style::textStyle *_textStyle = nullptr;
-void _initDefault() {
+void initDefault() {
_textStyle = &st::defaultTextStyle;
}
-inline int32 _blockHeight(const ITextBlock *b, const style::font &font) {
+inline int32 countBlockHeight(const ITextBlock *b, const style::font &font) {
return (b->type() == TextBlockTSkip) ? static_cast(b)->height() : (_textStyle->lineHeight > font->height) ? _textStyle->lineHeight : font->height;
}
-inline QFixed _blockRBearing(const ITextBlock *b) {
- return (b->type() == TextBlockTText) ? static_cast(b)->f_rbearing() : 0;
-}
-
} // namespace
const style::textStyle *textstyleCurrent() {
@@ -930,7 +926,7 @@ public:
if (_t->isEmpty()) return;
_blocksSize = _t->_blocks.size();
- if (!_textStyle) _initDefault();
+ if (!_textStyle) initDefault();
if (_p) {
_p->setFont(_t->_font->f);
@@ -977,8 +973,7 @@ public:
for (Text::TextBlocks::const_iterator i = _t->_blocks.cbegin(); i != e; ++i, ++blockIndex) {
ITextBlock *b = *i;
TextBlockType _btype = b->type();
- int32 blockHeight = _blockHeight(b, _t->_font);
- QFixed _rb = _blockRBearing(b);
+ int32 blockHeight = countBlockHeight(b, _t->_font);
if (_btype == TextBlockTNewline) {
if (!_lineHeight) _lineHeight = blockHeight;
@@ -990,7 +985,7 @@ public:
_lineStart = nextStart;
_lineStartBlock = blockIndex + 1;
- last_rBearing = _rb;
+ last_rBearing = b->f_rbearing();
last_rPadding = b->f_rpadding();
_wLeft = _w - (b->f_width() - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
@@ -1005,10 +1000,11 @@ public:
continue;
}
- QFixed lpadding = b->f_lpadding();
- QFixed newWidthLeft = _wLeft - lpadding - last_rBearing - (last_rPadding + b->f_width() - _rb);
+ auto b__f_lpadding = b->f_lpadding();
+ auto b__f_rbearing = b->f_rbearing();
+ QFixed newWidthLeft = _wLeft - b__f_lpadding - last_rBearing - (last_rPadding + b->f_width() - b__f_rbearing);
if (newWidthLeft >= 0) {
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
_wLeft = newWidthLeft;
@@ -1021,7 +1017,7 @@ public:
if (_btype == TextBlockTText) {
TextBlock *t = static_cast(b);
if (t->_words.isEmpty()) { // no words in this block, spaces only => layout this block in the same line
- last_rPadding += lpadding;
+ last_rPadding += b__f_lpadding;
_lineHeight = qMax(_lineHeight, blockHeight);
@@ -1032,14 +1028,14 @@ public:
QFixed f_wLeft = _wLeft; // vars for saving state of the last word start
int32 f_lineHeight = _lineHeight; // f points to the last word-start element of t->_words
for (TextBlock::TextWords::const_iterator j = t->_words.cbegin(), en = t->_words.cend(), f = j; j != en; ++j) {
- bool wordEndsHere = (j->width >= 0);
- QFixed j_width = wordEndsHere ? j->width : -j->width;
+ bool wordEndsHere = (j->f_width() >= 0);
+ QFixed j_width = wordEndsHere ? j->f_width() : -j->f_width();
- QFixed newWidthLeft = _wLeft - lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
- lpadding = 0;
+ QFixed newWidthLeft = _wLeft - b__f_lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
+ b__f_lpadding = 0;
if (newWidthLeft >= 0) {
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
_wLeft = newWidthLeft;
_lineHeight = qMax(_lineHeight, blockHeight);
@@ -1064,16 +1060,16 @@ public:
j = f;
_wLeft = f_wLeft;
_lineHeight = f_lineHeight;
- j_width = (j->width >= 0) ? j->width : -j->width;
+ j_width = (j->f_width() >= 0) ? j->f_width() : -j->f_width();
}
- if (!drawLine(elidedLine ? ((j + 1 == en) ? _blockEnd(_t, i, e) : (j + 1)->from) : j->from, i, e)) return;
+ if (!drawLine(elidedLine ? ((j + 1 == en) ? _blockEnd(_t, i, e) : (j + 1)->from()) : j->from(), i, e)) return;
_y += _lineHeight;
_lineHeight = qMax(0, blockHeight);
- _lineStart = j->from;
+ _lineStart = j->from();
_lineStartBlock = blockIndex;
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
_wLeft = _w - (j_width - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
_wLeft -= _elideRemoveFromEnd;
@@ -1098,7 +1094,7 @@ public:
_lineStart = b->from();
_lineStartBlock = blockIndex;
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
_wLeft = _w - (b->f_width() - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
@@ -2426,7 +2422,7 @@ Text &Text::operator=(Text &&other) {
}
void Text::setText(style::font font, const QString &text, const TextParseOptions &options) {
- if (!_textStyle) _initDefault();
+ if (!_textStyle) initDefault();
_font = font;
clear();
{
@@ -2445,9 +2441,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
ITextBlock *b = *i;
TextBlockType _btype = b->type();
- int32 blockHeight = _blockHeight(b, _font);
- QFixed _rb = _blockRBearing(b);
-
+ int32 blockHeight = countBlockHeight(b, _font);
if (_btype == TextBlockTNewline) {
if (!lineHeight) lineHeight = blockHeight;
if (initial) {
@@ -2466,7 +2460,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
_minHeight += lineHeight;
lineHeight = 0;
- last_rBearing = _rb;
+ last_rBearing = b->f_rbearing();
last_rPadding = b->f_rpadding();
if (_maxWidth < _width) {
_maxWidth = _width;
@@ -2475,11 +2469,13 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
continue;
}
+ auto b__f_rbearing = b->f_rbearing(); // cache
+
_width += b->f_lpadding();
- _width += last_rBearing + (last_rPadding + b->f_width() - _rb);
+ _width += last_rBearing + (last_rPadding + b->f_width() - b__f_rbearing);
lineHeight = qMax(lineHeight, blockHeight);
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
continue;
}
@@ -2495,7 +2491,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
}
}
if (_width > 0) {
- if (!lineHeight) lineHeight = _blockHeight(_blocks.back(), _font);
+ if (!lineHeight) lineHeight = countBlockHeight(_blocks.back(), _font);
_minHeight += lineHeight;
if (_maxWidth < _width) {
_maxWidth = _width;
@@ -2504,7 +2500,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
}
void Text::setMarkedText(style::font font, const QString &text, const EntitiesInText &entities, const TextParseOptions &options) {
- if (!_textStyle) _initDefault();
+ if (!_textStyle) initDefault();
_font = font;
clear();
{
@@ -2666,11 +2662,10 @@ int32 Text::countWidth(int32 w) const {
for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
ITextBlock *b = *i;
TextBlockType _btype = b->type();
- int32 blockHeight = _blockHeight(b, _font);
- QFixed _rb = _blockRBearing(b);
+ int32 blockHeight = countBlockHeight(b, _font);
if (_btype == TextBlockTNewline) {
- last_rBearing = _rb;
+ last_rBearing = b->f_rbearing();
last_rPadding = b->f_rpadding();
if (widthLeft < minWidthLeft) {
minWidthLeft = widthLeft;
@@ -2680,10 +2675,11 @@ int32 Text::countWidth(int32 w) const {
longWordLine = true;
continue;
}
- QFixed lpadding = b->f_lpadding();
- QFixed newWidthLeft = widthLeft - lpadding - last_rBearing - (last_rPadding + b->f_width() - _rb);
+ auto b__f_lpadding = b->f_lpadding();
+ auto b__f_rbearing = b->f_rbearing(); // cache
+ QFixed newWidthLeft = widthLeft - b__f_lpadding - last_rBearing - (last_rPadding + b->f_width() - b__f_rbearing);
if (newWidthLeft >= 0) {
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
widthLeft = newWidthLeft;
@@ -2694,7 +2690,7 @@ int32 Text::countWidth(int32 w) const {
if (_btype == TextBlockTText) {
TextBlock *t = static_cast(b);
if (t->_words.isEmpty()) { // no words in this block, spaces only => layout this block in the same line
- last_rPadding += lpadding;
+ last_rPadding += b__f_lpadding;
longWordLine = false;
continue;
@@ -2702,14 +2698,14 @@ int32 Text::countWidth(int32 w) const {
QFixed f_wLeft = widthLeft;
for (TextBlock::TextWords::const_iterator j = t->_words.cbegin(), e = t->_words.cend(), f = j; j != e; ++j) {
- bool wordEndsHere = (j->width >= 0);
- QFixed j_width = wordEndsHere ? j->width : -j->width;
+ bool wordEndsHere = (j->f_width() >= 0);
+ QFixed j_width = wordEndsHere ? j->f_width() : -j->f_width();
- QFixed newWidthLeft = widthLeft - lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
- lpadding = 0;
+ QFixed newWidthLeft = widthLeft - b__f_lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
+ b__f_lpadding = 0;
if (newWidthLeft >= 0) {
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
widthLeft = newWidthLeft;
if (wordEndsHere) {
@@ -2725,11 +2721,11 @@ int32 Text::countWidth(int32 w) const {
if (f != j) {
j = f;
widthLeft = f_wLeft;
- j_width = (j->width >= 0) ? j->width : -j->width;
+ j_width = (j->f_width() >= 0) ? j->f_width() : -j->f_width();
}
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
if (widthLeft < minWidthLeft) {
minWidthLeft = widthLeft;
}
@@ -2742,7 +2738,7 @@ int32 Text::countWidth(int32 w) const {
continue;
}
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
if (widthLeft < minWidthLeft) {
minWidthLeft = widthLeft;
@@ -2772,24 +2768,24 @@ int32 Text::countHeight(int32 w) const {
for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
ITextBlock *b = *i;
TextBlockType _btype = b->type();
- int32 blockHeight = _blockHeight(b, _font);
- QFixed _rb = _blockRBearing(b);
+ int32 blockHeight = countBlockHeight(b, _font);
if (_btype == TextBlockTNewline) {
if (!lineHeight) lineHeight = blockHeight;
result += lineHeight;
lineHeight = 0;
- last_rBearing = _rb;
+ last_rBearing = b->f_rbearing();
last_rPadding = b->f_rpadding();
widthLeft = width - (b->f_width() - last_rBearing);
longWordLine = true;
continue;
}
- QFixed lpadding = b->f_lpadding();
- QFixed newWidthLeft = widthLeft - lpadding - last_rBearing - (last_rPadding + b->f_width() - _rb);
+ auto b__f_lpadding = b->f_lpadding();
+ auto b__f_rbearing = b->f_rbearing();
+ QFixed newWidthLeft = widthLeft - b__f_lpadding - last_rBearing - (last_rPadding + b->f_width() - b__f_rbearing);
if (newWidthLeft >= 0) {
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
widthLeft = newWidthLeft;
@@ -2802,7 +2798,7 @@ int32 Text::countHeight(int32 w) const {
if (_btype == TextBlockTText) {
TextBlock *t = static_cast(b);
if (t->_words.isEmpty()) { // no words in this block, spaces only => layout this block in the same line
- last_rPadding += lpadding;
+ last_rPadding += b__f_lpadding;
lineHeight = qMax(lineHeight, blockHeight);
@@ -2813,14 +2809,14 @@ int32 Text::countHeight(int32 w) const {
QFixed f_wLeft = widthLeft;
int32 f_lineHeight = lineHeight;
for (TextBlock::TextWords::const_iterator j = t->_words.cbegin(), e = t->_words.cend(), f = j; j != e; ++j) {
- bool wordEndsHere = (j->width >= 0);
- QFixed j_width = wordEndsHere ? j->width : -j->width;
+ bool wordEndsHere = (j->f_width() >= 0);
+ QFixed j_width = wordEndsHere ? j->f_width() : -j->f_width();
- QFixed newWidthLeft = widthLeft - lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
- lpadding = 0;
+ QFixed newWidthLeft = widthLeft - b__f_lpadding - last_rBearing - (last_rPadding + j_width - j->f_rbearing());
+ b__f_lpadding = 0;
if (newWidthLeft >= 0) {
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
widthLeft = newWidthLeft;
lineHeight = qMax(lineHeight, blockHeight);
@@ -2840,13 +2836,13 @@ int32 Text::countHeight(int32 w) const {
j = f;
widthLeft = f_wLeft;
lineHeight = f_lineHeight;
- j_width = (j->width >= 0) ? j->width : -j->width;
+ j_width = (j->f_width() >= 0) ? j->f_width() : -j->f_width();
}
result += lineHeight;
lineHeight = qMax(0, blockHeight);
last_rBearing = j->f_rbearing();
- last_rPadding = j->rpadding;
+ last_rPadding = j->f_rpadding();
widthLeft = width - (j_width - last_rBearing);
longWordLine = true;
@@ -2859,7 +2855,7 @@ int32 Text::countHeight(int32 w) const {
result += lineHeight;
lineHeight = qMax(0, blockHeight);
- last_rBearing = _rb;
+ last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
widthLeft = width - (b->f_width() - last_rBearing);
diff --git a/Telegram/SourceFiles/ui/text/text_block.cpp b/Telegram/SourceFiles/ui/text/text_block.cpp
index 0505636b5..705d935f5 100644
--- a/Telegram/SourceFiles/ui/text/text_block.cpp
+++ b/Telegram/SourceFiles/ui/text/text_block.cpp
@@ -32,10 +32,11 @@ struct ScriptLine {
QFixed textWidth;
};
+// All members finished with "_" are internal.
struct LineBreakHelper
{
LineBreakHelper()
- : glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0)
+ : glyphCount(0), maxGlyphs(INT_MAX), currentPosition(0), fontEngine(0), logClusters(0)
{
}
@@ -48,7 +49,9 @@ struct LineBreakHelper
int glyphCount;
int maxGlyphs;
int currentPosition;
- glyph_t previousGlyph;
+
+ glyph_t previousGlyph_ = 0;
+ QFontEngine *previousFontEngine_ = nullptr;
QFixed rightBearing;
@@ -65,35 +68,71 @@ struct LineBreakHelper
inline void saveCurrentGlyph()
{
- previousGlyph = 0;
if (currentPosition > 0 &&
logClusters[currentPosition - 1] < glyphs.numGlyphs) {
- previousGlyph = currentGlyph(); // needed to calculate right bearing later
+ previousGlyph_ = currentGlyph(); // needed to calculate right bearing later
+ previousFontEngine_ = fontEngine;
+ } else {
+ previousGlyph_ = 0;
+ previousFontEngine_ = nullptr;
}
}
- inline void adjustRightBearing(glyph_t glyph)
+ inline void calculateRightBearing(QFontEngine *engine, glyph_t glyph)
{
qreal rb;
- fontEngine->getGlyphBearings(glyph, 0, &rb);
- rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
+ engine->getGlyphBearings(glyph, 0, &rb);
+
+ // We only care about negative right bearings, so we limit the range
+ // of the bearing here so that we can assume it's negative in the rest
+ // of the code, as well ase use QFixed(1) as a sentinel to represent
+ // the state where we have yet to compute the right bearing.
+ rightBearing = qMin(QFixed::fromReal(rb), QFixed(0));
}
- inline void adjustRightBearing()
+ inline void calculateRightBearing()
{
- if (currentPosition <= 0)
- return;
- adjustRightBearing(currentGlyph());
+ if (currentPosition > 0 &&
+ logClusters[currentPosition - 1] < glyphs.numGlyphs) {
+ calculateRightBearing(fontEngine, currentGlyph());
+ } else {
+ rightBearing = 0;
+ }
}
- inline void adjustPreviousRightBearing()
+ inline void calculateRightBearingForPreviousGlyph()
{
- if (previousGlyph > 0)
- adjustRightBearing(previousGlyph);
+ if (previousGlyph_ > 0) {
+ calculateRightBearing(previousFontEngine_, previousGlyph_);
+ } else {
+ rightBearing = 0;
+ }
+ }
+
+ // We always calculate the right bearing right before it is needed.
+ // So we don't need caching / optimizations referred to delayed right bearing calculations.
+
+ //static const QFixed RightBearingNotCalculated;
+
+ //inline void resetRightBearing()
+ //{
+ // rightBearing = RightBearingNotCalculated;
+ //}
+
+ // We express the negative right bearing as an absolute number
+ // so that it can be applied to the width using addition.
+ inline QFixed negativeRightBearing() const
+ {
+ //if (rightBearing == RightBearingNotCalculated)
+ // return QFixed(0);
+
+ return qAbs(rightBearing);
}
};
+//const QFixed LineBreakHelper::RightBearingNotCalculated = QFixed(1);
+
static inline void addNextCluster(int &pos, int end, ScriptLine &line, int &glyphCount,
const QScriptItem ¤t, const unsigned short *logClusters,
const QGlyphLayout &glyphs)
@@ -127,8 +166,6 @@ public:
void parseWords(QFixed minResizeWidth, int32 blockFrom) {
LineBreakHelper lbh;
- lbh.maxGlyphs = INT_MAX;
-
int item = -1;
int newItem = eng->findItem(0);
@@ -137,10 +174,8 @@ public:
const QCharAttributes *attributes = eng->attributes();
if (!attributes)
return;
- lbh.currentPosition = 0;
int end = 0;
lbh.logClusters = eng->layoutData->logClustersPtr;
- lbh.previousGlyph = 0;
block->_lpadding = 0;
block->_words.clear();
@@ -180,7 +215,7 @@ public:
if (block->_words.isEmpty()) {
block->_lpadding = lbh.spaceData.textWidth;
} else {
- block->_words.back().rpadding += lbh.spaceData.textWidth;
+ block->_words.back().add_rpadding(lbh.spaceData.textWidth);
block->_width += lbh.spaceData.textWidth;
}
lbh.spaceData.length = 0;
@@ -199,8 +234,8 @@ public:
if (lbh.currentPosition >= eng->layoutData->string.length()
|| attributes[lbh.currentPosition].whiteSpace
|| isLineBreak(attributes, lbh.currentPosition)) {
- lbh.adjustRightBearing();
- block->_words.push_back(TextWord(wordStart + blockFrom, lbh.tmpData.textWidth, qMin(QFixed(), lbh.rightBearing)));
+ lbh.calculateRightBearing();
+ block->_words.push_back(TextWord(wordStart + blockFrom, lbh.tmpData.textWidth, -lbh.negativeRightBearing()));
block->_width += lbh.tmpData.textWidth;
lbh.tmpData.textWidth = 0;
lbh.tmpData.length = 0;
@@ -209,8 +244,8 @@ public:
} else if (attributes[lbh.currentPosition].graphemeBoundary) {
if (!addingEachGrapheme && lbh.tmpData.textWidth > minResizeWidth) {
if (lastGraphemeBoundaryPosition >= 0) {
- lbh.adjustPreviousRightBearing();
- block->_words.push_back(TextWord(wordStart + blockFrom, -lastGraphemeBoundaryLine.textWidth, qMin(QFixed(), lbh.rightBearing)));
+ lbh.calculateRightBearingForPreviousGlyph();
+ block->_words.push_back(TextWord(wordStart + blockFrom, -lastGraphemeBoundaryLine.textWidth, -lbh.negativeRightBearing()));
block->_width += lastGraphemeBoundaryLine.textWidth;
lbh.tmpData.textWidth -= lastGraphemeBoundaryLine.textWidth;
lbh.tmpData.length -= lastGraphemeBoundaryLine.length;
@@ -219,8 +254,8 @@ public:
addingEachGrapheme = true;
}
if (addingEachGrapheme) {
- lbh.adjustRightBearing();
- block->_words.push_back(TextWord(wordStart + blockFrom, -lbh.tmpData.textWidth, qMin(QFixed(), lbh.rightBearing)));
+ lbh.calculateRightBearing();
+ block->_words.push_back(TextWord(wordStart + blockFrom, -lbh.tmpData.textWidth, -lbh.negativeRightBearing()));
block->_width += lbh.tmpData.textWidth;
lbh.tmpData.textWidth = 0;
lbh.tmpData.length = 0;
@@ -239,7 +274,7 @@ public:
if (block->_words.isEmpty()) {
block->_rpadding = 0;
} else {
- block->_rpadding = block->_words.back().rpadding;
+ block->_rpadding = block->_words.back().f_rpadding();
block->_width -= block->_rpadding;
block->_words.squeeze();
}
@@ -261,6 +296,10 @@ private:
};
+QFixed ITextBlock::f_rbearing() const {
+ return (type() == TextBlockTText) ? static_cast(this)->real_f_rbearing() : 0;
+}
+
TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, color, lnkIndex) {
_flags |= ((TextBlockTText & 0x0F) << 8);
if (length) {
diff --git a/Telegram/SourceFiles/ui/text/text_block.h b/Telegram/SourceFiles/ui/text/text_block.h
index 1b3cd9b07..e64547042 100644
--- a/Telegram/SourceFiles/ui/text/text_block.h
+++ b/Telegram/SourceFiles/ui/text/text_block.h
@@ -75,6 +75,9 @@ public:
return _rpadding;
}
+ // Should be virtual, but optimized throught type() call.
+ QFixed f_rbearing() const;
+
uint16 lnkIndex() const {
return (_flags >> 12) & 0xFFFF;
}
@@ -132,27 +135,41 @@ private:
friend class TextPainter;
};
-struct TextWord {
- TextWord() {
+class TextWord {
+public:
+ TextWord() = default;
+ TextWord(uint16 from, QFixed width, QFixed rbearing, QFixed rpadding = 0)
+ : _from(from)
+ , _rbearing(rbearing.value() > 0x7FFF ? 0x7FFF : (rbearing.value() < -0x7FFF ? -0x7FFF : rbearing.value()))
+ , _width(width)
+ , _rpadding(rpadding) {
}
- TextWord(uint16 from, QFixed width, QFixed rbearing, QFixed rpadding = 0) : from(from),
- _rbearing(rbearing.value() > 0x7FFF ? 0x7FFF : (rbearing.value() < -0x7FFF ? -0x7FFF : rbearing.value())), width(width), rpadding(rpadding) {
+ uint16 from() const {
+ return _from;
}
QFixed f_rbearing() const {
return QFixed::fromFixed(_rbearing);
}
- uint16 from;
- int16 _rbearing;
- QFixed width, rpadding;
+ QFixed f_width() const {
+ return _width;
+ }
+ QFixed f_rpadding() const {
+ return _rpadding;
+ }
+ void add_rpadding(QFixed padding) {
+ _rpadding += padding;
+ }
+
+private:
+ uint16 _from = 0;
+ QFixed _width, _rpadding;
+ int16 _rbearing = 0;
+
};
class TextBlock : public ITextBlock {
public:
- QFixed f_rbearing() const {
- return _words.isEmpty() ? 0 : _words.back().f_rbearing();
- }
-
ITextBlock *clone() const {
return new TextBlock(*this);
}
@@ -161,6 +178,11 @@ private:
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, const style::color &color, uint16 lnkIndex);
+ friend class ITextBlock;
+ QFixed real_f_rbearing() const {
+ return _words.isEmpty() ? 0 : _words.back().f_rbearing();
+ }
+
typedef QVector TextWords;
TextWords _words;
diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj
index f49da0710..db2eecaa3 100644
--- a/Telegram/Telegram.vcxproj
+++ b/Telegram/Telegram.vcxproj
@@ -75,7 +75,7 @@
$(IntDir)$(TargetName).pch
MultiThreadedDebug
Disabled
- /Zm152 %(AdditionalOptions)
+ /Zm152 /Zo
Level3
true
@@ -107,7 +107,7 @@
AnySuitable
true
Speed
- /Zm110 %(AdditionalOptions)
+ /Zm152 /Zo
Level3
true
@@ -140,7 +140,7 @@
AnySuitable
true
Speed
- /Zm110 %(AdditionalOptions)
+ /Zm152 /Zo
Level3
true
@@ -2384,7 +2384,11 @@
-
+
+ .\GeneratedFiles\lang_auto.h
+ .\GeneratedFiles\lang_auto.cpp
+ "$(SolutionDir)$(Platform)\$(Configuration)Lang\MetaLang.exe" -lang_in ".\Resources\langs\lang.strings" -lang_out ".\GeneratedFiles\lang_auto"
+
diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters
index 24a3ca5e0..2fba282fa 100644
--- a/Telegram/Telegram.vcxproj.filters
+++ b/Telegram/Telegram.vcxproj.filters
@@ -1528,6 +1528,9 @@
SourceFiles\history
+
+ Resources\langs
+
@@ -1569,9 +1572,6 @@
SourceFiles
-
- Resources\langs
-
Resources\langs
diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj
index df93781f5..41b3df598 100644
--- a/Telegram/Telegram.xcodeproj/project.pbxproj
+++ b/Telegram/Telegram.xcodeproj/project.pbxproj
@@ -2023,7 +2023,7 @@
SDKROOT = macosx;
SYMROOT = ./../Mac;
TDESKTOP_MAJOR_VERSION = 0.9;
- TDESKTOP_VERSION = 0.9.46;
+ TDESKTOP_VERSION = 0.9.47;
};
name = Release;
};
@@ -2164,7 +2164,7 @@
SDKROOT = macosx;
SYMROOT = ./../Mac;
TDESKTOP_MAJOR_VERSION = 0.9;
- TDESKTOP_VERSION = 0.9.46;
+ TDESKTOP_VERSION = 0.9.47;
};
name = Debug;
};
diff --git a/Telegram/build/version b/Telegram/build/version
index ccbaa4e17..b2d958b19 100644
--- a/Telegram/build/version
+++ b/Telegram/build/version
@@ -1,6 +1,6 @@
-AppVersion 9046
+AppVersion 9047
AppVersionStrMajor 0.9
-AppVersionStrSmall 0.9.46
-AppVersionStr 0.9.46
+AppVersionStrSmall 0.9.47
+AppVersionStr 0.9.47
AlphaChannel 1
BetaVersion 0