예제 #1
0
/**
*  \copydoc MythUIType::customEvent()
*/
void MythUIImage::customEvent(QEvent *event)
{
    if (event->type() == ImageLoadEvent::kEventType)
    {
        ImageLoadEvent *le = dynamic_cast<ImageLoadEvent*>(event);

        if (le->GetParent() != this)
            return;

        MythImage *image = le->GetImage();

        if (!image)
            return;

        d->m_UpdateLock.lockForRead();
        if (le->GetBasefile() != m_Filename)
        {
            d->m_UpdateLock.unlock();
#if 0
            VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC +
                    QString("customEvent(): Expecting '%2', got '%3'")
                    .arg(m_Filename).arg(le->GetBasefile()));
#endif
            image->DownRef();
            return;
        }
        d->m_UpdateLock.unlock();

        QString filename = le->GetFilename();
        int number = le->GetNumber();

        d->m_UpdateLock.lockForWrite();
        if (m_ForceSize.isNull())
            SetSize(image->size());
        d->m_UpdateLock.unlock();

        m_ImagesLock.lock();
        if (m_Images[number])
        {
            // If we got to this point, it means this same MythUIImage
            // was told to reload the same image, so we use the newest
            // copy of the image.
            m_Images[number]->DownRef(); // delete the original
        }
        m_Images[number] = image;
        m_ImagesLock.unlock();

        SetRedraw();

        d->m_UpdateLock.lockForWrite();
        m_LastDisplay = QTime::currentTime();
        d->m_UpdateLock.unlock();
    }
}
예제 #2
0
/**
 *  \brief Assign a set of MythImages to the widget for animation.
 *         Use is strongly discouraged, use SetFilepattern() instead.
 *
 */
void MythUIImage::SetImages(QVector<MythImage *> &images)
{
    Clear();

    QWriteLocker updateLocker(&d->m_UpdateLock);
    QSize aSize = GetArea().size();

    QVector<MythImage *>::iterator it;
    for (it = images.begin(); it != images.end(); ++it)
    {
        MythImage *im = (*it);
        if (!im)
        {
            QMutexLocker locker(&m_ImagesLock);
            m_Images[m_Images.size()] = im;
            continue;
        }

        im->UpRef();

        if (!m_ForceSize.isNull())
        {
            int w = (m_ForceSize.width() <= 0) ? im->width() : m_ForceSize.width();
            int h = (m_ForceSize.height() <= 0) ? im->height() : m_ForceSize.height();

            im->Resize(QSize(w, h), m_preserveAspect);
        }

        if (m_isReflected && !im->IsReflected())
            im->Reflect(m_reflectAxis, m_reflectShear, m_reflectScale,
                         m_reflectLength, m_reflectSpacing);

        if (m_isGreyscale && !im->isGrayscale())
            im->ToGreyscale();

        m_ImagesLock.lock();
        m_Images[m_Images.size()] = im;
        m_ImagesLock.unlock();

        aSize = aSize.expandedTo(im->size());
    }

    SetImageCount(1, m_Images.size());

    if (m_ForceSize.isNull())
        SetSize(aSize);

    m_CurPos = 0;
    SetRedraw();
}
예제 #3
0
/**
 *  \brief Assign a set of MythImages to the widget for animation.
 *         Use is strongly discouraged, use SetFilepattern() instead.
 *
 */
