circled profile images

This commit is contained in:
John Preston 2016-03-18 13:18:30 +03:00
parent 47c7f76f2c
commit baf1e31b76
20 changed files with 224 additions and 120 deletions

View File

@ -362,7 +362,7 @@ void ContactsInner::loadProfilePhotos(int32 yFrom) {
preloadFrom != _contacts->list.end && (_newItemHeight + preloadFrom->pos * _rowHeight) < yTo; preloadFrom != _contacts->list.end && (_newItemHeight + preloadFrom->pos * _rowHeight) < yTo;
preloadFrom = preloadFrom->next preloadFrom = preloadFrom->next
) { ) {
preloadFrom->history->peer->photo->load(); preloadFrom->history->peer->loadUserpic();
} }
} }
} else if (!_filtered.isEmpty()) { } else if (!_filtered.isEmpty()) {
@ -373,7 +373,7 @@ void ContactsInner::loadProfilePhotos(int32 yFrom) {
if (to > _filtered.size()) to = _filtered.size(); if (to > _filtered.size()) to = _filtered.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_filtered[from]->history->peer->photo->load(); _filtered[from]->history->peer->loadUserpic();
} }
} }
} }
@ -445,7 +445,7 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b
} }
p.fillRect(0, 0, width(), _rowHeight, inverse ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white)); p.fillRect(0, 0, width(), _rowHeight, inverse ? st::contactsBgActive : (sel ? st::contactsBgOver : st::white));
p.setPen(inverse ? st::white : st::black); p.setPen(inverse ? st::white : st::black);
p.drawPixmapLeft(st::contactsPadding.left(), st::contactsPadding.top(), width(), peer->photo->pix(st::contactsPhotoSize)); peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(); int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
int32 iconw = (_chat || _creating != CreatingGroupNone) ? (st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth()) : 0; int32 iconw = (_chat || _creating != CreatingGroupNone) ? (st::contactsCheckPosition.x() * 2 + st::contactsCheckIcon.pxWidth()) : 0;
@ -1909,7 +1909,7 @@ void MembersInner::paintDialog(Painter &p, PeerData *peer, MemberData *data, boo
UserData *user = peer->asUser(); UserData *user = peer->asUser();
p.fillRect(0, 0, width(), _rowHeight, (sel ? st::contactsBgOver : st::white)->b); p.fillRect(0, 0, width(), _rowHeight, (sel ? st::contactsBgOver : st::white)->b);
p.drawPixmapLeft(st::contactsPadding.left(), st::contactsPadding.top(), width(), peer->photo->pix(st::contactsPhotoSize)); peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
p.setPen(st::black); p.setPen(st::black);
@ -1994,7 +1994,7 @@ void MembersInner::loadProfilePhotos(int32 yFrom) {
if (to > _rows.size()) to = _rows.size(); if (to > _rows.size()) to = _rows.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_rows[from]->photo->load(); _rows[from]->loadUserpic();
} }
} }
} }

View File

