LCOV - code coverage report
Current view: top level - chart2/source/view/main - OpenglShapeFactory.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 158 0.0 %
Date: 2014-04-11 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <svx/unoshape.hxx>
      21             : #include "OpenglShapeFactory.hxx"
      22             : #include "DummyXShape.hxx"
      23             : #include "ViewDefines.hxx"
      24             : #include "Stripe.hxx"
      25             : #include "CommonConverters.hxx"
      26             : #include "macros.hxx"
      27             : #include "PropertyMapper.hxx"
      28             : #include <comphelper/InlineContainer.hxx>
      29             : #include <com/sun/star/beans/XPropertySet.hpp>
      30             : #include <com/sun/star/drawing/CircleKind.hpp>
      31             : #include <com/sun/star/drawing/DoubleSequence.hpp>
      32             : #include <com/sun/star/drawing/FlagSequence.hpp>
      33             : #include <com/sun/star/drawing/FillStyle.hpp>
      34             : #include <com/sun/star/drawing/LineStyle.hpp>
      35             : #include <com/sun/star/drawing/NormalsKind.hpp>
      36             : #include <com/sun/star/drawing/PointSequence.hpp>
      37             : #include <com/sun/star/drawing/PolygonKind.hpp>
      38             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      39             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      40             : #include <com/sun/star/drawing/ShadeMode.hpp>
      41             : #include <com/sun/star/drawing/TextFitToSizeType.hpp>
      42             : #include <com/sun/star/drawing/TextureProjectionMode.hpp>
      43             : #include <com/sun/star/text/XText.hpp>
      44             : #include <com/sun/star/uno/Any.hxx>
      45             : 
      46             : #include <editeng/unoprnms.hxx>
      47             : #include <rtl/math.hxx>
      48             : #include <svx/svdocirc.hxx>
      49             : #include <svx/svdopath.hxx>
      50             : 
      51             : #include <basegfx/point/b2dpoint.hxx>
      52             : #include <basegfx/matrix/b3dhommatrix.hxx>
      53             : 
      54             : #include "RelativeSizeHelper.hxx"
      55             : 
      56             : #include <algorithm>
      57             : #include <iostream>
      58             : using namespace std;
      59             : 
      60             : 
      61             : using namespace ::com::sun::star;
      62             : using ::com::sun::star::uno::Reference;
      63             : 
      64             : namespace chart
      65             : {
      66             : 
      67             : extern "C" {
      68           0 :     SAL_DLLPUBLIC_EXPORT opengl::OpenglShapeFactory* getOpenglShapeFactory()
      69           0 :                               {    return new opengl::OpenglShapeFactory();}
      70             :     }
      71             : 
      72             : 
      73             : using dummy::DummyXShape;
      74             : using dummy::DummyXShapes;
      75             : using dummy::DummyCylinder;
      76             : using dummy::DummyRectangle;
      77             : using dummy::DummyPyramid;
      78             : using dummy::DummyCone;
      79             : 
      80             : namespace opengl {
      81             : 
      82             : namespace {
      83             : 
      84           0 : uno::Reference< drawing::XShapes > getChartShape(
      85             :     const uno::Reference< drawing::XDrawPage>& xDrawPage )
      86             : {
      87           0 :     uno::Reference< drawing::XShapes > xRet;
      88           0 :     uno::Reference< drawing::XShapes > xShapes( xDrawPage, uno::UNO_QUERY );
      89           0 :     if( xShapes.is() )
      90             :     {
      91           0 :         sal_Int32 nCount = xShapes->getCount();
      92           0 :         uno::Reference< drawing::XShape > xShape;
      93           0 :         for( sal_Int32 nN = nCount; nN--; )
      94             :         {
      95           0 :             if( xShapes->getByIndex( nN ) >>= xShape )
      96             :             {
      97             : 
      98           0 :                 OUString aRet;
      99             : 
     100           0 :                 uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
     101           0 :                 xProp->getPropertyValue( UNO_NAME_MISC_OBJ_NAME ) >>= aRet;
     102           0 :                 if( aRet.equals("com.sun.star.chart2.shapes") )
     103             :                 {
     104           0 :                     xRet = dynamic_cast<SvxDummyShapeContainer*>(xShape.get())->getWrappedShape();
     105           0 :                     break;
     106           0 :                 }
     107             :             }
     108           0 :         }
     109             :     }
     110           0 :     return xRet;
     111             : }
     112             : 
     113             : }
     114             : 
     115           0 : uno::Reference< drawing::XShapes > OpenglShapeFactory::getOrCreateChartRootShape(
     116             :     const uno::Reference< drawing::XDrawPage>& xDrawPage )
     117             : {
     118           0 :     uno::Reference< drawing::XShapes > xRet( getChartShape( xDrawPage ) );
     119           0 :     if( !xRet.is()  )
     120             :     {
     121             :         //create the root shape
     122             :         SAL_WARN("chart2.opengl", "getOrCreateChartRootShape");
     123             : 
     124           0 :         uno::Reference< drawing::XShape > xTarget (m_xShapeFactory->createInstance(
     125           0 :                 "com.sun.star.drawing.OpenGLObject" ), uno::UNO_QUERY );
     126           0 :         dummy::DummyChart *pChart = new dummy::DummyChart(xTarget);
     127           0 :         SvxDummyShapeContainer* pContainer = new SvxDummyShapeContainer(pChart);
     128           0 :         pContainer->setSize(awt::Size(0,0));
     129           0 :         xRet = pChart;
     130           0 :         xDrawPage->add(xTarget);
     131           0 :         xDrawPage->add(pContainer);
     132             :     }
     133           0 :     return xRet;
     134             : }
     135             : 
     136           0 : void OpenglShapeFactory::setPageSize( uno::Reference < drawing::XShapes > xChartShapes, const awt::Size& rSize )
     137             : {
     138           0 :     uno::Reference< drawing::XShape > xShape(xChartShapes, uno::UNO_QUERY_THROW);
     139           0 :     xShape->setSize(rSize);
     140           0 : }
     141             : 
     142             : //  methods for 3D shape creation
     143             : 
     144             : uno::Reference<drawing::XShape>
     145           0 :         OpenglShapeFactory::createCube(
     146             :             const uno::Reference<drawing::XShapes>& xTarget
     147             :             , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
     148             :             , sal_Int32
     149             :             , const uno::Reference< beans::XPropertySet >& xSourceProp
     150             :             , const tPropertyNameMap& rPropertyNameMap
     151             :             , bool )
     152             : {
     153             :     dummy::DummyCube* pCube = new dummy::DummyCube(rPosition, rSize,
     154             :             xSourceProp,
     155           0 :             rPropertyNameMap);
     156           0 :     xTarget->add(pCube);
     157           0 :     return pCube;
     158             : }
     159             : 
     160             : uno::Reference<drawing::XShape>
     161           0 :         OpenglShapeFactory::createCylinder(
     162             :             const uno::Reference<drawing::XShapes>& xTarget
     163             :           , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
     164             :           , sal_Int32 )
     165             : {
     166           0 :     dummy::DummyCylinder* pCylinder = new dummy::DummyCylinder( rPosition, rSize );
     167           0 :     xTarget->add(pCylinder);
     168           0 :     return pCylinder;
     169             : }
     170             : 
     171             : uno::Reference<drawing::XShape>
     172           0 :         OpenglShapeFactory::createPyramid(
     173             :             const uno::Reference<drawing::XShapes>& xTarget
     174             :           , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
     175             :           , double, bool
     176             :           , const uno::Reference< beans::XPropertySet >& xSourceProp
     177             :           , const tPropertyNameMap& rPropertyNameMap )
     178             : {
     179             :     dummy::DummyPyramid* pPyramid = new dummy::DummyPyramid(rPosition, rSize,
     180           0 :             xSourceProp, rPropertyNameMap );
     181           0 :     xTarget->add(pPyramid);
     182           0 :     return pPyramid;
     183             : }
     184             : 
     185             : uno::Reference<drawing::XShape>
     186           0 :         OpenglShapeFactory::createCone(
     187             :             const uno::Reference<drawing::XShapes>& xTarget
     188             :           , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
     189             :           , double, sal_Int32 )
     190             : {
     191           0 :     dummy::DummyCone* pCone = new dummy::DummyCone(rPosition, rSize);
     192           0 :     xTarget->add(pCone);
     193           0 :     return pCone;
     194             : }
     195             : 
     196             : uno::Reference< drawing::XShape >
     197           0 :         OpenglShapeFactory::createPieSegment2D(
     198             :                     const uno::Reference< drawing::XShapes >& xTarget
     199             :                     , double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree
     200             :                     , double fUnitCircleInnerRadius, double fUnitCircleOuterRadius
     201             :                     , const drawing::Direction3D& rOffset
     202             :                     , const drawing::HomogenMatrix& rUnitCircleToScene )
     203             : {
     204             :     dummy::DummyPieSegment2D* pSegment = new dummy::DummyPieSegment2D(fUnitCircleStartAngleDegree,
     205             :             fUnitCircleWidthAngleDegree, fUnitCircleInnerRadius, fUnitCircleOuterRadius,
     206           0 :             rOffset, rUnitCircleToScene);
     207           0 :     xTarget->add(pSegment);
     208           0 :     return pSegment;
     209             : }
     210             : 
     211             : uno::Reference< drawing::XShape >
     212           0 :         OpenglShapeFactory::createPieSegment(
     213             :                     const uno::Reference< drawing::XShapes >& xTarget
     214             :                     , double, double
     215             :                     , double, double
     216             :                     , const drawing::Direction3D& rOffset
     217             :                     , const drawing::HomogenMatrix& rUnitCircleToScene
     218             :                     , double )
     219             : {
     220             :     dummy::DummyPieSegment* pSegment = new dummy::DummyPieSegment(
     221           0 :             rOffset, rUnitCircleToScene);
     222             : 
     223           0 :     xTarget->add(pSegment);
     224           0 :     return pSegment;
     225             : }
     226             : 
     227             : uno::Reference< drawing::XShape >
     228           0 :         OpenglShapeFactory::createStripe( const uno::Reference< drawing::XShapes >& xTarget
     229             :                     , const Stripe& rStripe
     230             :                     , const uno::Reference< beans::XPropertySet >& xSourceProp
     231             :                     , const tPropertyNameMap& rPropertyNameMap
     232             :                     , sal_Bool
     233             :                     , short
     234             :                     , bool )
     235             : {
     236             :     dummy::DummyStripe* pStripe = new dummy::DummyStripe(rStripe,
     237           0 :             xSourceProp, rPropertyNameMap);
     238           0 :     xTarget->add(pStripe);
     239           0 :     return pStripe;
     240             : }
     241             : 
     242             : uno::Reference< drawing::XShape >
     243           0 :         OpenglShapeFactory::createArea3D( const uno::Reference< drawing::XShapes >& xTarget
     244             :                     , const drawing::PolyPolygonShape3D& rPolyPolygon
     245             :                     , double )
     246             : {
     247           0 :     dummy::DummyArea3D* pArea = new dummy::DummyArea3D(rPolyPolygon);
     248           0 :     xTarget->add(pArea);
     249           0 :     return pArea;
     250             : }
     251             : 
     252             : uno::Reference< drawing::XShape >
     253           0 :         OpenglShapeFactory::createArea2D( const uno::Reference< drawing::XShapes >& xTarget
     254             :                     , const drawing::PolyPolygonShape3D& rPolyPolygon )
     255             : {
     256           0 :     dummy::DummyArea2D* pArea = new dummy::DummyArea2D(PolyToPointSequence(rPolyPolygon));
     257           0 :     xTarget->add(pArea);
     258           0 :     return pArea;
     259             : }
     260             : 
     261             : uno::Reference< drawing::XShape >
     262           0 :         OpenglShapeFactory::createSymbol2D(
     263             :                       const uno::Reference< drawing::XShapes >& xTarget
     264             :                     , const drawing::Position3D& rPosition
     265             :                     , const drawing::Direction3D& rSize
     266             :                     , sal_Int32 nStandardSymbol
     267             :                     , sal_Int32
     268             :                     , sal_Int32 nFillColor )
     269             : {
     270             :     dummy::DummySymbol2D* pSymbol = new dummy::DummySymbol2D(rPosition, rSize,
     271           0 :             nStandardSymbol, nFillColor);
     272           0 :     xTarget->add(pSymbol);
     273           0 :     return pSymbol;
     274             : }
     275             : 
     276             : uno::Reference< drawing::XShape >
     277           0 :         OpenglShapeFactory::createGraphic2D(
     278             :                       const uno::Reference< drawing::XShapes >& xTarget
     279             :                     , const drawing::Position3D& rPosition
     280             :                     , const drawing::Direction3D& rSize
     281             :                     , const uno::Reference< graphic::XGraphic >& xGraphic )
     282             : {
     283             :     dummy::DummyGraphic2D* pGraphic = new dummy::DummyGraphic2D(rPosition, rSize,
     284           0 :             xGraphic);
     285           0 :     xTarget->add(pGraphic);
     286           0 :     return pGraphic;
     287             : }
     288             : 
     289             : uno::Reference< drawing::XShapes >
     290           0 :         OpenglShapeFactory::createGroup2D( const uno::Reference< drawing::XShapes >& xTarget
     291             :         , const OUString& aName)
     292             : {
     293           0 :     dummy::DummyGroup2D* pNewShape = new dummy::DummyGroup2D(aName);
     294           0 :     xTarget->add(pNewShape);
     295           0 :     return pNewShape;
     296             : }
     297             : 
     298             : uno::Reference< drawing::XShapes >
     299           0 :         OpenglShapeFactory::createGroup3D( const uno::Reference< drawing::XShapes >& xTarget
     300             :         , const OUString& aName )
     301             : {
     302           0 :     dummy::DummyGroup3D* pNewShape = new dummy::DummyGroup3D(aName);
     303           0 :     xTarget->add(pNewShape);
     304           0 :     return pNewShape;
     305             : }
     306             : 
     307             : uno::Reference< drawing::XShape >
     308           0 :         OpenglShapeFactory::createCircle2D( const uno::Reference< drawing::XShapes >& xTarget
     309             :                     , const drawing::Position3D& rPosition
     310             :                     , const drawing::Direction3D& rSize )
     311             : {
     312             :     drawing::Position3D aCenterPosition(
     313           0 :             rPosition.PositionX - (rSize.DirectionX / 2.0),
     314           0 :             rPosition.PositionY - (rSize.DirectionY / 2.0),
     315           0 :             rPosition.PositionZ );
     316             :     dummy::DummyCircle* pCircle = new dummy::DummyCircle(Position3DToAWTPoint( aCenterPosition ),
     317           0 :             Direction3DToAWTSize( rSize ));
     318           0 :     xTarget->add(pCircle);
     319           0 :     return pCircle;
     320             : }
     321             : 
     322             : uno::Reference< drawing::XShape >
     323           0 :     OpenglShapeFactory::createCircle( const uno::Reference< drawing::XShapes >& xTarget
     324             :                     , const awt::Size& rSize
     325             :                     , const awt::Point& rPosition )
     326             : {
     327           0 :     dummy::DummyCircle* pCircle = new dummy::DummyCircle(rPosition, rSize);
     328           0 :     xTarget->add(pCircle);
     329           0 :     return pCircle;
     330             : }
     331             : 
     332             : uno::Reference< drawing::XShape >
     333           0 :         OpenglShapeFactory::createLine3D( const uno::Reference< drawing::XShapes >& xTarget
     334             :                     , const drawing::PolyPolygonShape3D& rPoints
     335             :                     , const VLineProperties& rLineProperties )
     336             : {
     337           0 :     dummy::DummyLine3D* pLine = new dummy::DummyLine3D(rPoints, rLineProperties);
     338           0 :     xTarget->add(pLine);
     339           0 :     return pLine;
     340             : }
     341             : 
     342             : uno::Reference< drawing::XShape >
     343           0 :         OpenglShapeFactory::createLine2D( const uno::Reference< drawing::XShapes >& xTarget
     344             :                     , const drawing::PointSequenceSequence& rPoints
     345             :                     , const VLineProperties* pLineProperties )
     346             : {
     347           0 :     dummy::DummyLine2D* pLine = new dummy::DummyLine2D(rPoints, pLineProperties);
     348           0 :     xTarget->add(pLine);
     349             : 
     350           0 :     return pLine;
     351             : }
     352             : 
     353             : uno::Reference< drawing::XShape >
     354           0 :     OpenglShapeFactory::createLine ( const uno::Reference< drawing::XShapes >& xTarget,
     355             :             const awt::Size& rSize, const awt::Point& rPosition )
     356             : {
     357           0 :     dummy::DummyLine2D* pLine = new dummy::DummyLine2D(rSize, rPosition);
     358           0 :     xTarget->add(pLine);
     359           0 :     return pLine;
     360             : }
     361             : 
     362           0 : uno::Reference< drawing::XShape > OpenglShapeFactory::createInvisibleRectangle(
     363             :             const uno::Reference< drawing::XShapes >& xTarget
     364             :             , const awt::Size& rSize )
     365             : {
     366           0 :     dummy::DummyRectangle* pRectangle = new dummy::DummyRectangle(rSize);
     367           0 :     pRectangle->setPropertyValue("Invisible", uno::makeAny(sal_True));
     368           0 :     xTarget->add(pRectangle);
     369           0 :     return pRectangle;
     370             : }
     371             : 
     372           0 : uno::Reference< drawing::XShape > OpenglShapeFactory::createRectangle(
     373             :     const uno::Reference< drawing::XShapes >& xTarget,
     374             :     const awt::Size& rSize,
     375             :     const awt::Point& rPosition,
     376             :     const tNameSequence& rPropNames,
     377             :     const tAnySequence& rPropValues,
     378             :     StackPosition /*ePos*/ )
     379             : {
     380             :     dummy::DummyRectangle* pRectangle = new dummy::DummyRectangle(rSize, rPosition,
     381           0 :             rPropNames, rPropValues);
     382             : 
     383             :     // TODO : Honor stack position.
     384           0 :     xTarget->add(pRectangle);
     385           0 :     return pRectangle;
     386             : }
     387             : 
     388             : uno::Reference< drawing::XShape >
     389           0 :     OpenglShapeFactory::createRectangle(
     390             :             const uno::Reference<
     391             :             drawing::XShapes >& xTarget)
     392             : {
     393           0 :     dummy::DummyRectangle* pRectangle = new dummy::DummyRectangle();
     394           0 :     xTarget->add(pRectangle);
     395           0 :     return pRectangle;
     396             : }
     397             : 
     398             : uno::Reference< drawing::XShape >
     399           0 :         OpenglShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget
     400             :                     , const OUString& rText
     401             :                     , const tNameSequence& rPropNames
     402             :                     , const tAnySequence& rPropValues
     403             :                     , const uno::Any& rATransformation )
     404             : {
     405             :     dummy::DummyText* pText = new dummy::DummyText( rText, rPropNames, rPropValues,
     406           0 :             rATransformation, xTarget, 0 );
     407           0 :     return pText;
     408             : }
     409             : 
     410             : 
     411             : uno::Reference< drawing::XShape >
     412           0 :         OpenglShapeFactory::createText( const uno::Reference< drawing::XShapes >& xTarget,
     413             :                 const awt::Size& , const awt::Point& rPos,
     414             :                 uno::Sequence< uno::Reference< chart2::XFormattedString > >& rFormattedString,
     415             :                 const uno::Reference< beans::XPropertySet > & xTextProperties,
     416             :                 double nRotation, const OUString& rName)
     417             : {
     418           0 :     tPropertyNameValueMap aValueMap;
     419             :     //fill line-, fill- and paragraph-properties into the ValueMap
     420             :     {
     421           0 :         tMakePropertyNameMap aNameMap = PropertyMapper::getPropertyNameMapForParagraphProperties();
     422           0 :         aNameMap( PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
     423             : 
     424           0 :         PropertyMapper::getValueMap( aValueMap, aNameMap, xTextProperties );
     425             :     }
     426             : 
     427             :     //fill some more shape properties into the ValueMap
     428             :     {
     429           0 :         drawing::TextHorizontalAdjust eHorizontalAdjust = drawing::TextHorizontalAdjust_CENTER;
     430           0 :         drawing::TextVerticalAdjust eVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
     431             : 
     432           0 :         aValueMap.insert( tPropertyNameValueMap::value_type( "TextHorizontalAdjust", uno::makeAny(eHorizontalAdjust) ) ); // drawing::TextHorizontalAdjust
     433           0 :         aValueMap.insert( tPropertyNameValueMap::value_type( "TextVerticalAdjust", uno::makeAny(eVerticalAdjust) ) ); //drawing::TextVerticalAdjust
     434           0 :         aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowHeight", uno::makeAny(sal_True) ) ); // sal_Bool
     435           0 :         aValueMap.insert( tPropertyNameValueMap::value_type( "TextAutoGrowWidth", uno::makeAny(sal_True) ) ); // sal_Bool
     436             : 
     437             :     }
     438             : 
     439             :     //set global title properties
     440           0 :     tNameSequence aPropNames;
     441           0 :     tAnySequence aPropValues;
     442           0 :     PropertyMapper::getMultiPropertyListsFromValueMap( aPropNames, aPropValues, aValueMap );
     443             : 
     444           0 :     OUString aString = rFormattedString[0]->getString();
     445             : 
     446           0 :     sal_Int32 nXPos = rPos.X;
     447           0 :     sal_Int32 nYPos = rPos.Y;
     448           0 :     ::basegfx::B2DHomMatrix aM;
     449           0 :     aM.rotate( -nRotation*F_PI/180.0 );//#i78696#->#i80521#
     450           0 :     aM.translate( nXPos, nYPos );
     451             : 
     452             :     dummy::DummyText* pText = new dummy::DummyText(aString, aPropNames, aPropValues,
     453           0 :             uno::makeAny(B2DHomMatrixToHomogenMatrix3(aM)), xTarget, nRotation);
     454           0 :     pText->setName(rName);
     455           0 :     return pText;
     456             : }
     457             : 
     458           0 : void OpenglShapeFactory::render(uno::Reference< drawing::XShapes > xRootShape)
     459             : {
     460           0 :     dummy::DummyChart* pChart = dynamic_cast<dummy::DummyChart*>(xRootShape.get());
     461             :     assert(pChart);
     462           0 :     pChart->render();
     463           0 : }
     464             : 
     465           0 : void OpenglShapeFactory::clearPage(uno::Reference< drawing::XShapes > xRootShape)
     466             : {
     467           0 :     dummy::DummyChart* pChart = dynamic_cast<dummy::DummyChart*>(xRootShape.get());
     468             :     assert(pChart);
     469           0 :     pChart->clear();
     470           0 : }
     471             : 
     472             : } //namespace dummy
     473             : 
     474           0 : } //namespace chart
     475             : 
     476             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10