void MythUIImage::SetImages(QVector<MythImage *> *images)
{
    Clear();

    QWriteLocker updateLocker(&d->m_UpdateLock);
    QSize aSize = GetFullArea().size();

    m_imageProperties.isThemeImage = false;

    QVector<MythImage *>::iterator it;

    for (it = images->begin(); it != images->end(); ++it)
    {
        MythImage *im = (*it);

        if (!im)
        {
            QMutexLocker locker(&m_ImagesLock);
            m_Images[m_Images.size()] = im;
            continue;
        }

        im->IncrRef();


        QSize forceSize = m_imageProperties.forceSize;
        if (!forceSize.isNull())
        {
            int w = (forceSize.width() <= 0) ? im->width() : forceSize.width();
            int h = (forceSize.height() <= 0) ? im->height() : forceSize.height();
            im->Resize(QSize(w, h), m_imageProperties.preserveAspect);
        }

        if (m_imageProperties.isReflected && !im->IsReflected())
            im->Reflect(m_imageProperties.reflectAxis,
                        m_imageProperties.reflectShear,
                        m_imageProperties.reflectScale,
                        m_imageProperties.reflectLength,
                        m_imageProperties.reflectSpacing);

        if (m_imageProperties.isGreyscale && !im->isGrayscale())
            im->ToGreyscale();

        if (m_imageProperties.isOriented && !im->IsOriented() &&
            (m_imageProperties.orientation >= 1 &&
             m_imageProperties.orientation <= 8))
            im->Orientation(m_imageProperties.orientation);

        m_ImagesLock.lock();
        m_Images[m_Images.size()] = im;
        m_ImagesLock.unlock();

        aSize = aSize.expandedTo(im->size());
    }

    SetImageCount(1, m_Images.size());

    if (m_imageProperties.forceSize.isNull())
        SetSize(aSize);

    MythRect rect(GetFullArea());
    rect.setSize(aSize);
    SetMinArea(rect);

    m_CurPos = 0;
    m_animatedImage = true;
    m_Initiator = m_EnableInitiator;
    SetRedraw();
}
예제 #4
0
    static MythImage *LoadImage(MythPainter *painter,
                                 // Must be a copy for thread safety
                                ImageProperties imProps,
                                ImageCacheMode cacheMode,
                                 // Included only to check address, could be
                                 // replaced by generating a unique value for
                                 // each MythUIImage object?
                                const MythUIImage *parent,
                                bool &aborted,
                                MythImageReader *imageReader = NULL)
    {
        QString cacheKey = GenImageLabel(imProps);
        if (!PreLoad(cacheKey, parent))
        {
            aborted = true;
            return NULL;
        }

        QString filename = imProps.filename;
        MythImage *image = NULL;

        bool bResize = false;
        bool bFoundInCache = false;

        int w = -1;
        int h = -1;

        if (!imProps.forceSize.isNull())
        {
            if (imProps.forceSize.width() != -1)
                w = imProps.forceSize.width();

            if (imProps.forceSize.height() != -1)
                h = imProps.forceSize.height();

            bResize = true;
        }

        if (!imageReader)
        {
            image = GetMythUI()->LoadCacheImage(filename, cacheKey,
                                                painter, cacheMode);
        }

        if (image)
        {
            if (VERBOSE_LEVEL_CHECK(VB_GUI | VB_FILE, LOG_INFO))
            {
                image->IncrRef();
                int cnt = image->DecrRef();
                LOG(VB_GUI | VB_FILE, LOG_INFO,
                    QString("ImageLoader::LoadImage(%1) Found in cache, "
                            "RefCount = %2")
                    .arg(cacheKey).arg(cnt));
            }

            if (imProps.isReflected)
                image->setIsReflected(true);

            if (imProps.isOriented)
                image->setIsOriented(true);

            bFoundInCache = true;
        }
        else
        {
            LOG(VB_GUI | VB_FILE, LOG_INFO,
                QString("ImageLoader::LoadImage(%1) NOT Found in cache. "
                        "Loading Directly").arg(cacheKey));

            image = painter->GetFormatImage();
            bool ok = false;

            if (imageReader)
                ok = image->Load(imageReader);
            else
                ok = image->Load(filename);

            if (!ok)
            {
                image->DecrRef();
                image = NULL;
            }
        }

        if (image && image->isNull())
        {
            LOG(VB_GUI | VB_FILE, LOG_INFO,
                QString("ImageLoader::LoadImage(%1) Image is NULL")
                                                    .arg(filename));

            image->DecrRef();
            image = NULL;
        }

        if (image && !bFoundInCache)
        {
            if (imProps.isReflected)
                image->Reflect(imProps.reflectAxis, imProps.reflectShear,
                               imProps.reflectScale, imProps.reflectLength,
                               imProps.reflectSpacing);

            if (imProps.isGreyscale)
                image->ToGreyscale();

            if (imProps.isOriented)
                image->Orientation(imProps.orientation);

            // Even if an explicit size wasn't defined this image may still need
            // to be scaled because of a difference between the theme resolution
            // and the screen resolution. We want to avoid scaling twice.
            if (!bResize && imProps.isThemeImage)
            {
                float wmult; // Width multipler
                float hmult; // Height multipler
                GetMythUI()->GetScreenSettings(wmult, hmult);
                if (wmult != 1.0f || hmult != 1.0f)
                {
                    w = image->size().width() * wmult;
                    h = image->size().height() * hmult;
                    bResize = true;
                }
            }

            if (bResize)
                image->Resize(QSize(w, h), imProps.preserveAspect);

            if (imProps.isMasked)
            {
                QRect imageArea = image->rect();
                QRect maskArea = imProps.GetMaskImageRect();

                // Crop the mask to the image
                int x = 0;
                int y = 0;

                if (maskArea.width() > imageArea.width())
                    x = (maskArea.width() - imageArea.width()) / 2;

                if (maskArea.height() > imageArea.height())
                    y = (maskArea.height() - imageArea.height()) / 2;

                if (x > 0 || y > 0)
                    imageArea.translate(x, y);

                QImage mask = imProps.GetMaskImageSubset(imageArea);
                image->setAlphaChannel(mask.alphaChannel());
            }

            if (!imageReader)
                GetMythUI()->CacheImage(cacheKey, image);
        }

        if (image)
            image->SetChanged();

        PostLoad(cacheKey);

        return image;
    }