@ -82,7 +82,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
maxH = limitH; maxH = limitH;
} }
} }
_thumb = imagePix(_file->thumb.toImage(), maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), true, true, false, maxW, maxH); _thumb = imagePix(_file->thumb.toImage(), maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixBlurred, maxW, maxH);
} else { } else {
for (PreparedPhotoThumbs::const_iterator i = _file->photoThumbs.cbegin(), e = _file->photoThumbs.cend(); i != e; ++i) { for (PreparedPhotoThumbs::const_iterator i = _file->photoThumbs.cbegin(), e = _file->photoThumbs.cend(); i != e; ++i) {
if (i->width() >= maxW && i->height() >= maxH) { if (i->width() >= maxW && i->height() >= maxH) {
@ -124,7 +124,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
} else { } else {
_thumbw = st::msgFileThumbSize; _thumbw = st::msgFileThumbSize;
} }
_thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, true, false, true, st::msgFileThumbSize, st::msgFileThumbSize); _thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize);
} }
_name.setText(st::semiboldFont, _file->filename, _textNameOptions); _name.setText(st::semiboldFont, _file->filename, _textNameOptions);
@ -274,7 +274,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
p.drawSpriteCenter(inner, _isImage ? st::msgFileOutImage : st::msgFileOutFile); p.drawSpriteCenter(inner, _isImage ? st::msgFileOutImage : st::msgFileOutFile);
} else { } else {
p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixRounded(st::msgFileSize)); p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixCircled(st::msgFileSize));
} }
p.setFont(st::semiboldFont); p.setFont(st::semiboldFont);
p.setPen(st::black); p.setPen(st::black);
@ -428,7 +428,7 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
} else { } else {
_thumbw = st::msgFileThumbSize; _thumbw = st::msgFileThumbSize;
} }
_thumb = imagePix(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, true, false, true, st::msgFileThumbSize, st::msgFileThumbSize); _thumb = imagePix(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize);
} }
if (doc) { if (doc) {
@ -459,11 +459,11 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
maxH = limitH; maxH = limitH;
} }
} }
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), true, true, false, maxW, maxH); _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixBlurred, maxW, maxH);
} else { } else {
maxW = dimensions.width(); maxW = dimensions.width();
maxH = dimensions.height(); maxH = dimensions.height();
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), true, false, false, maxW, maxH); _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixRounded, maxW, maxH);
} }
int32 tw = _thumb.width(), th = _thumb.height(); int32 tw = _thumb.width(), th = _thumb.height();
if (!tw || !th) { if (!tw || !th) {

View File

@ -247,11 +247,8 @@ void DialogsInner::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool a
History *history = App::history(peer->id); History *history = App::history(peer->id);
if (peer->migrateTo()) { PeerData *userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, peer->migrateTo()->photo->pix(st::dlgPhotoSize)); userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
} else {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, peer->photo->pix(st::dlgPhotoSize));
}
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor; int32 namewidth = w - nameleft - st::dlgPaddingHor;
@ -299,7 +296,7 @@ void DialogsInner::searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) c
p.fillRect(fullRect, st::dlgBG->b); p.fillRect(fullRect, st::dlgBG->b);
if (onlyBackground) return; if (onlyBackground) return;
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, _searchInPeer->photo->pix(st::dlgPhotoSize)); _searchInPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, fullWidth());
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width; int32 namewidth = w - nameleft - st::dlgPaddingHor * 2 - st::btnCancelSearch.width;
@ -1373,7 +1370,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
if (yFrom < otherStart) { if (yFrom < otherStart) {
dialogs.list.adjustCurrent(yFrom, st::dlgHeight); dialogs.list.adjustCurrent(yFrom, st::dlgHeight);
for (DialogRow *row = dialogs.list.current; row != dialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) { for (DialogRow *row = dialogs.list.current; row != dialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
row->history->peer->photo->load(); row->history->peer->loadUserpic();
} }
yFrom = 0; yFrom = 0;
} else { } else {
@ -1383,7 +1380,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
if (yTo > 0) { if (yTo > 0) {
contactsNoDialogs.list.adjustCurrent(yFrom, st::dlgHeight); contactsNoDialogs.list.adjustCurrent(yFrom, st::dlgHeight);
for (DialogRow *row = contactsNoDialogs.list.current; row != contactsNoDialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) { for (DialogRow *row = contactsNoDialogs.list.current; row != contactsNoDialogs.list.end && (row->pos * st::dlgHeight) < yTo; row = row->next) {
row->history->peer->photo->load(); row->history->peer->loadUserpic();
} }
} }
} else if (_state == FilteredState || _state == SearchedState) { } else if (_state == FilteredState || _state == SearchedState) {
@ -1394,7 +1391,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
if (to > _filterResults.size()) to = _filterResults.size(); if (to > _filterResults.size()) to = _filterResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_filterResults[from]->history->peer->photo->load(); _filterResults[from]->history->peer->loadUserpic();
} }
} }
@ -1405,7 +1402,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
if (to > _peopleResults.size()) to = _peopleResults.size(); if (to > _peopleResults.size()) to = _peopleResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_peopleResults[from]->photo->load(); _peopleResults[from]->loadUserpic();
} }
} }
from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size(); from = (yFrom > filteredOffset() + ((_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peopleResults.isEmpty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dlgHeight)) : 0) - _filterResults.size() - _peopleResults.size();
@ -1415,7 +1412,7 @@ void DialogsInner::loadPeerPhotos(int32 yFrom) {
if (to > _searchResults.size()) to = _searchResults.size(); if (to > _searchResults.size()) to = _searchResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_searchResults[from]->_item->history()->peer->photo->load(); _searchResults[from]->_item->history()->peer->loadUserpic();
} }
} }
} }

View File

@ -3944,8 +3944,8 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
second = st::mentionFont->elided(second, unamewidth - firstwidth); second = st::mentionFont->elided(second, unamewidth - firstwidth);
} }
} }
user->photo->load(); user->loadUserpic();
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize)); user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width());
user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth); user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
p.setFont(st::mentionFont->f); p.setFont(st::mentionFont->f);
@ -3986,10 +3986,8 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
if (hasUsername || botStatus == 0 || botStatus == 2) { if (hasUsername || botStatus == 0 || botStatus == 2) {
toHighlight += '@' + user->username; toHighlight += '@' + user->username;
} }
if (true || _parent->chat() || botStatus == 0 || botStatus == 2) { user->loadUserpic();
user->photo->load(); user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width());
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize));
}
int32 addleft = 0, widthleft = mentionwidth; int32 addleft = 0, widthleft = mentionwidth;
QString first = (_parent->filter().size() < 2) ? QString() : ('/' + toHighlight.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('/' + toHighlight) : toHighlight.mid(_parent->filter().size() - 1); QString first = (_parent->filter().size() < 2) ? QString() : ('/' + toHighlight.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('/' + toHighlight) : toHighlight.mid(_parent->filter().size() - 1);

View File

@ -375,6 +375,8 @@ struct GlobalDataStruct {
int32 EditTimeLimit = 172800; int32 EditTimeLimit = 172800;
Global::HiddenPinnedMessagesMap HiddenPinnedMessages; Global::HiddenPinnedMessagesMap HiddenPinnedMessages;
Global::CircleMasksMap CircleMasks;
}; };
GlobalDataStruct *GlobalData = 0; GlobalDataStruct *GlobalData = 0;
@ -421,4 +423,6 @@ namespace Global {
DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages); DefineVar(Global, HiddenPinnedMessagesMap, HiddenPinnedMessages);
DefineRefVar(Global, CircleMasksMap, CircleMasks);
}; };

View File

