diff --git a/krita/gemini/main.cpp b/krita/gemini/main.cpp index c43b314577..cce12096a9 100644 --- a/krita/gemini/main.cpp +++ b/krita/gemini/main.cpp @@ -1,204 +1,205 @@ /* This file is part of the KDE project * Copyright (C) 2012 Arjen Hiemstra * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include "data/splash/splash_screen.xpm" #include "MainWindow.h" -#include "sketch/SketchInputContext.h" +// QT5TODO +// #include "sketch/SketchInputContext.h" #include #include #if defined Q_OS_WIN #include "stdlib.h" #include #elif defined HAVE_X11 #include #endif int main( int argc, char** argv ) { QString calligraVersion(CALLIGRA_VERSION_STRING); QString version; #ifdef CALLIGRA_GIT_SHA1_STRING QString gitVersion(CALLIGRA_GIT_SHA1_STRING); version = QString("%1 (git %2)").arg(calligraVersion).arg(gitVersion).toLatin1(); #else version = calligraVersion; #endif KAboutData aboutData("kritagemini", "krita", ki18n("Krita Gemini"), version.toLatin1(), ki18n("Krita Gemini: Painting at Home and on the Go for Artists"), KAboutData::License_GPL, ki18n("(c) 1999-%1 The Krita team.\n").subs(CALLIGRA_YEAR), KLocalizedString(), "http://www.kritastudio.com", "submit@bugs.kde.org"); KCmdLineArgs::init (argc, argv, &aboutData); KCmdLineOptions options; options.add( "+[files]", ki18n( "Images to open" ) ); options.add( "vkb", ki18n( "Use the virtual keyboard" ) ); options.add( "fullscreen", ki18n( "Use full-screen display" ) ); options.add( "sketch", ki18n( "Start with the Sketch interface" ) ); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); QStringList fileNames; if (args->count() > 0) { for (int i = 0; i < args->count(); ++i) { QString fileName = args->arg(i); if (QFile::exists(fileName)) { fileNames << fileName; } } } KApplication app; app.setApplicationName("kritagemini"); KIconLoader::global()->addAppDir("krita"); KIconLoader::global()->addAppDir("kritasketch"); #ifdef Q_OS_WIN QDir appdir(app.applicationDirPath()); appdir.cdUp(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); // If there's no kdehome, set it and restart the process. if (!env.contains("KDEHOME") ) { _putenv_s("KDEHOME", QDesktopServices::storageLocation(QDesktopServices::DataLocation).toLocal8Bit()); } if (!env.contains("KDESYCOCA")) { _putenv_s("KDESYCOCA", QString(appdir.absolutePath() + "/sycoca").toLocal8Bit()); } if (!env.contains("XDG_DATA_DIRS")) { _putenv_s("XDG_DATA_DIRS", QString(appdir.absolutePath() + "/share").toLocal8Bit()); } if (!env.contains("KDEDIR")) { _putenv_s("KDEDIR", appdir.absolutePath().toLocal8Bit()); } if (!env.contains("KDEDIRS")) { _putenv_s("KDEDIRS", appdir.absolutePath().toLocal8Bit()); } _putenv_s("PATH", QString(appdir.absolutePath() + "/bin" + ";" + appdir.absolutePath() + "/lib" + ";" + appdir.absolutePath() + "/lib" + "/kde4" + ";" + appdir.absolutePath()).toLocal8Bit()); app.addLibraryPath(appdir.absolutePath()); app.addLibraryPath(appdir.absolutePath() + "/bin"); app.addLibraryPath(appdir.absolutePath() + "/lib"); app.addLibraryPath(appdir.absolutePath() + "/lib/kde4"); #endif #if defined Q_OS_WIN KisTabletSupportWin::init(); app.setEventFilter(&KisTabletSupportWin::eventFilter); #elif defined HAVE_X11 KisTabletSupportX11::init(); app.setEventFilter(&KisTabletSupportX11::eventFilter); #endif if (qgetenv("KDE_FULL_SESSION").isEmpty()) { // There are two themes that work for Krita, oxygen and plastique. Try to set plastique first, then oxygen qobject_cast(QApplication::instance())->setStyle("Plastique"); qobject_cast(QApplication::instance())->setStyle("Oxygen"); } // Prepare to show window fullscreen if required bool showFullscreen = false; #ifdef HAVE_STEAMWORKS if (steamClient->isInBigPictureMode()) { // Show main window full screen showFullscreen = true; } #endif if (args->isSet("sketch")) { showFullscreen = true; } if (args->isSet("fullscreen")) { showFullscreen = true; } // then create the pixmap from an xpm: we cannot get the // location of our datadir before we've started our components, // so use an xpm. // If fullscreen, hide splash screen QPixmap pm(splash_screen_xpm); QSplashScreen splash(pm); if (!showFullscreen) { splash.show(); splash.showMessage("."); app.processEvents(); } #if defined HAVE_X11 QApplication::setAttribute(Qt::AA_X11InitThreads); #endif MainWindow window(fileNames); - if (args->isSet("vkb")) { - app.setInputContext(new SketchInputContext(&app)); - } +// QT5TODO +// if (args->isSet("vkb")) { +// app.setInputContext(new SketchInputContext(&app)); +// } if (args->isSet("sketch")) { window.setSlateMode(true); } if (showFullscreen) { window.showFullScreen(); } else { #ifdef Q_OS_WIN window.showMaximized(); #else window.show(); #endif } splash.finish(&window); return app.exec(); } diff --git a/krita/sketch/Theme.cpp b/krita/sketch/Theme.cpp index 437a979be8..5c20daf924 100644 --- a/krita/sketch/Theme.cpp +++ b/krita/sketch/Theme.cpp @@ -1,417 +1,419 @@ /* * This file is part of the KDE project * Copyright (C) 2014 Arjen Hiemstra * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "Theme.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "QmlGlobalEngine.h" #ifdef Q_OS_WIN #include #endif class Theme::Private { public: Private() : inheritedTheme(0) , iconPath("icons/") , imagePath("images/") , fontPath("fonts/") , fontsAdded(false) , lineCountLandscape(40) , lineCountPortrait(70) { } void rebuildFontCache(); QString id; QString name; QString inherits; Theme* inheritedTheme; QVariantMap colors; QVariantMap sizes; QVariantMap fonts; QString basePath; QString iconPath; QString imagePath; QString fontPath; QHash colorCache; QHash fontMap; bool fontsAdded; QList addedFonts; int lineCountLandscape; int lineCountPortrait; }; Theme::Theme(QObject* parent) : QObject(parent), d(new Private) { qApp->installEventFilter(this); } Theme::~Theme() { QFontDatabase db; Q_FOREACH(int id, d->addedFonts) { db.removeApplicationFont(id); } delete d; } QString Theme::id() const { return d->id; } void Theme::setId(const QString& newValue) { if(newValue != d->id) { d->id = newValue; const QString themeQmlPath = KoResourcePaths::findResource("data", QString("kritasketch/themes/%1/theme.qml").arg(d->id)); d->basePath = QFileInfo(themeQmlPath).dir().absolutePath(); emit idChanged(); } } QString Theme::name() const { return d->name; } void Theme::setName(const QString& newValue) { if(newValue != d->name) { d->name = newValue; emit nameChanged(); } } QString Theme::inherits() const { return d->inherits; } void Theme::setInherits(const QString& newValue) { if(newValue != d->inherits) { if(d->inheritedTheme) { delete d->inheritedTheme; d->inheritedTheme = 0; } d->inherits = newValue; if(!d->inherits.isEmpty()) { d->inheritedTheme = Theme::load(d->inherits, this); connect(d->inheritedTheme, SIGNAL(fontCacheRebuilt()), SIGNAL(fontCacheRebuilt())); } emit inheritsChanged(); } } QVariantMap Theme::colors() const { return d->colors; } void Theme::setColors(const QVariantMap& newValue) { if(newValue != d->colors) { d->colors = newValue; emit colorsChanged(); } } QColor Theme::color(const QString& name) { if(d->colorCache.contains(name)) return d->colorCache.value(name); QStringList parts = name.split('/'); QColor result; if(!parts.isEmpty()) { QVariantMap map = d->colors; QString current = parts.takeFirst(); while(map.contains(current)) { QVariant value = map.value(current); if(value.type() == QVariant::Map) { if(parts.isEmpty()) break; map = value.toMap(); current = parts.takeFirst(); } else { result = value.value(); map = QVariantMap(); } } } if(!result.isValid() && d->inheritedTheme) { result = d->inheritedTheme->color(name); } if(!result.isValid()) { warnKrita << "Unable to find color" << name; } else { d->colorCache.insert(name, result); } return result; } QVariantMap Theme::sizes() const { return d->sizes; } void Theme::setSizes(const QVariantMap& newValue) { if(newValue != d->sizes) { d->sizes = newValue; emit sizesChanged(); } } float Theme::size(const QString& name) { Q_UNUSED(name); return 0.f; } QVariantMap Theme::fonts() const { return d->fonts; } void Theme::setFonts(const QVariantMap& newValue) { if(newValue != d->fonts) { d->fonts = newValue; d->fontMap.clear(); emit fontsChanged(); } } QFont Theme::font(const QString& name) { if(!d->fontsAdded) { QDir fontDir(d->basePath + '/' + d->fontPath); QStringList entries = fontDir.entryList(QDir::Files); QFontDatabase db; Q_FOREACH(QString entry, entries) { d->addedFonts.append(db.addApplicationFont(fontDir.absoluteFilePath(entry))); } d->fontsAdded = true; } if(d->fontMap.isEmpty()) { d->rebuildFontCache(); } if(d->fontMap.contains(name)) return d->fontMap.value(name); if(d->inheritedTheme) return d->inheritedTheme->font(name); warnKrita << "Unable to find font" << name; return QFont(); } QString Theme::fontPath() const { return d->fontPath; } void Theme::setFontPath(const QString& newValue) { if(newValue != d->fontPath) { if(!d->addedFonts.isEmpty()) { QFontDatabase db; Q_FOREACH(int id, d->addedFonts) { db.removeApplicationFont(id); } d->addedFonts.clear(); } d->fontPath = newValue; d->fontsAdded = false; emit fontPathChanged(); } } QString Theme::iconPath() const { return d->iconPath; } void Theme::setIconPath(const QString& newValue) { if(newValue != d->iconPath) { d->iconPath = newValue; emit iconPathChanged(); } } QUrl Theme::icon(const QString& name) { QString url = QString("%1/%2/%3.svg").arg(d->basePath, d->iconPath, name); if(!QFile::exists(url)) { if(d->inheritedTheme) { return d->inheritedTheme->icon(name); } else { warnKrita << "Unable to find icon" << url; } } return QUrl::fromLocalFile(url); } QString Theme::imagePath() const { return d->imagePath; } void Theme::setImagePath(const QString& newValue) { if(newValue != d->imagePath) { d->imagePath = newValue; emit imagePathChanged(); } } QUrl Theme::image(const QString& name) { QString url = QString("%1/%2/%3").arg(d->basePath, d->imagePath, name); if(!QFile::exists(url)) { if(d->inheritedTheme) { return d->inheritedTheme->image(name); } else { warnKrita << "Unable to find image" << url; } } return QUrl::fromLocalFile(url); } Theme* Theme::load(const QString& id, QObject* parent) { QString qml; //Ugly hacky stuff for making things work on Windows #ifdef Q_OS_WIN QDir appdir(qApp->applicationDirPath()); // Corrects for mismatched case errors in path (qtdeclarative fails to load) wchar_t buffer[1024]; QString absolute = appdir.absolutePath(); DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024); rv = ::GetLongPathName(buffer, buffer, 1024); QString correctedPath((QChar *)buffer); appdir.setPath(correctedPath); // for now, the app in bin/ and we still use the env.bat script appdir.cdUp(); qml = QString("%1/share/apps/kritasketch/themes/%2/theme.qml").arg(appdir.canonicalPath(), id); #else qml = KoResourcePaths::findResource("data", QString("kritasketch/themes/%1/theme.qml").arg(id)); #endif QQmlComponent themeComponent(QmlGlobalEngine::instance()->engine(), parent); themeComponent.loadUrl(QUrl::fromLocalFile(qml), QQmlComponent::PreferSynchronous); + warnKrita << "+++++++++++" << themeComponent.url() << themeComponent.progress() << themeComponent.status(); + if(themeComponent.isError()) { warnKrita << themeComponent.errorString(); return 0; } Theme* theme = qobject_cast(themeComponent.create()); if(!theme) { warnKrita << "Failed to create theme instance!"; return 0; } return theme; } bool Theme::eventFilter(QObject* target, QEvent* event) { if(target == qApp->activeWindow() && target->inherits("QMainWindow") && event->type() == QEvent::Resize) { d->rebuildFontCache(); emit fontCacheRebuilt(); } return QObject::eventFilter(target, event); } void Theme::Private::rebuildFontCache() { fontMap.clear(); QFontDatabase db; for(QVariantMap::iterator itr = fonts.begin(); itr != fonts.end(); ++itr) { QVariantMap map = itr->toMap(); if(map.isEmpty()) continue; QFont font = db.font(map.value("family").toString(), map.value("style", "Regular").toString(), 10); if(font.isCopyOf(qApp->font())) warnKrita << "Could not find font" << map.value("family") << "with style" << map.value("style", "Regular"); float lineCount = qApp->activeWindow()->height() > qApp->activeWindow()->width() ? lineCountPortrait : lineCountLandscape; float lineHeight = qApp->activeWindow()->height() / lineCount; font.setPixelSize(lineHeight * map.value("size", 1).toFloat()); fontMap.insert(itr.key(), font); } } diff --git a/krita/ui/opengl/kis_texture_tile.cpp b/krita/ui/opengl/kis_texture_tile.cpp index 1417213be4..7cb17ed228 100644 --- a/krita/ui/opengl/kis_texture_tile.cpp +++ b/krita/ui/opengl/kis_texture_tile.cpp @@ -1,360 +1,359 @@ /* * Copyright (c) 2010 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define GL_GLEXT_PROTOTYPES #include "kis_texture_tile.h" #include "kis_texture_tile_update_info.h" #ifdef HAVE_OPENGL #include #include #ifndef GL_BGRA #define GL_BGRA 0x814F #endif void KisTextureTile::setTextureParameters() { f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, m_numMipmapLevels); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, m_numMipmapLevels); f->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); } inline QRectF relativeRect(const QRect &br /* baseRect */, const QRect &cr /* childRect */, const KisGLTexturesInfo *texturesInfo) { const qreal x = qreal(cr.x() - br.x()) / texturesInfo->width; const qreal y = qreal(cr.y() - br.y()) / texturesInfo->height; const qreal w = qreal(cr.width()) / texturesInfo->width; const qreal h = qreal(cr.height()) / texturesInfo->height; return QRectF(x, y, w, h); } KisTextureTile::KisTextureTile(const QRect &imageRect, const KisGLTexturesInfo *texturesInfo, const QByteArray &fillData, FilterMode filter, bool useBuffer, int numMipmapLevels, QOpenGLFunctions *fcn) : m_textureId(0) #ifdef USE_PIXEL_BUFFERS , m_glBuffer(0) #endif , m_tileRectInImagePixels(imageRect) , m_filter(filter) , m_texturesInfo(texturesInfo) , m_needsMipmapRegeneration(false) , m_currentLodPlane(0) , m_useBuffer(useBuffer) , m_numMipmapLevels(numMipmapLevels) , f(fcn) { const GLvoid *fd = fillData.constData(); m_textureRectInImagePixels = stretchRect(m_tileRectInImagePixels, texturesInfo->border); m_tileRectInTexturePixels = relativeRect(m_textureRectInImagePixels, m_tileRectInImagePixels, m_texturesInfo); f->glGenTextures(1, &m_textureId); f->glBindTexture(GL_TEXTURE_2D, m_textureId); setTextureParameters(); #ifdef USE_PIXEL_BUFFERS createTextureBuffer(fillData.constData(), fillData.size()); // we set fill data to 0 so the next glTexImage2D call uses our buffer fd = 0; #endif f->glTexImage2D(GL_TEXTURE_2D, 0, m_texturesInfo->internalFormat, m_texturesInfo->width, m_texturesInfo->height, 0, m_texturesInfo->format, m_texturesInfo->type, fd); #ifdef USE_PIXEL_BUFFERS if (m_useBuffer) { m_glBuffer->release(); } #endif setNeedsMipmapRegeneration(); } KisTextureTile::~KisTextureTile() { #ifdef USE_PIXEL_BUFFERS - if (m_useBuffer) { - delete m_glBuffer; - } + delete m_glBuffer; #endif f->glDeleteTextures(1, &m_textureId); } void KisTextureTile::bindToActiveTexture() { f->glBindTexture(GL_TEXTURE_2D, m_textureId); if (m_needsMipmapRegeneration) { f->glGenerateMipmap(GL_TEXTURE_2D); m_needsMipmapRegeneration = false; } } void KisTextureTile::setNeedsMipmapRegeneration() { // TODO: when a switch for LoD is implemented, put it there to // allow mipmapping in that case if (m_filter == TrilinearFilterMode || m_filter == HighQualityFiltering) { m_needsMipmapRegeneration = true; } m_currentLodPlane = 0; } int KisTextureTile::currentLodPlane() const { return m_currentLodPlane; } void KisTextureTile::setCurrentLodPlane(int lod) { m_currentLodPlane = lod; m_needsMipmapRegeneration = false; } void KisTextureTile::update(const KisTextureTileUpdateInfo &updateInfo) { f->initializeOpenGLFunctions(); f->glBindTexture(GL_TEXTURE_2D, m_textureId); setTextureParameters(); const int patchLevelOfDetail = updateInfo.patchLevelOfDetail(); const QSize patchSize = updateInfo.realPatchSize(); const QPoint patchOffset = updateInfo.realPatchOffset(); const GLvoid *fd = updateInfo.data(); #ifdef USE_PIXEL_BUFFERS if (!m_glBuffer) { createTextureBuffer((const char*)updateInfo.data(), updateInfo.patchPixelsLength()); } #endif if (updateInfo.isEntireTileUpdated()) { #ifdef USE_PIXEL_BUFFERS if (m_useBuffer) { m_glBuffer->bind(); m_glBuffer->allocate(updateInfo.patchPixelsLength()); void *vid = m_glBuffer->map(QOpenGLBuffer::WriteOnly); memcpy(vid, fd, updateInfo.patchPixelsLength()); m_glBuffer->unmap(); // we set fill data to 0 so the next glTexImage2D call uses our buffer fd = 0; } #endif f->glTexImage2D(GL_TEXTURE_2D, patchLevelOfDetail, m_texturesInfo->internalFormat, patchSize.width(), patchSize.height(), 0, m_texturesInfo->format, m_texturesInfo->type, fd); #ifdef USE_PIXEL_BUFFERS if (m_useBuffer) { m_glBuffer->release(); } #endif } else { #ifdef USE_PIXEL_BUFFERS if (m_useBuffer) { m_glBuffer->bind(); quint32 size = patchSize.width() * patchSize.height() * updateInfo.pixelSize(); m_glBuffer->allocate(size); void *vid = m_glBuffer->map(QOpenGLBuffer::WriteOnly); memcpy(vid, fd, size); m_glBuffer->unmap(); // we set fill data to 0 so the next glTexImage2D call uses our buffer fd = 0; } #endif f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail, patchOffset.x(), patchOffset.y(), patchSize.width(), patchSize.height(), m_texturesInfo->format, m_texturesInfo->type, fd); #ifdef USE_PIXEL_BUFFERS if (m_useBuffer) { m_glBuffer->release(); } #endif } /** * On the boundaries of KisImage, there is a border-effect as well. * So we just repeat the bounding pixels of the image to make * bilinear interpolator happy. */ /** * WARN: The width of the stripes will be equal to the broder * width of the tiles. */ const int pixelSize = updateInfo.pixelSize(); const QSize tileSize = updateInfo.realTileSize(); if(updateInfo.isTopmost()) { int start = 0; int end = patchOffset.y() - 1; for (int i = start; i <= end; i++) { f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail, patchOffset.x(), i, patchSize.width(), 1, m_texturesInfo->format, m_texturesInfo->type, updateInfo.data()); } } if (updateInfo.isBottommost()) { int shift = patchSize.width() * (patchSize.height() - 1) * pixelSize; int start = patchOffset.y() + patchSize.height(); int end = tileSize.height() - 1; for (int i = start; i < end; i++) { f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail, patchOffset.x(), i, patchSize.width(), 1, m_texturesInfo->format, m_texturesInfo->type, updateInfo.data() + shift); } } if (updateInfo.isLeftmost()) { QByteArray columnBuffer(patchSize.height() * pixelSize, 0); quint8 *srcPtr = updateInfo.data(); quint8 *dstPtr = (quint8*) columnBuffer.data(); for(int i = 0; i < patchSize.height(); i++) { memcpy(dstPtr, srcPtr, pixelSize); srcPtr += patchSize.width() * pixelSize; dstPtr += pixelSize; } int start = 0; int end = patchOffset.x() - 1; for (int i = start; i <= end; i++) { f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail, i, patchOffset.y(), 1, patchSize.height(), m_texturesInfo->format, m_texturesInfo->type, columnBuffer.constData()); } } if (updateInfo.isRightmost()) { QByteArray columnBuffer(patchSize.height() * pixelSize, 0); quint8 *srcPtr = updateInfo.data() + (patchSize.width() - 1) * pixelSize; quint8 *dstPtr = (quint8*) columnBuffer.data(); for(int i = 0; i < patchSize.height(); i++) { memcpy(dstPtr, srcPtr, pixelSize); srcPtr += patchSize.width() * pixelSize; dstPtr += pixelSize; } int start = patchOffset.x() + patchSize.width(); int end = tileSize.width() - 1; for (int i = start; i <= end; i++) { f->glTexSubImage2D(GL_TEXTURE_2D, patchLevelOfDetail, i, patchOffset.y(), 1, patchSize.height(), m_texturesInfo->format, m_texturesInfo->type, columnBuffer.constData()); } } if (!patchLevelOfDetail) { setNeedsMipmapRegeneration(); } else { setCurrentLodPlane(patchLevelOfDetail); } } #ifdef USE_PIXEL_BUFFERS void KisTextureTile::createTextureBuffer(const char *data, int size) { if (m_useBuffer) { if (!m_glBuffer) { m_glBuffer = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer); m_glBuffer->setUsagePattern(QOpenGLBuffer::DynamicDraw); m_glBuffer->create(); m_glBuffer->bind(); m_glBuffer->allocate(size); } void *vid = m_glBuffer->map(QOpenGLBuffer::WriteOnly); memcpy(vid, data, size); m_glBuffer->unmap(); } else { + delete m_glBuffer; m_glBuffer = 0; } } #endif #endif /* HAVE_OPENGL */ diff --git a/libs/widgetutils/kis_icon_utils.cpp b/libs/widgetutils/kis_icon_utils.cpp index 75a8779088..7d075332f0 100644 --- a/libs/widgetutils/kis_icon_utils.cpp +++ b/libs/widgetutils/kis_icon_utils.cpp @@ -1,179 +1,179 @@ /* * Copyright (c) 2015 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_icon_utils.h" #include #include #include #include #include #include #include #include #include namespace KisIconUtils { QIcon loadIcon(const QString &name) { // try load themed icon QColor background = qApp->palette().background().color(); bool useDarkIcons = background.value() > 100; const char * const prefix = useDarkIcons ? "dark_" : "light_"; QString realName = QLatin1String(prefix) + name; // Dark and light, no size specified const QStringList names = { ":/pics/" + realName + ".png", ":/pics/" + realName + ".svg", ":/pics/" + realName + ".svgz", ":/pics/" + name + ".png", ":/pics/" + name + ".svg", ":/pics/" + name + ".svz", ":/" + realName + ".png", ":/" + realName + ".svg", ":/" + realName + ".svz", ":/" + name, ":/" + name + ".png", ":/" + name + ".svg", ":/" + name + ".svgz"}; for (const QString &resname : names) { if (QFile(resname).exists()) { QIcon icon(resname); return icon; } } // Now check for icons with sizes QStringList sizes = QStringList() << "16_" << "22_" << "32_" << "48_" << "64_" << "128_" << "256_" << "512_" << "1048_"; QVector > icons; Q_FOREACH (const QString &size, sizes) { const QStringList names = { ":/pics/" + size + realName + ".png", ":/pics/" + size + realName + ".svg", ":/pics/" + size + realName + ".svgz", ":/pics/" + size + name + ".png", ":/pics/" + size + name + ".svg", ":/pics/" + size + name + ".svz", ":/" + size + realName + ".png", ":/" + size + realName + ".svg", ":/" + size + realName + ".svz", ":/" + size + name, ":/" + size + name + ".png", ":/" + size + name + ".svg", ":/" + size + name + ".svgz"}; for (const QString &resname : names) { if (QFile(resname).exists()) { icons << qMakePair(size, resname); } } } if (!icons.isEmpty()) { QIcon icon; Q_FOREACH (auto p, icons) { QString sz = p.first; sz.chop(1); int size = sz.toInt(); icon.addFile(p.second, QSize(size, size)); } return icon; } QIcon icon = QIcon::fromTheme(name); - qWarning() << "\tfalling back on QIcon::FromTheme:" << name; +// qWarning() << "\tfalling back on QIcon::FromTheme:" << name; return icon; } bool adjustIcon(QIcon *icon) { bool result = false; QString iconName = icon->name(); if (iconName.isNull()) return result; QString realIconName = iconName; if (iconName.startsWith("dark_")) { realIconName = iconName.mid(5); } if (iconName.startsWith("light_")) { realIconName = iconName.mid(6); } if (!realIconName.isNull()) { *icon = loadIcon(realIconName); result = !icon->isNull(); } return result; } void updateIconCommon(QObject *object) { QAbstractButton* button = dynamic_cast(object); if (button) { updateIcon(button); } QComboBox* comboBox = dynamic_cast(object); if (comboBox) { updateIcon(comboBox); } QAction* action = dynamic_cast(object); if (action) { updateIcon(action); } } void updateIcon(QAbstractButton *button) { QIcon icon = button->icon(); if (adjustIcon(&icon)) { button->setIcon(icon); } } void updateIcon(QComboBox *comboBox) { for (int i = 0; i < comboBox->count(); i++) { QIcon icon = comboBox->itemIcon(i); if (adjustIcon(&icon)) { comboBox->setItemIcon(i, icon); } } } void updateIcon(QAction *action) { QIcon icon = action->icon(); if (adjustIcon(&icon)) { action->setIcon(icon); } } }