예제 #5
0
/**
*  \copydoc MythUIType::customEvent()
*/
void MythUIImage::customEvent(QEvent *event)
{
    if (event->type() == ImageLoadEvent::kEventType)
    {
        MythImage *image = NULL;
        AnimationFrames *animationFrames = NULL;
        int number = 0;
        QString filename;
        bool aborted;

        ImageLoadEvent *le = static_cast<ImageLoadEvent *>(event);

        if (le->GetParent() != this)
            return;

        image  = le->GetImage();
        number = le->GetNumber();
        filename = le->GetFilename();
        animationFrames = le->GetAnimationFrames();
        aborted = le->GetAbortState();

        m_runningThreads--;

        d->m_UpdateLock.lockForRead();

        // 1) We aborted loading the image for some reason (e.g. two requests
        //    for same image)
        // 2) Filename changed since we started this image, so abort to avoid
        // rendering two different images in quick succession which causes
        // unsightly flickering
        if (aborted ||
            (le->GetBasefile() != m_imageProperties.filename))
        {
            d->m_UpdateLock.unlock();

            if (aborted)
                LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading image %1")
                                                                .arg(filename));

            if (image)
                image->DecrRef();

            if (animationFrames)
            {
                AnimationFrames::iterator it;

                for (it = animationFrames->begin(); it != animationFrames->end();
                     ++it)
                {
                    MythImage *im = (*it).first;
                    if (im)
                        im->DecrRef();
                }

                delete animationFrames;
            }

            return;
        }

        d->m_UpdateLock.unlock();

        if (animationFrames)
        {
            SetAnimationFrames(*animationFrames);

            delete animationFrames;

            return;
        }

        if (image)
        {
            // We don't clear until we have the new image ready to display to
            // avoid unsightly flashing. This isn't currently supported for
            // animations.
            if ((m_HighNum == m_LowNum) && !m_animatedImage)
                Clear();

            d->m_UpdateLock.lockForWrite();

            if (m_imageProperties.forceSize.isNull())
                SetSize(image->size());

            MythRect rect(GetFullArea());
            rect.setSize(image->size());
            SetMinArea(rect);

            d->m_UpdateLock.unlock();

            m_ImagesLock.lock();

            if (m_Images[number])
            {
                // If we got to this point, it means this same MythUIImage
                // was told to reload the same image, so we use the newest
                // copy of the image.
                m_Images[number]->DecrRef(); // delete the original
            }

            m_Images[number] = image;
            m_ImagesLock.unlock();

            SetRedraw();

            d->m_UpdateLock.lockForWrite();
            m_LastDisplay = QTime::currentTime();
            d->m_UpdateLock.unlock();

            return;
        }

        // No Images were loaded, so trigger Reset to default
        Reset();
    }
}
예제 #6
0
/**
 *  \copydoc MythUIType::ParseElement()
 */
