/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "imgprod.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include ImageProducer::ImageProducer() : mpStm(nullptr) , mnTransIndex(0) , mbConsInit(false) { moGraphic.emplace(); } ImageProducer::~ImageProducer() { } // XInterface css::uno::Any ImageProducer::queryInterface( const css::uno::Type & rType ) { css::uno::Any aRet = ::cppu::queryInterface( rType, static_cast< css::lang::XInitialization* >(this), static_cast< css::lang::XServiceInfo* >(this), static_cast< css::awt::XImageProducer* >(this) ); return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); } void ImageProducer::addConsumer( const css::uno::Reference< css::awt::XImageConsumer >& rxConsumer ) { DBG_ASSERT( rxConsumer.is(), "::AddConsumer(...): No consumer referenced!" ); if( rxConsumer.is() ) maConsList.push_back( rxConsumer ); } void ImageProducer::removeConsumer( const css::uno::Reference< css::awt::XImageConsumer >& rxConsumer ) { ConsumerList_t::reverse_iterator riter = std::find(maConsList.rbegin(),maConsList.rend(),rxConsumer); if (riter != maConsList.rend()) maConsList.erase(riter.base()-1); } void ImageProducer::SetImage( const OUString& rPath ) { maURL = rPath; moGraphic->Clear(); mbConsInit = false; mxOwnedStream.reset(); mpStm = nullptr; if ( ::svt::GraphicAccess::isSupportedURL( maURL ) ) { mxOwnedStream = ::svt::GraphicAccess::getImageStream( ::comphelper::getProcessComponentContext(), maURL ); mpStm = mxOwnedStream.get(); } else if( !maURL.isEmpty() ) { mxOwnedStream = ::utl::UcbStreamHelper::CreateStream( maURL, StreamMode::STD_READ ); mpStm = mxOwnedStream.get(); } } void ImageProducer::SetImage( SvStream& rStm ) { maURL.clear(); moGraphic->Clear(); mbConsInit = false; mxOwnedStream.reset(); mpStm = &rStm; } void ImageProducer::setImage( css::uno::Reference< css::io::XInputStream > const & rInputStmRef ) { maURL.clear(); moGraphic->Clear(); mbConsInit = false; mxOwnedStream.reset(); mpStm = nullptr; if( rInputStmRef.is() ) { mxOwnedStream = utl::UcbStreamHelper::CreateStream( rInputStmRef ); mpStm = mxOwnedStream.get(); } } void ImageProducer::NewDataAvailable() { if (GraphicType::NONE == moGraphic->GetType()) startProduction(); } void ImageProducer::startProduction() { if( maConsList.empty() && !maDoneHdl.IsSet() ) return; bool bNotifyEmptyGraphics = false; // valid stream or filled graphic? => update consumers if (mpStm || moGraphic->GetType() != GraphicType::NONE) { // if we already have a graphic, we don't have to import again; // graphic is cleared if a new Stream is set if (moGraphic->GetType() == GraphicType::NONE) { if ( ImplImportGraphic( *moGraphic ) ) maDoneHdl.Call( &*moGraphic ); } if( moGraphic->GetType() != GraphicType::NONE ) ImplUpdateData( *moGraphic ); else bNotifyEmptyGraphics = true; } else bNotifyEmptyGraphics = true; if ( !bNotifyEmptyGraphics ) return; // reset image // create temporary list to hold interfaces ConsumerList_t aTmp = maConsList; // iterate through interfaces for (auto const& elem : aTmp) { elem->init( 0, 0 ); elem->complete( css::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this ); } maDoneHdl.Call( nullptr ); } bool ImageProducer::ImplImportGraphic( Graphic& rGraphic ) { if (!mpStm) return false; if( ERRCODE_IO_PENDING == mpStm->GetError() ) mpStm->ResetError(); mpStm->Seek( 0 ); bool bRet = GraphicConverter::Import( *mpStm, rGraphic ) == ERRCODE_NONE; if( ERRCODE_IO_PENDING == mpStm->GetError() ) mpStm->ResetError(); return bRet; } void ImageProducer::ImplUpdateData( const Graphic& rGraphic ) { ImplInitConsumer( rGraphic ); if( mbConsInit && !maConsList.empty() ) { // create temporary list to hold interfaces ConsumerList_t aTmp = maConsList; ImplUpdateConsumer( rGraphic ); mbConsInit = false; // iterate through interfaces for (auto const& elem : aTmp) elem->complete( css::awt::ImageStatus::IMAGESTATUS_STATICIMAGEDONE, this ); } } void ImageProducer::ImplInitConsumer( const Graphic& rGraphic ) { sal_uInt32 nRMask = 0; sal_uInt32 nGMask = 0; sal_uInt32 nBMask = 0; sal_uInt32 nAMask = 0; sal_uInt32 nWidth = 0; sal_uInt32 nHeight = 0; sal_uInt8 nBitCount = 0; css::uno::Sequence< sal_Int32 > aRGBPal; rGraphic.GetBitmapEx().GetColorModel(aRGBPal, nRMask, nGMask, nBMask, nAMask, mnTransIndex, nWidth, nHeight, nBitCount); // create temporary list to hold interfaces ConsumerList_t aTmp = maConsList; // iterate through interfaces for (auto const& elem : aTmp) { elem->init( nWidth, nHeight ); elem->setColorModel( nBitCount,aRGBPal, nRMask, nGMask, nBMask, nAMask ); } mbConsInit = true; } void ImageProducer::ImplUpdateConsumer( const Graphic& rGraphic ) { BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); Bitmap aBmp( aBmpEx.GetBitmap() ); BitmapScopedReadAccess pBmpAcc(aBmp); if( !pBmpAcc ) return; AlphaMask aMask( aBmpEx.GetAlphaMask() ); BitmapScopedReadAccess pMskAcc; if (!aMask.IsEmpty()) pMskAcc = aMask; const tools::Long nWidth = pBmpAcc->Width(); const tools::Long nHeight = pBmpAcc->Height(); const tools::Long nStartX = 0; const tools::Long nEndX = nWidth - 1; const tools::Long nStartY = 0; const tools::Long nEndY = nHeight - 1; const tools::Long nPartWidth = nEndX - nStartX + 1; const tools::Long nPartHeight = nEndY - nStartY + 1; if( !pMskAcc ) { aMask = AlphaMask(aBmp.GetSizePixel()); aMask.Erase( 0 ); pMskAcc = aMask; } // create temporary list to hold interfaces ConsumerList_t aTmp = maConsList; if( pBmpAcc->HasPalette() ) { const BitmapColor aWhite( pMskAcc->GetBestMatchingColor( COL_ALPHA_TRANSPARENT ) ); if( mnTransIndex < 256 ) { css::uno::Sequence aData( nPartWidth * nPartHeight ); sal_Int8* pTmp = aData.getArray(); for( tools::Long nY = nStartY; nY <= nEndY; nY++ ) { Scanline pScanlineMask = pMskAcc->GetScanline( nY ); Scanline pScanline = pBmpAcc->GetScanline( nY ); for( tools::Long nX = nStartX; nX <= nEndX; nX++ ) { if( pMskAcc->GetPixelFromData( pScanlineMask, nX ) == aWhite ) *pTmp++ = sal::static_int_cast< sal_Int8 >( mnTransIndex ); else *pTmp++ = pBmpAcc->GetPixelFromData( pScanline, nX ).GetIndex(); } } // iterate through interfaces for (auto const& elem : aTmp) elem->setPixelsByBytes( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth ); } else { css::uno::Sequence aData( nPartWidth * nPartHeight ); sal_Int32* pTmp = aData.getArray(); for( tools::Long nY = nStartY; nY <= nEndY; nY++ ) { Scanline pScanlineMask = pMskAcc->GetScanline( nY ); Scanline pScanline = pBmpAcc->GetScanline( nY ); for( tools::Long nX = nStartX; nX <= nEndX; nX++ ) { if( pMskAcc->GetPixelFromData( pScanlineMask, nX ) == aWhite ) *pTmp++ = mnTransIndex; else *pTmp++ = pBmpAcc->GetPixelFromData( pScanline, nX ).GetIndex(); } } // iterate through interfaces for (auto const& elem : aTmp) elem->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth ); } } else { css::uno::Sequence aData( nPartWidth * nPartHeight ); const BitmapColor aWhite( pMskAcc->GetBestMatchingColor( COL_WHITE ) ); sal_Int32* pTmp = aData.getArray(); for( tools::Long nY = nStartY; nY <= nEndY; nY++ ) { Scanline pScanlineMask = pMskAcc->GetScanline( nY ); Scanline pScanline = pBmpAcc->GetScanline( nY ); for( tools::Long nX = nStartX; nX <= nEndX; nX++, pTmp++ ) { const BitmapColor aCol( pBmpAcc->GetPixelFromData( pScanline, nX ) ); *pTmp = static_cast(aCol.GetRed()) << 24; *pTmp |= static_cast(aCol.GetGreen()) << 16; *pTmp |= static_cast(aCol.GetBlue()) << 8; if( pMskAcc->GetPixelFromData( pScanlineMask, nX ) != aWhite ) *pTmp |= 0x000000ffUL; } } // iterate through interfaces for (auto const& elem : aTmp) elem->setPixelsByLongs( nStartX, nStartY, nPartWidth, nPartHeight, aData, 0UL, nPartWidth ); } } void ImageProducer::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) { if ( aArguments.getLength() == 1 ) { css::uno::Any aArg = aArguments.getConstArray()[0]; OUString aURL; if ( aArg >>= aURL ) { SetImage( aURL ); } } } OUString ImageProducer::getImplementationName() { return u"com.sun.star.form.ImageProducer"_ustr; } sal_Bool ImageProducer::supportsService(OUString const & ServiceName) { return cppu::supportsService(this, ServiceName); } css::uno::Sequence ImageProducer::getSupportedServiceNames() { return {u"com.sun.star.awt.ImageProducer"_ustr}; } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* com_sun_star_form_ImageProducer_get_implementation(css::uno::XComponentContext*, css::uno::Sequence const &) { return cppu::acquire(new ImageProducer()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 3_2'>feature/calctiledrendering_attempt3_2 LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2021-12-18Fix loplugin:unusedvariablecheckStephan Bergmann
2021-12-17loplugin:unusedvariablecheck improveNoel Grandin
2021-12-15ucb: remove --with-webdav=neonMichael Stahl
2021-12-13Adapt CompilerTest_compilerplugins_clangStephan Bergmann
2021-12-07improve loplugin:cow_wrapperNoel Grandin
2021-12-07loplugin:unusedmethodsNoel Grandin
2021-12-07loplugin:unusedfieldsNoel Grandin
2021-12-07loplugin:unnecessaryvirtualNoel Grandin
2021-11-30Silence loplugin:badstaticsStephan Bergmann
2021-11-26-FIIntrin.h in CC/CXX is no longer needed for my clang-cl buildStephan Bergmann
2021-11-23Fix test for clang-cl with the MSVC template instantiation modelStephan Bergmann
2021-11-22sw: prefix members of SwDBManager, SwWebGlosDocShell, SwWordCountWrapper ...Miklos Vajna
2021-11-17drop unused PopupMenuFlags::NoHorzPlacementCaolán McNamara
2021-11-17retire loplugin:simplifyboolLuboš Luňák
2021-11-17remove loplugin:finalprotectedLuboš Luňák
2021-11-15Adapt CompilerTest_compilerplugins_clangStephan Bergmann
2021-11-11Drop ScGlobal::GetEmptyOUString() and EMPTY_OUSTRINGMike Kaganski
2021-11-10new loplugin:stringliteraldefineNoel Grandin
2021-11-10Avoid unhelpful loplugin:stringview from implicit conversionsStephan Bergmann
2021-11-09Adapt test to clang-cl on Windows (sal_Int32 typedef int vs. long)Stephan Bergmann
2021-11-03Silence loplugin:toolslong in ucb/source/ucp/webdav-curl/CurlSession.cxxStephan Bergmann
2021-11-03loplugin:constparamsNoel Grandin
2021-11-02Tweak loplugin:implicitboolconversion to allow some more bool -> sal_BoolStephan Bergmann
2021-11-01loplugin:unusedmember: Work around more cases not marking an enum as referencedStephan Bergmann