@ -170,6 +170,9 @@ namespace Global {
typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap; typedef QMap<PeerId, MsgId> HiddenPinnedMessagesMap;
DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages); DeclareVar(HiddenPinnedMessagesMap, HiddenPinnedMessages);
typedef QMap<uint64, QPixmap> CircleMasksMap;
DeclareRefVar(CircleMasksMap, CircleMasks);
}; };
namespace Adaptive { namespace Adaptive {

View File

@ -47,6 +47,7 @@ namespace {
static const uint64 ColoredCacheSkip = 0x2000000000000000LLU; static const uint64 ColoredCacheSkip = 0x2000000000000000LLU;
static const uint64 BlurredColoredCacheSkip = 0x3000000000000000LLU; static const uint64 BlurredColoredCacheSkip = 0x3000000000000000LLU;
static const uint64 RoundedCacheSkip = 0x4000000000000000LLU; static const uint64 RoundedCacheSkip = 0x4000000000000000LLU;
static const uint64 CircledCacheSkip = 0x5000000000000000LLU;
} }
StorageImageLocation StorageImageLocation::Null; StorageImageLocation StorageImageLocation::Null;
@ -106,7 +107,7 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
uint64 k = (uint64(w) << 32) | uint64(h); uint64 k = (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k); Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, true)); QPixmap p(pixNoCache(w, h, ImagePixSmooth));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -128,7 +129,29 @@ const QPixmap &Image::pixRounded(int32 w, int32 h) const {
uint64 k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h); uint64 k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k); Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, true, false, true)); QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixRounded));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAcquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
}
const QPixmap &Image::pixCircled(int32 w, int32 h) const {
checkload();
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = CircledCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixCircled));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -150,7 +173,7 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
uint64 k = BlurredCacheSkip | (uint64(w) << 32) | uint64(h); uint64 k = BlurredCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k); Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, true, true)); QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixBlurred));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -219,7 +242,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) co
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
QPixmap p(pixNoCache(w, h, true, false, true, outerw, outerh)); QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixRounded, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -229,7 +252,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) co
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const { const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -244,7 +267,7 @@ const QPixmap &Image::pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 out
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
QPixmap p(pixNoCache(w, h, true, true, true, outerw, outerh)); QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixBlurred | ImagePixRounded, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -375,6 +398,42 @@ yi += stride;
return img; return img;
} }
const QPixmap &circleMask(int width, int height) {
t_assert(Global::started());
uint64 key = uint64(uint32(width)) << 32 | uint64(uint32(height));
Global::CircleMasksMap &masks(Global::RefCircleMasks());
auto i = masks.constFind(key);
if (i == masks.cend()) {
QImage mask(width, height, QImage::Format_ARGB32_Premultiplied);
mask.fill(st::transparent);
{
Painter p(&mask);
p.setRenderHint(QPainter::HighQualityAntialiasing);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setBrush(st::white);
p.setPen(Qt::NoPen);
p.drawEllipse(0, 0, width, height);
}
i = masks.insert(key, QPixmap::fromImage(mask));
}
return i.value();
}
void imageCircle(QImage &img) {
t_assert(!img.isNull());
img.setDevicePixelRatio(cRetinaFactor());
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
t_assert(!img.isNull());
QPixmap mask = circleMask(img.width(), img.height());
Painter p(&img);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.drawPixmap(0, 0, mask);
}
void imageRound(QImage &img) { void imageRound(QImage &img) {
t_assert(!img.isNull()); t_assert(!img.isNull());
@ -435,18 +494,18 @@ QImage imageColored(const style::color &add, QImage img) {
return img; return img;
} }
QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh) { QPixmap imagePix(QImage img, int32 w, int32 h, ImagePixOptions options, int32 outerw, int32 outerh) {
t_assert(!img.isNull()); t_assert(!img.isNull());
if (blurred) { if (options.testFlag(ImagePixBlurred)) {
img = imageBlur(img); img = imageBlur(img);
t_assert(!img.isNull()); t_assert(!img.isNull());
} }
if (w <= 0 || (w == img.width() && (h <= 0 || h == img.height()))) { if (w <= 0 || (w == img.width() && (h <= 0 || h == img.height()))) {
} else if (h <= 0) { } else if (h <= 0) {
img = img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation); img = img.scaledToWidth(w, options.testFlag(ImagePixSmooth) ? Qt::SmoothTransformation : Qt::FastTransformation);
t_assert(!img.isNull()); t_assert(!img.isNull());
} else { } else {
img = img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation); img = img.scaled(w, h, Qt::IgnoreAspectRatio, options.testFlag(ImagePixSmooth) ? Qt::SmoothTransformation : Qt::FastTransformation);
t_assert(!img.isNull()); t_assert(!img.isNull());
} }
if (outerw > 0 && outerh > 0) { if (outerw > 0 && outerh > 0) {
@ -467,7 +526,10 @@ QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool r
t_assert(!img.isNull()); t_assert(!img.isNull());
} }
} }
if (rounded) { if (options.testFlag(ImagePixCircled)) {
imageCircle(img);
t_assert(!img.isNull());
} else if (options.testFlag(ImagePixRounded)) {
imageRound(img); imageRound(img);
t_assert(!img.isNull()); t_assert(!img.isNull());
} }
@ -475,7 +537,7 @@ QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool r
return QPixmap::fromImage(img, Qt::ColorOnly); return QPixmap::fromImage(img, Qt::ColorOnly);
} }
QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh) const { QPixmap Image::pixNoCache(int w, int h, ImagePixOptions options, int outerw, int outerh) const {
if (!loading()) const_cast<Image*>(this)->load(); if (!loading()) const_cast<Image*>(this)->load();
restore(); restore();
@ -483,7 +545,7 @@ QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool roun
if (h <= 0 && height() > 0) { if (h <= 0 && height() > 0) {
h = qRound(width() * w / float64(height())); h = qRound(width() * w / float64(height()));
} }
return blank()->pixNoCache(w, h, smooth, blurred, rounded, outerw, outerh); return blank()->pixNoCache(w, h, options, outerw, outerh);
} }
if (isNull() && outerw > 0 && outerh > 0) { if (isNull() && outerw > 0 && outerh > 0) {
@ -506,11 +568,15 @@ QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool roun
p.fillRect(qMax(0, (outerw - w) / 2), qMax(0, (outerh - h) / 2), qMin(result.width(), w), qMin(result.height(), h), st::white); p.fillRect(qMax(0, (outerw - w) / 2), qMax(0, (outerh - h) / 2), qMin(result.width(), w), qMin(result.height(), h), st::white);
} }
if (rounded) imageRound(result); if (options.testFlag(ImagePixCircled)) {
imageCircle(result);
} else if (options.testFlag(ImagePixRounded)) {
imageRound(result);
}
return QPixmap::fromImage(result, Qt::ColorOnly); return QPixmap::fromImage(result, Qt::ColorOnly);
} }
return imagePix(_data.toImage(), w, h, smooth, blurred, rounded, outerw, outerh); return imagePix(_data.toImage(), w, h, options, outerw, outerh);
} }
QPixmap Image::pixColoredNoCache(const style::color &add, int32 w, int32 h, bool smooth) const { QPixmap Image::pixColoredNoCache(const style::color &add, int32 w, int32 h, bool smooth) const {

View File

@ -107,7 +107,15 @@ inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation
return !(a == b); return !(a == b);
} }
QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh); enum ImagePixOption {
ImagePixSmooth = 0x01,
ImagePixBlurred = 0x02,
ImagePixRounded = 0x04,
ImagePixCircled = 0x08,
};
Q_DECLARE_FLAGS(ImagePixOptions, ImagePixOption);
Q_DECLARE_OPERATORS_FOR_FLAGS(ImagePixOptions);
QPixmap imagePix(QImage img, int w, int h, ImagePixOptions options, int outerw, int outerh);
class DelayedStorageImage; class DelayedStorageImage;
@ -145,12 +153,13 @@ public:
const QPixmap &pix(int32 w = 0, int32 h = 0) const; const QPixmap &pix(int32 w = 0, int32 h = 0) const;
const QPixmap &pixRounded(int32 w = 0, int32 h = 0) const; const QPixmap &pixRounded(int32 w = 0, int32 h = 0) const;
const QPixmap &pixCircled(int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const;
const QPixmap &pixColored(const style::color &add, int32 w = 0, int32 h = 0) const; const QPixmap &pixColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurredColored(const style::color &add, int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurredColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) const; const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) const;
const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const; const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const;
QPixmap pixNoCache(int32 w = 0, int32 h = 0, bool smooth = false, bool blurred = false, bool rounded = false, int32 outerw = -1, int32 outerh = -1) const; QPixmap pixNoCache(int w = 0, int h = 0, ImagePixOptions options = 0, int outerw = -1, int outerh = -1) const;
QPixmap pixColoredNoCache(const style::color &add, int32 w = 0, int32 h = 0, bool smooth = false) const; QPixmap pixColoredNoCache(const style::color &add, int32 w = 0, int32 h = 0, bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h = 0) const; QPixmap pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h = 0) const;