bool MythUIImage::ParseElement(
    const QString &filename, QDomElement &element, bool showWarnings)
{
    QWriteLocker updateLocker(&d->m_UpdateLock);

    if (element.tagName() == "filename")
    {
        m_imageProperties.isThemeImage = true; // This is an image distributed with the them
        m_OrigFilename = m_imageProperties.filename = getFirstText(element);

        if (m_imageProperties.filename.endsWith('/'))
        {
            m_showingRandomImage = true;
            m_imageDirectory = m_imageProperties.filename;

            FindRandomImage();
        }
    }
    else if (element.tagName() == "filepattern")
    {
        m_imageProperties.isThemeImage = true; // This is an image distributed with the theme
        m_OrigFilename = m_imageProperties.filename = getFirstText(element);
        QString tmp = element.attribute("low");

        if (!tmp.isEmpty())
            m_LowNum = tmp.toInt();

        tmp = element.attribute("high");

        if (!tmp.isEmpty())
            m_HighNum = tmp.toInt();

        tmp = element.attribute("cycle", "start");

        if (tmp == "reverse")
            m_animationCycle = kCycleReverse;
    }
    else if (element.tagName() == "area")
    {
        SetArea(parseRect(element));
        m_imageProperties.forceSize = m_Area.size();
    }
    else if (element.tagName() == "preserveaspect")
        m_imageProperties.preserveAspect = parseBool(element);
    else if (element.tagName() == "crop")
        m_imageProperties.cropRect = parseRect(element);
    else if (element.tagName() == "delay")
    {
        QString value = getFirstText(element);

        if (value.contains(","))
        {
            QVector<int> delays;
            QStringList tokens = value.split(",");
            QStringList::iterator it = tokens.begin();

            for (; it != tokens.end(); ++it)
            {
                if ((*it).isEmpty())
                {
                    if (delays.size())
                        delays.append(delays[delays.size()-1]);
                    else
                        delays.append(0); // Default 0ms delay before first image
                }
                else
                {
                    delays.append((*it).toInt());
                }
            }

            if (delays.size())
            {
                m_Delay = delays[0];
                SetDelays(delays);
            }
        }
        else
        {
            m_Delay = value.toInt();
        }
    }
    else if (element.tagName() == "reflection")
    {
        m_imageProperties.isReflected = true;
        QString tmp = element.attribute("axis");

        if (!tmp.isEmpty())
        {
            if (tmp.toLower() == "horizontal")
                m_imageProperties.reflectAxis = ReflectHorizontal;
            else
                m_imageProperties.reflectAxis = ReflectVertical;
        }

        tmp = element.attribute("shear");

        if (!tmp.isEmpty())
            m_imageProperties.reflectShear = tmp.toInt();

        tmp = element.attribute("scale");

        if (!tmp.isEmpty())
            m_imageProperties.reflectScale = tmp.toInt();

        tmp = element.attribute("length");

        if (!tmp.isEmpty())
            m_imageProperties.reflectLength = tmp.toInt();

        tmp = element.attribute("spacing");

        if (!tmp.isEmpty())
            m_imageProperties.reflectSpacing = tmp.toInt();
    }
    else if (element.tagName() == "mask")
    {
        QString maskfile = getFirstText(element);

        MythImage *newMaskImage = GetPainter()->GetFormatImage();
        if (newMaskImage->Load(maskfile))
        {
            float wmult; // Width multipler
            float hmult; // Height multipler
            GetMythUI()->GetScreenSettings(wmult, hmult);
            if (wmult != 1.0f || hmult != 1.0f)
            {
                int width = newMaskImage->size().width() * wmult;
                int height = newMaskImage->size().height() * hmult;
                newMaskImage->Resize(QSize(width, height));
            }

            m_imageProperties.SetMaskImage(newMaskImage);
        }
        else
            m_imageProperties.SetMaskImage(NULL);
        newMaskImage->DecrRef();
    }
    else if (element.tagName() == "grayscale" ||
             element.tagName() == "greyscale")
    {
        m_imageProperties.isGreyscale = parseBool(element);
    }
    else
    {
        return MythUIType::ParseElement(filename, element, showWarnings);
    }

    m_NeedLoad = true;

    if (m_Parent && m_Parent->IsDeferredLoading(true))
        m_NeedLoad = false;

    return true;
}
예제 #7
0
/**
 *  \copydoc MythUIType::DrawSelf()
 */
