Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/vcl/source/gdi/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 15 kB image not shown  

Quelle  graph.cxx   Sprache: C

 
/* -*- 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 <sal/config.h>

#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <tools/fract.hxx>
#include <vcl/outdev.hxx>
#include <vcl/svapp.hxx>
#include <vcl/graph.hxx>
#include <vcl/image.hxx>
#include <impgraph.hxx>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <comphelper/servicehelper.hxx>
#include <graphic/UnoGraphic.hxx>
#include <vcl/GraphicExternalLink.hxx>

using namespace ::com::sun::star;

namespace
{

void ImplDrawDefault(OutputDevice& rOutDev, const OUString* pText,
                     vcl::Font* pFont, const BitmapEx* pBitmapEx,
                     const Point& rDestPt, const Size& rDestSize)
{
    sal_uInt16  nPixel = static_cast<sal_uInt16>(rOutDev.PixelToLogic( Size( 1, 1 ) ).Width());
    sal_uInt16  nPixelWidth = nPixel;
    Point       aPoint( rDestPt.X() + nPixelWidth, rDestPt.Y() + nPixelWidth );
    Size        aSize( rDestSize.Width() - ( nPixelWidth << 1 ), rDestSize.Height() - ( nPixelWidth << 1 ) );
    bool        bFilled = ( pBitmapEx != nullptr || pFont != nullptr );
    tools::Rectangle   aBorderRect( aPoint, aSize );

    rOutDev.Push();

    rOutDev.SetFillColor();

    // On the printer a black rectangle and on the screen one with 3D effect
    rOutDev.DrawBorder(aBorderRect);

    aPoint.AdjustX(nPixelWidth + 2*nPixel );
    aPoint.AdjustY(nPixelWidth + 2*nPixel );
    aSize.AdjustWidth( -(2*nPixelWidth + 4*nPixel) );
    aSize.AdjustHeight( -(2*nPixelWidth + 4*nPixel) );

    if( !aSize.IsEmpty() && pBitmapEx && !pBitmapEx->IsEmpty() )
    {
        Size aBitmapSize( rOutDev.PixelToLogic( pBitmapEx->GetSizePixel() ) );

        if( aSize.Height() > aBitmapSize.Height() && aSize.Width() > aBitmapSize.Width() )
        {
            rOutDev.DrawBitmapEx( aPoint, *pBitmapEx );
            aPoint.AdjustX(aBitmapSize.Width() + 2*nPixel );
            aSize.AdjustWidth( -(aBitmapSize.Width() + 2*nPixel) );
        }
    }

    if ( !aSize.IsEmpty() && pFont && pText && pText->getLength() && rOutDev.IsOutputEnabled() )
    {
        MapMode aMapMode( MapUnit::MapPoint );
        Size aSz = rOutDev.LogicToLogic( Size( 0, 12 ), &aMapMode, nullptr );
        tools::Long    nThreshold = aSz.Height() / 2;
        tools::Long    nStep = nThreshold / 3;

        if ( !nStep )
            nStep = aSz.Height() - nThreshold;

        for(;; aSz.AdjustHeight( -nStep ) )
        {
            pFont->SetFontSize( aSz );
            rOutDev.SetFont( *pFont );

            tools::Long nTextHeight = rOutDev.GetTextHeight();
            tools::Long nTextWidth = rOutDev.GetTextWidth( *pText );
            if ( nTextHeight )
            {
                // The approximation does not respect imprecisions caused
                // by word wraps
                tools::Long nLines = aSize.Height() / nTextHeight;
                tools::Long nWidth = aSize.Width() * nLines; // Approximation!!!

                if ( nTextWidth <= nWidth || aSz.Height() <= nThreshold )
                {
                    sal_Int32 nStart = 0;
                    sal_Int32 nLen = 0;

                    while( nStart < pText->getLength() && (*pText)[nStart] == ' ' )
                        nStart++;
                    while( nStart+nLen < pText->getLength() && (*pText)[nStart+nLen] != ' ' )
                        nLen++;
                    while( nStart < pText->getLength() && nLines-- )
                    {
                        sal_Int32 nNext = nLen;
                        do
                        {
                            while ( nStart+nNext < pText->getLength() && (*pText)[nStart+nNext] == ' ' )
                                nNext++;
                            while ( nStart+nNext < pText->getLength() && (*pText)[nStart+nNext] != ' ' )
                                nNext++;
                            nTextWidth = rOutDev.GetTextWidth( *pText, nStart, nNext );
                            if ( nTextWidth > aSize.Width() )
                                break;
                            nLen = nNext;
                        }
                        while ( nStart+nNext < pText->getLength() );

                        sal_Int32 n = nLen;
                        nTextWidth = rOutDev.GetTextWidth( *pText, nStart, n );
                        while( nTextWidth > aSize.Width() )
                            nTextWidth = rOutDev.GetTextWidth( *pText, nStart, --n );
                        rOutDev.DrawText( aPoint, *pText, nStart, n );

                        aPoint.AdjustY(nTextHeight );
                        nStart      = sal::static_int_cast<sal_uInt16>(nStart + nLen);
                        nLen        = nNext-nLen;
                        while( nStart < pText->getLength() && (*pText)[nStart] == ' ' )
                        {
                            nStart++;
                            nLen--;
                        }
                    }
                    break;
                }
            }
            else
                break;
        }
    }

    // If the default graphic does not have content, we draw a red rectangle
    if( !bFilled )
    {
        aBorderRect.AdjustLeft( 1 );
        aBorderRect.AdjustTop( 1 );
        aBorderRect.AdjustRight( -1 );
        aBorderRect.AdjustBottom( -1 );

        rOutDev.SetLineColor( COL_LIGHTRED );
        rOutDev.DrawLine( aBorderRect.TopLeft(), aBorderRect.BottomRight() );
        rOutDev.DrawLine( aBorderRect.TopRight(), aBorderRect.BottomLeft() );
    }

    rOutDev.Pop();
}

// end anonymous namespace

Graphic::Graphic()
    : mxImpGraphic(new ImpGraphic())
{
}

Graphic::Graphic(const Graphic& rGraphic)
{
    if( rGraphic.IsAnimated() )
        mxImpGraphic = std::make_shared<ImpGraphic>(*rGraphic.mxImpGraphic);
    else
        mxImpGraphic = rGraphic.mxImpGraphic;
}

Graphic::Graphic(Graphic&& rGraphic) noexcept
    : mxImpGraphic(std::move(rGraphic.mxImpGraphic))
{
}

Graphic::Graphic(std::shared_ptr<GfxLink> const & rGfxLink, sal_Int32 nPageIndex)
    : mxImpGraphic(new ImpGraphic(rGfxLink, nPageIndex))
{
}

Graphic::Graphic(GraphicExternalLink const & rGraphicExternalLink)
    : mxImpGraphic(new ImpGraphic(rGraphicExternalLink))
{
}

Graphic::Graphic(const BitmapEx& rBitmapEx)
    : mxImpGraphic(new ImpGraphic(rBitmapEx))
{
}

// We use XGraphic for passing toolbar images across app UNO aps
// and we need to be able to see and preserve 'stock' images too.
Graphic::Graphic(const Image& rImage)
    // FIXME: should really defer the BitmapEx load.
    : mxImpGraphic(new ImpGraphic(rImage.GetBitmapEx()))
{
    const OUString& aStock = rImage.GetStock();
    if (aStock.getLength())
        mxImpGraphic->setOriginURL("private:graphicrepository/" + aStock);
}

Graphic::Graphic(const std::shared_ptr<VectorGraphicData>& rVectorGraphicDataPtr)
    : mxImpGraphic(new ImpGraphic(rVectorGraphicDataPtr))
{
}

Graphic::Graphic(const Animation& rAnimation)
    : mxImpGraphic(new ImpGraphic(rAnimation))
{
}

Graphic::Graphic(const GDIMetaFile& rMetaFile)
    : mxImpGraphic(new ImpGraphic(rMetaFile))
{
}

Graphic::Graphic( const css::uno::Reference< css::graphic::XGraphic >& rxGraphic )
{
    const ::unographic::Graphic* pUnoGraphic = dynamic_cast<::unographic::Graphic*>(rxGraphic.get());
    const ::Graphic* pGraphic = pUnoGraphic ? &pUnoGraphic->GetGraphic() : nullptr;

    if( pGraphic )
    {
        if (pGraphic->IsAnimated())
            mxImpGraphic = std::make_shared<ImpGraphic>(*pGraphic->mxImpGraphic);
        else
            mxImpGraphic = pGraphic->mxImpGraphic;
    }
    else
        mxImpGraphic = std::make_shared<ImpGraphic>();
}

void Graphic::ImplTestRefCount()
{
    if (mxImpGraphic.use_count() > 1)
    {
        mxImpGraphic = std::make_shared<ImpGraphic>(*mxImpGraphic);
    }
}

bool Graphic::isAvailable() const
{
    return mxImpGraphic->isAvailable();
}

bool Graphic::makeAvailable()
{
    return mxImpGraphic->makeAvailable();
}

Graphic& Graphic::operator=( const Graphic& rGraphic )
{
    if( &rGraphic != this )
    {
        if( rGraphic.IsAnimated() )
            mxImpGraphic = std::make_shared<ImpGraphic>(*rGraphic.mxImpGraphic);
        else
            mxImpGraphic = rGraphic.mxImpGraphic;
    }

    return *this;
}

Graphic& Graphic::operator=(Graphic&& rGraphic) noexcept
{
    mxImpGraphic = std::move(rGraphic.mxImpGraphic);
    return *this;
}

bool Graphic::operator==( const Graphic& rGraphic ) const
{
    return (*mxImpGraphic == *rGraphic.mxImpGraphic);
}

bool Graphic::operator!=( const Graphic& rGraphic ) const
{
    return (*mxImpGraphic != *rGraphic.mxImpGraphic);
}

bool Graphic::IsNone() const
{
    return GraphicType::NONE == mxImpGraphic->getType();
}

void Graphic::Clear()
{
    mxImpGraphic = std::make_shared<ImpGraphic>();
}

GraphicType Graphic::GetType() const
{
    return mxImpGraphic->getType();
}

void Graphic::SetDefaultType()
{
    mxImpGraphic = std::make_shared<ImpGraphic>(true);
}

bool Graphic::IsSupportedGraphic() const
{
    return mxImpGraphic->isSupportedGraphic();
}

bool Graphic::IsTransparent() const
{
    return mxImpGraphic->isTransparent();
}

bool Graphic::IsAlpha() const
{
    return mxImpGraphic->isAlpha();
}

bool Graphic::IsAnimated() const
{
    return mxImpGraphic->isAnimated();
}

bool Graphic::IsEPS() const
{
    return mxImpGraphic->isEPS();
}

BitmapEx Graphic::GetBitmapEx(const GraphicConversionParameters& rParameters) const
{
    return mxImpGraphic->getBitmapEx(rParameters);
}

Animation Graphic::GetAnimation() const
{
    return mxImpGraphic->getAnimation();
}

const GDIMetaFile& Graphic::GetGDIMetaFile() const
{
    return mxImpGraphic->getGDIMetaFile();
}

const BitmapEx& Graphic::GetBitmapExRef() const
{
    return mxImpGraphic->getBitmapExRef();
}

uno::Reference<css::graphic::XGraphic> Graphic::GetXGraphic() const
{
    if (GetType() == GraphicType::NONE)
        return nullptr;

    rtl::Reference<unographic::Graphic> pUnoGraphic = new unographic::Graphic;
    pUnoGraphic->init(*this);
    return pUnoGraphic;
}

Size Graphic::GetPrefSize() const
{
    return mxImpGraphic->getPrefSize();
}

void Graphic::SetPrefSize( const Size& rPrefSize )
{
    ImplTestRefCount();
    mxImpGraphic->setPrefSize( rPrefSize );
}

MapMode Graphic::GetPrefMapMode() const
{
    return mxImpGraphic->getPrefMapMode();
}

void Graphic::SetPrefMapMode( const MapMode& rPrefMapMode )
{
    ImplTestRefCount();
    mxImpGraphic->setPrefMapMode( rPrefMapMode );
}

basegfx::B2DSize Graphic::GetPPUnit(const MapMode& unit) const
{
    const Size aGrfPrefMapModeSize(GetPrefSize());
    if (aGrfPrefMapModeSize.IsEmpty())
        return {};
    const Size aGrfPixelSize(GetSizePixel());
    basegfx::B2DHomMatrix toPixels = basegfx::utils::createScaleB2DHomMatrix(
        double(aGrfPixelSize.Width()) / aGrfPrefMapModeSize.Width(),
        double(aGrfPixelSize.Height()) / aGrfPrefMapModeSize.Height());
    toPixels *= OutputDevice::LogicToLogic(unit, GetPrefMapMode());
    return toPixels * basegfx::B2DSize(1, 1);
}

basegfx::B2DSize Graphic::GetPPI() const { return GetPPUnit(MapMode(MapUnit::MapInch)); }

basegfx::B2DSize Graphic::GetPPM() const
{
    return GetPPUnit(MapMode(MapUnit::MapMM, {}, { 1000, 1 }, { 1000, 1 }));
}

Size Graphic::GetSizePixel( const OutputDevice* pRefDevice ) const
{
    Size aRet;

    if( GraphicType::Bitmap == mxImpGraphic->getType() )
        aRet = mxImpGraphic->getSizePixel();
    else
        aRet = ( pRefDevice ? pRefDevice : Application::GetDefaultDevice() )->LogicToPixel( GetPrefSize(), GetPrefMapMode() );

    return aRet;
}

sal_uLong Graphic::GetSizeBytes() const
{
    return mxImpGraphic->getSizeBytes();
}

void Graphic::Draw(OutputDevice& rOutDev, const Point& rDestPt,
                   const Size& rDestSz) const
{
    if( GraphicType::Default == mxImpGraphic->getType() )
        ImplDrawDefault(rOutDev, nullptr, nullptr, nullptr, rDestPt, rDestSz);
    else
        mxImpGraphic->draw(rOutDev, rDestPt, rDestSz);
}

void Graphic::DrawEx(OutputDevice& rOutDev, const OUString& rText,
                     vcl::Font& rFont, const BitmapEx& rBitmap,
                     const Point& rDestPt, const Size& rDestSz)
{
    ImplDrawDefault(rOutDev, &rText, &rFont, &rBitmap, rDestPt, rDestSz);
}

void Graphic::StartAnimation(OutputDevice& rOutDev, const Point& rDestPt,
                             const Size& rDestSz, tools::Long nRendererId,
                             OutputDevice* pFirstFrameOutDev)
{
    ImplTestRefCount();
    mxImpGraphic->startAnimation(rOutDev, rDestPt, rDestSz, nRendererId, pFirstFrameOutDev);
}

void Graphic::StopAnimation( const OutputDevice* pOutDev, tools::Long nRendererId )
{
    ImplTestRefCount();
    mxImpGraphic->stopAnimation( pOutDev, nRendererId );
}

void Graphic::SetAnimationNotifyHdl( const Link<Animation*,void>& rLink )
{
    mxImpGraphic->setAnimationNotifyHdl( rLink );
}

Link<Animation*,void> Graphic::GetAnimationNotifyHdl() const
{
    return mxImpGraphic->getAnimationNotifyHdl();
}

sal_uInt32 Graphic::GetAnimationLoopCount() const
{
    return mxImpGraphic->getAnimationLoopCount();
}

void Graphic::SetDummyContext( bool value )
{
    mxImpGraphic->setDummyContext( value );
}

bool Graphic::IsDummyContext() const
{
    return mxImpGraphic->isDummyContext();
}

void Graphic::SetGfxLink( const std::shared_ptr<GfxLink>& rGfxLink )
{
    ImplTestRefCount();
    mxImpGraphic->setGfxLink(rGfxLink);
}

const std::shared_ptr<GfxLink> & Graphic::GetSharedGfxLink() const
{
    return mxImpGraphic->getSharedGfxLink();
}

GfxLink Graphic::GetGfxLink() const
{
    return mxImpGraphic->getGfxLink();
}

bool Graphic::IsGfxLink() const
{
    return mxImpGraphic->isGfxLink();
}

BitmapChecksum Graphic::GetChecksum() const
{
    return mxImpGraphic->getChecksum();
}

const std::shared_ptr<VectorGraphicData>& Graphic::getVectorGraphicData() const
{
    return mxImpGraphic->getVectorGraphicData();
}

sal_Int32 Graphic::getPageNumber() const
{
    return mxImpGraphic->getPageNumber();
}

const OUString & Graphic::getOriginURL() const
{
    if (mxImpGraphic)
    {
        return mxImpGraphic->getOriginURL();
    }
    return EMPTY_OUSTRING;
}

void Graphic::setOriginURL(OUString const & rOriginURL)
{
    if (mxImpGraphic)
    {
        mxImpGraphic->setOriginURL(rOriginURL);
    }
}

OString Graphic::getUniqueID() const
{
    OString aUniqueString;
    if (mxImpGraphic)
        aUniqueString = mxImpGraphic->getUniqueID();
    return aUniqueString;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=98 H=90 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.