View File

@ -98,11 +98,8 @@ void DialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackgrou
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b); p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
if (onlyBackground) return; if (onlyBackground) return;
if (history->peer->migrateTo()) { PeerData *userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->migrateTo()->photo->pix(st::dlgPhotoSize)); userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, w);
} else {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
}
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor; int32 namewidth = w - nameleft - st::dlgPaddingHor;
@ -205,11 +202,8 @@ void FakeDialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBack
if (onlyBackground) return; if (onlyBackground) return;
History *history = _item->history(); History *history = _item->history();
if (history->peer->migrateTo()) { PeerData *userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->migrateTo()->photo->pix(st::dlgPhotoSize)); userpicPeer->paintUserpicLeft(p, st::dlgPhotoSize, st::dlgPaddingHor, st::dlgPaddingVer, w);
} else {
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
}
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding; int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
int32 namewidth = w - nameleft - st::dlgPaddingHor; int32 namewidth = w - nameleft - st::dlgPaddingHor;
@ -1506,7 +1500,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
} else if (peer->isChannel()) { } else if (peer->isChannel()) {
peer->asChannel()->setPhoto(MTP_chatPhoto(*smallLoc, *bigLoc), photo ? photo->id : 0); peer->asChannel()->setPhoto(MTP_chatPhoto(*smallLoc, *bigLoc), photo ? photo->id : 0);
} }
peer->photo->load(); peer->loadUserpic();
} }
} }
} }
@ -5054,7 +5048,7 @@ void HistoryContact::initDimensions(const HistoryItem *parent) {
_contact = _userId ? App::userLoaded(_userId) : 0; _contact = _userId ? App::userLoaded(_userId) : 0;
if (_contact) { if (_contact) {
_contact->photo->load(); _contact->loadUserpic();
} }
if (_contact && _contact->contact > 0) { if (_contact && _contact->contact > 0) {
_linkl.reset(new SendMessageLink(_contact)); _linkl.reset(new SendMessageLink(_contact));
@ -5106,11 +5100,10 @@ void HistoryContact::draw(Painter &p, const HistoryItem *parent, const QRect &r,
linktop = st::msgFileThumbLinkTop; linktop = st::msgFileThumbLinkTop;
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width));
if (_contact && _contact->photo->loaded()) { if (_contact) {
QPixmap thumb = _contact->photo->pixRounded(st::msgFileThumbSize, st::msgFileThumbSize); _contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y());
p.drawPixmap(rthumb.topLeft(), thumb);
} else { } else {
p.drawPixmap(rthumb.topLeft(), userDefPhoto(_contact ? _contact->colorIndex : (qAbs(_userId) % UserColorsCount))->pixRounded(st::msgFileThumbSize, st::msgFileThumbSize)); p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % UserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize));
} }
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
@ -5127,7 +5120,7 @@ void HistoryContact::draw(Painter &p, const HistoryItem *parent, const QRect &r,
statustop = st::msgFileStatusTop; statustop = st::msgFileStatusTop;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width));
p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(parent->id) % UserColorsCount)->pixRounded(st::msgFileSize, st::msgFileSize)); p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(parent->id) % UserColorsCount)->pixCircled(st::msgFileSize, st::msgFileSize));
} }
int32 namewidth = width - nameleft - nameright; int32 namewidth = width - nameleft - nameright;
@ -6705,7 +6698,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
if (displayFromPhoto()) { if (displayFromPhoto()) {
int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
p.drawPixmap(photoleft, _height - st::msgMargin.bottom() - st::msgPhotoSize, author()->photo->pixRounded(st::msgPhotoSize)); author()->paintUserpic(p, st::msgPhotoSize, photoleft, _height - st::msgMargin.bottom() - st::msgPhotoSize);
} }
if (width < 1) return; if (width < 1) return;