void MythUIImage::DrawSelf(MythPainter *p, int xoffset, int yoffset,
                           int alphaMod, QRect clipRect)
{
    m_ImagesLock.lock();

    if (m_Images.size() > 0)
    {
        d->m_UpdateLock.lockForWrite();

        if (m_CurPos >= (uint)m_Images.size())
            m_CurPos = 0;

        if (!m_Images[m_CurPos])
        {
            unsigned int origPos = m_CurPos;
            m_CurPos++;

            while (!m_Images[m_CurPos] && m_CurPos != origPos)
            {
                m_CurPos++;

                if (m_CurPos >= (uint)m_Images.size())
                    m_CurPos = 0;
            }
        }

        QRect area = GetArea().toQRect();
        area.translate(xoffset, yoffset);

        int alpha = CalcAlpha(alphaMod);

        MythImage *currentImage = m_Images[m_CurPos];

        if (currentImage)
            currentImage->IncrRef();

        m_ImagesLock.unlock();
        d->m_UpdateLock.unlock();

        if (!currentImage)
            return;

        d->m_UpdateLock.lockForRead();

        QRect currentImageArea = currentImage->rect();

        if (!m_imageProperties.forceSize.isNull())
            area.setSize(area.size().expandedTo(currentImage->size()));

        // Centre image in available space, accounting for zoom
        int x = 0, y = 0;
        QRect visibleImage = m_Effects.GetExtent(currentImageArea.size());

        if (area.width() > visibleImage.width())
            x = area.width() / 2 + visibleImage.topLeft().x();

        if (area.height() > visibleImage.height())
            y = area.height() / 2 + visibleImage.topLeft().y();

        if ((x > 0 || y > 0))
            area.translate(x, y);

        QRect srcRect;
        m_imageProperties.cropRect.CalculateArea(GetFullArea());

        if (!m_imageProperties.cropRect.isEmpty())
            srcRect = m_imageProperties.cropRect.toQRect();
        else
            srcRect = currentImageArea;

        p->DrawImage(area, currentImage, srcRect, alpha);
        currentImage->DecrRef();
        d->m_UpdateLock.unlock();
    }
    else
        m_ImagesLock.unlock();
}
예제 #8
0
/**
 *  \brief Load the image(s), wraps ImageLoader::LoadImage()
 */
bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat)
{
    d->m_UpdateLock.lockForRead();

    m_Initiator = m_EnableInitiator;

    QString bFilename = m_imageProperties.filename;
    bFilename.detach();

    d->m_UpdateLock.unlock();

    QString filename = bFilename;

    if (bFilename.isEmpty())
    {
        Clear();
        SetMinArea(MythRect());
        SetRedraw();

        return false;
    }

    if (getenv("DISABLETHREADEDMYTHUIIMAGE"))
        allowLoadInBackground = false;

    // Don't clear the widget before we need to, otherwise it causes
    // unsightly flashing. We exclude animations for now since that requires a
    // deeper fix
    bool isAnimation = (m_HighNum != m_LowNum) || m_animatedImage;

    if (isAnimation)
        Clear();

    QString imagelabel;

    int j = 0;

    for (int i = m_LowNum; i <= m_HighNum && !m_animatedImage; i++)
    {
        if (!m_animatedImage && m_HighNum != m_LowNum &&
            bFilename.contains("%1"))
            filename = bFilename.arg(i);

        ImageProperties imProps = m_imageProperties;
        imProps.filename = filename;
        imagelabel = ImageLoader::GenImageLabel(imProps);

        // Only load in the background if allowed and the image is
        // not already in our mem cache
        int cacheMode = kCacheIgnoreDisk;

        if (forceStat)
            cacheMode |= (int)kCacheForceStat;

        int cacheMode2 = kCacheNormal;

        if (forceStat)
            cacheMode2 |= (int)kCacheForceStat;

        bool do_background_load = false;
        if (allowLoadInBackground)
        {
            MythImage *img = GetMythUI()->LoadCacheImage(
                filename, imagelabel, GetPainter(),
                static_cast<ImageCacheMode>(cacheMode));
            if (img)
                img->DecrRef();
            else
                do_background_load = true;
        }

        if (do_background_load)
        {
            SetMinArea(MythRect());
            LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
                QString("Load(), spawning thread to load '%1'").arg(filename));

            m_runningThreads++;
            ImageLoadThread *bImgThread;
            bImgThread = new ImageLoadThread(this, GetPainter(),
                                             imProps,
                                             bFilename, i,
                                             static_cast<ImageCacheMode>(cacheMode2));
            GetMythUI()->GetImageThreadPool()->start(bImgThread, "ImageLoad");
        }
        else
        {
            if (!isAnimation && !GetMythUI()->IsImageInCache(imagelabel))
                Clear();

            // Perform a blocking load
            LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
                QString("Load(), loading '%1' in foreground").arg(filename));
            bool aborted = false;

            if (ImageLoader::SupportsAnimation(filename))
            {
                AnimationFrames *myFrames;

                myFrames = ImageLoader::LoadAnimatedImage(GetPainter(), imProps,
                                        static_cast<ImageCacheMode>(cacheMode2),
                                        this, aborted);

                // TODO We might want to handle an abort here more gracefully
                if (aborted)
                    LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated"
                                                   "image %1 in foreground")
                                                                .arg(filename));

                SetAnimationFrames(*myFrames);

                delete myFrames;
            }
            else
            {
                MythImage *image = NULL;

                image = ImageLoader::LoadImage(GetPainter(),
                                               imProps,
                                               static_cast<ImageCacheMode>(cacheMode2),
                                               this, aborted);

                // TODO We might want to handle an abort here more gracefully
                if (aborted)
                    LOG(VB_GUI, LOG_DEBUG, QString("Aborted loading animated"
                                                   "image %1 in foreground")
                                                                .arg(filename));

                if (image)
                {
                    if (m_imageProperties.forceSize.isNull())
                        SetSize(image->size());

                    MythRect rect(GetFullArea());
                    rect.setSize(image->size());
                    SetMinArea(rect);

                    m_ImagesLock.lock();
                    m_Images[j] = image;
                    m_ImagesLock.unlock();

                    SetRedraw();
                    d->m_UpdateLock.lockForWrite();
                    m_LastDisplay = QTime::currentTime();
                    d->m_UpdateLock.unlock();
                }
                else
                {
                    Reset();

                    m_ImagesLock.lock();
                    m_Images[j] = NULL;
                    m_ImagesLock.unlock();
                }
            }
        }

        ++j;
    }

    return true;
}
예제 #9
0
/**
 *  \copydoc MythUIType::DrawSelf()
 */
void MythUIImage::DrawSelf(MythPainter *p, int xoffset, int yoffset,
                           int alphaMod, QRect clipRect)
{
    m_ImagesLock.lock();
    if (m_Images.size() > 0)
    {
        d->m_UpdateLock.lockForWrite();
        if (m_CurPos >= (uint)m_Images.size())
            m_CurPos = 0;
        if (!m_Images[m_CurPos])
        {
            unsigned int origPos = m_CurPos;
            m_CurPos++;
            while (!m_Images[m_CurPos] && m_CurPos != origPos)
            {
                m_CurPos++;
                if (m_CurPos >= (uint)m_Images.size())
                    m_CurPos = 0;
            }
        }

        QRect area = GetArea().toQRect();
        area.translate(xoffset, yoffset);

        int alpha = CalcAlpha(alphaMod);

        MythImage *currentImage = m_Images[m_CurPos];
        if (currentImage)
            currentImage->UpRef();
        m_ImagesLock.unlock();
        d->m_UpdateLock.unlock();

        if (!currentImage)
            return;

        d->m_UpdateLock.lockForRead();

        QRect currentImageArea = currentImage->rect();

        if (!m_ForceSize.isNull())
            area.setSize(area.size().expandedTo(currentImage->size()));

        // Centre image in available space
        int x = 0;
        int y = 0;
        if (area.width() > currentImageArea.width())
            x = (area.width() - currentImageArea.width()) / 2;
        if (area.height() > currentImageArea.height())
            y = (area.height() - currentImageArea.height()) / 2;

        if (x > 0 || y > 0)
            area.translate(x,y);

        QRect srcRect;
        m_cropRect.CalculateArea(GetArea());
        if (!m_cropRect.isEmpty())
            srcRect = m_cropRect.toQRect();
        else
            srcRect = currentImageArea;

        p->DrawImage(area, currentImage, srcRect, alpha);
        currentImage->DownRef();
        d->m_UpdateLock.unlock();
    }
    else
        m_ImagesLock.unlock();
}
예제 #10
0
/**
 *  \brief Load the image(s), wraps LoadImage()
 */
bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat)
{
    d->m_UpdateLock.lockForRead();

    QSize bForceSize = m_ForceSize;
    QString bFilename = m_Filename;
    bFilename.detach();

    d->m_UpdateLock.unlock();

    QString filename = bFilename;

    if (bFilename.isEmpty())
    {
        Clear();
        SetRedraw();

        return false;
    }

    Clear();

//    SetRedraw();

//    if (!IsVisible(true))
//        return false;

    int w = -1;
    int h = -1;

    if (!bForceSize.isNull())
    {
        if (bForceSize.width() != -1)
            w = bForceSize.width();

        if (bForceSize.height() != -1)
            h = bForceSize.height();
    }

    QString imagelabel;

    int j = 0;
    for (int i = m_LowNum; i <= m_HighNum && !m_animatedImage; i++)
    {
        if (!m_animatedImage && m_HighNum != m_LowNum && 
            bFilename.contains("%1"))
            filename = bFilename.arg(i);

        imagelabel = GenImageLabel(filename, w, h);

        // Only load in the background if allowed and the image is
        // not already in our mem cache
        ImageCacheMode cacheMode = kCacheCheckMemoryOnly;
        if (forceStat)
            cacheMode = (ImageCacheMode)
                ((int)kCacheCheckMemoryOnly | (int)kCacheForceStat);

        ImageCacheMode cacheMode2 = (!forceStat) ? kCacheNormal :
            (ImageCacheMode) ((int)kCacheNormal | (int)kCacheForceStat);


        if ((allowLoadInBackground) &&
            (!GetMythUI()->LoadCacheImage(filename, imagelabel,
                                          GetPainter(), cacheMode)) &&
            (!getenv("DISABLETHREADEDMYTHUIIMAGE")))
        {
            VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                        "Load(), spawning thread to load '%1'").arg(filename));
            ImageLoadThread *bImgThread = new ImageLoadThread(
                this, bFilename, filename, i, bForceSize, cacheMode2);
            GetMythUI()->GetImageThreadPool()->start(bImgThread);
        }
        else
        {
            // Perform a blocking load
            VERBOSE(VB_GUI|VB_FILE|VB_EXTRA, LOC + QString(
                        "Load(), loading '%1' in foreground").arg(filename));
            QString tmpFilename;
            if ((filename.startsWith("/")) ||
                (filename.startsWith("http://")) ||
                (filename.startsWith("https://")) ||
                (filename.startsWith("ftp://")))
                tmpFilename = filename;

            MythImageReader imageReader(tmpFilename);

            if (imageReader.supportsAnimation())
            {
                LoadAnimatedImage(
                    imageReader, filename, bForceSize, cacheMode2);
            }
            else
            {
                MythImage *image = LoadImage(
                    imageReader, filename, bForceSize, cacheMode2);
                if (image)
                {
                    if (bForceSize.isNull())
                        SetSize(image->size());

                    m_ImagesLock.lock();
                    m_Images[j] = image;
                    m_ImagesLock.unlock();

                    SetRedraw();
                    d->m_UpdateLock.lockForWrite();
                    m_LastDisplay = QTime::currentTime();
                    d->m_UpdateLock.unlock();
                }
                else
                {
                    m_ImagesLock.lock();
                    m_Images[j] = NULL;
                    m_ImagesLock.unlock();
                }
            }
        }
        ++j;
    }

    return true;
}