View File

@ -6744,7 +6744,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
th = 90; th = 90;
} }
thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(tw), MTP_int(th), MTP_int(0)); thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(tw), MTP_int(th), MTP_int(0));
thumb = result->thumb->pixNoCache(tw, th, true, false, false); thumb = result->thumb->pixNoCache(tw, th, ImagePixSmooth);
} else { } else {
tw = th = 0; tw = th = 0;
thumbSize = MTP_photoSizeEmpty(MTP_string("")); thumbSize = MTP_photoSizeEmpty(MTP_string(""));

View File

@ -866,7 +866,9 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
if (_data->thumb->loaded()) { if (_data->thumb->loaded()) {
if (_thumb.isNull() || loaded != _thumbForLoaded) { if (_thumb.isNull() || loaded != _thumbForLoaded) {
_thumbForLoaded = loaded; _thumbForLoaded = loaded;
_thumb = _data->thumb->pixNoCache(_thumbw, 0, true, !_thumbForLoaded, false, st::overviewFileSize, st::overviewFileSize); ImagePixOptions options = ImagePixSmooth;
if (!_thumbForLoaded) options |= ImagePixBlurred;
_thumb = _data->thumb->pixNoCache(_thumbw, 0, options, st::overviewFileSize, st::overviewFileSize);
} }
p.drawPixmap(rthumb.topLeft(), _thumb); p.drawPixmap(rthumb.topLeft(), _thumb);
} else { } else {
@ -1574,7 +1576,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
if (doc && !doc->thumb->isNull()) { if (doc && !doc->thumb->isNull()) {
if (doc->thumb->loaded()) { if (doc->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height); _thumb = doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} else { } else {
doc->thumb->load(); doc->thumb->load();
@ -1582,7 +1584,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
} else if (_result && !_result->thumb_url.isEmpty()) { } else if (_result && !_result->thumb_url.isEmpty()) {
if (_result->thumb->loaded()) { if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height); _thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} else { } else {
_result->thumb->load(); _result->thumb->load();
@ -1792,13 +1794,13 @@ void LayoutInlinePhoto::prepareThumb(int32 width, int32 height, const QSize &fra
if (photo) { if (photo) {
if (photo->medium->loaded()) { if (photo->medium->loaded()) {
if (!_thumbLoaded || _thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (!_thumbLoaded || _thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = photo->medium->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height); _thumb = photo->medium->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
_thumbLoaded = true; _thumbLoaded = true;
} else { } else {
if (photo->thumb->loaded()) { if (photo->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = photo->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height); _thumb = photo->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} }
photo->medium->load(); photo->medium->load();
@ -1806,7 +1808,7 @@ void LayoutInlinePhoto::prepareThumb(int32 width, int32 height, const QSize &fra
} else { } else {
if (_result->thumb->loaded()) { if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height); _thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} else { } else {
_result->thumb->load(); _result->thumb->load();
@ -1933,7 +1935,7 @@ void LayoutInlineWebVideo::prepareThumb(int32 width, int32 height) const {
w = width; w = width;
} }
} }
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height); _thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} else { } else {
_result->thumb->load(); _result->thumb->load();
@ -2081,7 +2083,7 @@ void LayoutInlineArticle::prepareThumb(int32 width, int32 height) const {
w = width; w = width;
} }
} }
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height); _thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), ImagePixSmooth, width, height);
} }
} else { } else {
_result->thumb->load(); _result->thumb->load();

View File

@ -3616,7 +3616,7 @@ namespace Local {
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access)); user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
} }
user->photo = photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc); user->setUserpic(photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc));
} }
} else if (result->isChat()) { } else if (result->isChat()) {
ChatData *chat = result->asChat(); ChatData *chat = result->asChat();
@ -3644,7 +3644,7 @@ namespace Local {
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
chat->inputChat = MTP_int(peerToChat(chat->id)); chat->inputChat = MTP_int(peerToChat(chat->id));
chat->photo = photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc); chat->setUserpic(photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc));
} }
} else if (result->isChannel()) { } else if (result->isChannel()) {
ChannelData *channel = result->asChannel(); ChannelData *channel = result->asChannel();
@ -3666,7 +3666,7 @@ namespace Local {
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
channel->photo = photoLoc.isNull() ? ImagePtr((channel->isMegagroup() ? chatDefPhoto(channel->colorIndex) : channelDefPhoto(channel->colorIndex))) : ImagePtr(photoLoc); channel->setUserpic(photoLoc.isNull() ? ImagePtr((channel->isMegagroup() ? chatDefPhoto(channel->colorIndex) : channelDefPhoto(channel->colorIndex))) : ImagePtr(photoLoc));
} }
} }
if (!wasLoaded) { if (!wasLoaded) {

View File

@ -4414,7 +4414,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
UserData *user = App::userLoaded(d.vuser_id.v); UserData *user = App::userLoaded(d.vuser_id.v);
if (user) { if (user) {
user->setPhoto(d.vphoto); user->setPhoto(d.vphoto);
user->photo->load(); user->loadUserpic();
if (mtpIsTrue(d.vprevious)) { if (mtpIsTrue(d.vprevious)) {
user->photosCount = -1; user->photosCount = -1;
user->photos.clear(); user->photos.clear();

View File

@ -967,7 +967,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (!_doc->data().isEmpty() && _doc->isAnimation()) { if (!_doc->data().isEmpty() && _doc->isAnimation()) {
if (!_gif) { if (!_gif) {
if (_doc->dimensions.width() && _doc->dimensions.height()) { if (_doc->dimensions.width() && _doc->dimensions.height()) {
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height()); _current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), ImagePixSmooth | ImagePixBlurred, _doc->dimensions.width(), _doc->dimensions.height());
} }
_gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback)); _gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback));
} }
@ -975,7 +975,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (_doc->isAnimation()) { if (_doc->isAnimation()) {
if (!_gif) { if (!_gif) {
if (_doc->dimensions.width() && _doc->dimensions.height()) { if (_doc->dimensions.width() && _doc->dimensions.height()) {
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height()); _current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), ImagePixSmooth | ImagePixBlurred, _doc->dimensions.width(), _doc->dimensions.height());
} }
_gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback)); _gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback));
} }
@ -1116,17 +1116,17 @@ void MediaView::paintEvent(QPaintEvent *e) {
int32 w = _width * cIntRetinaFactor(); int32 w = _width * cIntRetinaFactor();
if (_full <= 0 && _photo->loaded()) { if (_full <= 0 && _photo->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->full->pixNoCache(w, h, true); _current = _photo->full->pixNoCache(w, h, ImagePixSmooth);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_full = 1; _full = 1;
} else if (_full < 0 && _photo->medium->loaded()) { } else if (_full < 0 && _photo->medium->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->medium->pixNoCache(w, h, true, true); _current = _photo->medium->pixNoCache(w, h, ImagePixSmooth | ImagePixBlurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_full = 0; _full = 0;
} else if (_current.isNull() && _photo->thumb->loaded()) { } else if (_current.isNull() && _photo->thumb->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->thumb->pixNoCache(w, h, true, true); _current = _photo->thumb->pixNoCache(w, h, ImagePixSmooth | ImagePixBlurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
} else if (_current.isNull()) { } else if (_current.isNull()) {
_current = _photo->thumb->pix(); _current = _photo->thumb->pix();

View File

@ -282,7 +282,7 @@ void ProfileInner::loadProfilePhotos(int32 yFrom) {
if (yFrom >= _participants.size()) return; if (yFrom >= _participants.size()) return;
if (yTo > _participants.size()) yTo = _participants.size(); if (yTo > _participants.size()) yTo = _participants.size();
for (int32 i = yFrom; i < yTo; ++i) { for (int32 i = yFrom; i < yTo; ++i) {
_participants[i]->photo->load(); _participants[i]->loadUserpic();
} }
} }
@ -832,7 +832,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
// profile // profile
top += st::profilePadding.top(); top += st::profilePadding.top();
if (_photoLink || _peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator)) { if (_photoLink || _peerUser || (_peerChat && !_peerChat->canEdit()) || (_peerChannel && !_amCreator)) {
p.drawPixmap(_left, top, _peer->photo->pix(st::profilePhotoSize)); _peer->paintUserpic(p, st::profilePhotoSize, _left, top);
} else { } else {
if (a_photoOver.current() < 1) { if (a_photoOver.current() < 1) {
p.drawPixmap(QPoint(_left, top), App::sprite(), st::setPhotoImg); p.drawPixmap(QPoint(_left, top), App::sprite(), st::setPhotoImg);
@ -1019,7 +1019,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
} }
UserData *user = *i; UserData *user = *i;
p.drawPixmap(_left, top + st::profileListPadding.height(), user->photo->pix(st::profileListPhotoSize)); user->paintUserpic(p, st::profileListPhotoSize, _left, top + st::profileListPadding.height());
ParticipantData *data = _participantsData[cnt]; ParticipantData *data = _participantsData[cnt];
if (!data) { if (!data) {
data = _participantsData[cnt] = new ParticipantData(); data = _participantsData[cnt] = new ParticipantData();

View File

@ -3247,10 +3247,8 @@ QString toastImage(const StorageKey &key, PeerData *peer) {
v.until = 0; v.until = 0;
} }
v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(MTP::nonce<uint64>(), 16) + qsl(".png"); v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(MTP::nonce<uint64>(), 16) + qsl(".png");
if (peer->photo->loaded() && (key.first || key.second)) { if (key.first || key.second) {
peer->photo->pix().save(v.path, "PNG"); peer->saveUserpic(v.path);
} else if (!key.first && key.second) {
(peer->isUser() ? userDefPhoto : chatDefPhoto)(peer->colorIndex)->pix().save(v.path, "PNG");
} else { } else {
App::wnd()->iconLarge().save(v.path, "PNG"); App::wnd()->iconLarge().save(v.path, "PNG");
} }
@ -3275,11 +3273,7 @@ bool CreateToast(PeerData *peer, int32 msgId, bool showpix, const QString &title
StorageKey key; StorageKey key;
QString imagePath; QString imagePath;
if (showpix) { if (showpix) {
if (peer->photoLoc.isNull() || !peer->photo->loaded()) { key = peer->userpicUniqueKey();
key = StorageKey(0, (peer->isUser() ? 0x1000 : 0x2000) | peer->colorIndex);
} else {
key = storageKey(peer->photoLoc);
}
} else { } else {
key = StorageKey(0, 0); key = StorageKey(0, 0);
} }

View File

@ -208,7 +208,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
, _logOut(this, lang(lng_settings_logout), st::btnLogout) , _logOut(this, lang(lng_settings_logout), st::btnLogout)
, _supportGetRequest(0) { , _supportGetRequest(0) {
if (self()) { if (self()) {
self()->photo->load(); self()->loadUserpic();
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*))); connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
@ -382,7 +382,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
updateChatBackground(); updateChatBackground();
} }
QPainter p(this); Painter p(this);
p.setClipRect(e->rect()); p.setClipRect(e->rect());
@ -399,7 +399,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
} }
if (_photoLink) { if (_photoLink) {
p.drawPixmap(_left, top, self()->photo->pix(st::setPhotoSize)); self()->paintUserpicLeft(p, st::setPhotoSize, _left, top, st::setWidth);
} else { } else {
if (a_photoOver.current() < 1) { if (a_photoOver.current() < 1) {
p.drawPixmap(QPoint(_left, top), App::sprite(), st::setPhotoImg); p.drawPixmap(QPoint(_left, top), App::sprite(), st::setPhotoImg);

View File

@ -103,10 +103,10 @@ PeerData::PeerData(const PeerId &id) : id(id)
, loaded(false) , loaded(false)
, colorIndex(peerColorIndex(id)) , colorIndex(peerColorIndex(id))
, color(peerColor(colorIndex)) , color(peerColor(colorIndex))
, photo((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : (isChannel() ? channelDefPhoto(colorIndex) : userDefPhoto(colorIndex)))
, photoId(UnknownPeerPhotoId) , photoId(UnknownPeerPhotoId)
, nameVersion(0) , nameVersion(0)
, notify(UnknownNotifySettings) { , notify(UnknownNotifySettings)
, _userpic(isUser() ? userDefPhoto(colorIndex) : ((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))) {
if (!peerIsUser(id) && !peerIsChannel(id)) updateName(QString(), QString(), QString()); if (!peerIsUser(id) && !peerIsChannel(id)) updateName(QString(), QString(), QString());
} }
@ -154,6 +154,36 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
} }
} }
void PeerData::setUserpic(ImagePtr userpic) {
_userpic = userpic;
}
ImagePtr PeerData::currentUserpic() const {
if (_userpic->loaded()) {
return _userpic;
} else if (isUser()) {
return userDefPhoto(colorIndex);
} else if (isMegagroup() || isChat()) {
return chatDefPhoto(colorIndex);
}
return channelDefPhoto(colorIndex);
}
void PeerData::paintUserpic(Painter &p, int size, int x, int y) const {
p.drawPixmap(x, y, currentUserpic()->pixCircled(size, size));
}
StorageKey PeerData::userpicUniqueKey() const {
if (photoLoc.isNull() || !_userpic->loaded()) {
return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex);
}
return storageKey(photoLoc);
}
void PeerData::saveUserpic(const QString &path) const {
currentUserpic()->pixCircled().save(path, "PNG");
}
const Text &BotCommand::descriptionText() const { const Text &BotCommand::descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) { if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText(st::mentionFont, _description, _textNameOptions); _descriptionText.setText(st::mentionFont, _description, _textNameOptions);
@ -163,7 +193,7 @@ const Text &BotCommand::descriptionText() const {
void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well
PhotoId newPhotoId = photoId; PhotoId newPhotoId = photoId;
ImagePtr newPhoto = photo; ImagePtr newPhoto = _userpic;
StorageImageLocation newPhotoLoc = photoLoc; StorageImageLocation newPhotoLoc = photoLoc;
switch (p.type()) { switch (p.type()) {
case mtpc_userProfilePhoto: { case mtpc_userProfilePhoto: {
@ -176,7 +206,7 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a
default: { default: {
newPhotoId = 0; newPhotoId = 0;
if (id == ServiceUserId) { if (id == ServiceUserId) {
if (photo->isNull()) { if (_userpic->isNull()) {
newPhoto = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG"); newPhoto = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG");
} }
} else { } else {
@ -185,9 +215,9 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a
newPhotoLoc = StorageImageLocation(); newPhotoLoc = StorageImageLocation();
} break; } break;
} }
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) { if (newPhotoId != photoId || newPhoto.v() != _userpic.v() || newPhotoLoc != photoLoc) {
photoId = newPhotoId; photoId = newPhotoId;
photo = newPhoto; setUserpic(newPhoto);
photoLoc = newPhotoLoc; photoLoc = newPhotoLoc;
if (App::main()) { if (App::main()) {
emit App::main()->peerPhotoChanged(this); emit App::main()->peerPhotoChanged(this);
@ -338,7 +368,7 @@ void UserData::madeAction() {
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well
PhotoId newPhotoId = photoId; PhotoId newPhotoId = photoId;
ImagePtr newPhoto = photo; ImagePtr newPhoto = _userpic;
StorageImageLocation newPhotoLoc = photoLoc; StorageImageLocation newPhotoLoc = photoLoc;
switch (p.type()) { switch (p.type()) {
case mtpc_chatPhoto: { case mtpc_chatPhoto: {
@ -357,9 +387,9 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Loc
// photoFull = ImagePtr(); // photoFull = ImagePtr();
} break; } break;
} }
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) { if (newPhotoId != photoId || newPhoto.v() != _userpic.v() || newPhotoLoc != photoLoc) {
photoId = newPhotoId; photoId = newPhotoId;
photo = newPhoto; setUserpic(newPhoto);
photoLoc = newPhotoLoc; photoLoc = newPhotoLoc;
emit App::main()->peerPhotoChanged(this); emit App::main()->peerPhotoChanged(this);
} }
@ -367,7 +397,7 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Loc
void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Local::readPeer as well
PhotoId newPhotoId = photoId; PhotoId newPhotoId = photoId;
ImagePtr newPhoto = photo; ImagePtr newPhoto = _userpic;
StorageImageLocation newPhotoLoc = photoLoc; StorageImageLocation newPhotoLoc = photoLoc;
switch (p.type()) { switch (p.type()) {
case mtpc_chatPhoto: { case mtpc_chatPhoto: {
@ -386,9 +416,9 @@ void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see
// photoFull = ImagePtr(); // photoFull = ImagePtr();
} break; } break;
} }
if (newPhotoId != photoId || newPhoto.v() != photo.v() || newPhotoLoc != photoLoc) { if (newPhotoId != photoId || newPhoto.v() != _userpic.v() || newPhotoLoc != photoLoc) {
photoId = newPhotoId; photoId = newPhotoId;
photo = newPhoto; setUserpic(newPhoto);
photoLoc = newPhotoLoc; photoLoc = newPhotoLoc;
if (App::main()) emit App::main()->peerPhotoChanged(this); if (App::main()) emit App::main()->peerPhotoChanged(this);
} }

View File

@ -272,7 +272,18 @@ public:
int32 colorIndex; int32 colorIndex;
style::color color; style::color color;
ImagePtr photo;
void setUserpic(ImagePtr userpic);
void paintUserpic(Painter &p, int size, int x, int y) const;
void paintUserpicLeft(Painter &p, int size, int x, int y, int w) const {
paintUserpic(p, size, rtl() ? (w - x - size) : x, y);
}
void loadUserpic(bool loadFirst = false, bool prior = true) {
_userpic->load(loadFirst, prior);
}
StorageKey userpicUniqueKey() const;
void saveUserpic(const QString &path) const;
PhotoId photoId; PhotoId photoId;
StorageImageLocation photoLoc; StorageImageLocation photoLoc;
@ -280,12 +291,14 @@ public:
NotifySettingsPtr notify; NotifySettingsPtr notify;
private: PeerData(const PeerData &other) = delete;
PeerData &operator=(const PeerData &other) = delete;
protected:
PeerData(const PeerId &id); PeerData(const PeerId &id);
friend class UserData; ImagePtr _userpic;
friend class ChatData; ImagePtr currentUserpic() const;
friend class ChannelData;
}; };
static const uint64 UserNoAccess = 0xFFFFFFFFFFFFFFFFULL; static const uint64 UserNoAccess = 0xFFFFFFFFFFFFFFFFULL;

View File

@ -172,13 +172,8 @@ void NotifyWindow::updateNotifyDisplay() {
p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b);
if (!App::passcoded() && cNotifyView() <= dbinvShowName) { if (!App::passcoded() && cNotifyView() <= dbinvShowName) {
if (history->peer->photo->loaded()) { history->peer->loadUserpic(true, true);
p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width());
} else {
MTP::clearLoaderPriorities();
peerPhoto = history->peer->photo;
peerPhoto->load(true, true);
}
} else { } else {
static QPixmap icon = QPixmap::fromImage(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly); static QPixmap icon = QPixmap::fromImage(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly);
p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon); p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon);