LCOV - code coverage report
Current view: top level - libreoffice/cppcanvas/source/mtfrenderer - mtftools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 165 0.0 %
Date: 2012-12-27 Functions: 0 12 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             : 
      21             : #include <canvas/debug.hxx>
      22             : #include <tools/diagnose_ex.h>
      23             : #include <canvas/verbosetrace.hxx>
      24             : #include <com/sun/star/rendering/RenderState.hpp>
      25             : #include <com/sun/star/rendering/XCanvas.hpp>
      26             : #include <basegfx/numeric/ftools.hxx>
      27             : #include <basegfx/tools/canvastools.hxx>
      28             : #include <basegfx/polygon/b2dpolygontools.hxx>
      29             : #include <basegfx/polygon/b2dpolygon.hxx>
      30             : #include <basegfx/range/b2drectangle.hxx>
      31             : #include <basegfx/vector/b2dvector.hxx>
      32             : #include <canvas/canvastools.hxx>
      33             : #include <vcl/gdimtf.hxx>
      34             : #include <vcl/metaact.hxx>
      35             : #include <vcl/virdev.hxx>
      36             : #include <vcl/metric.hxx>
      37             : #include <tools/poly.hxx>
      38             : #include "mtftools.hxx"
      39             : #include "outdevstate.hxx"
      40             : #include "polypolyaction.hxx"
      41             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      42             : 
      43             : 
      44             : 
      45             : using namespace ::com::sun::star;
      46             : 
      47             : namespace cppcanvas
      48             : {
      49             :     namespace tools
      50             :     {
      51           0 :         void initRenderState( rendering::RenderState&                   renderState,
      52             :                               const ::cppcanvas::internal::OutDevState& outdevState )
      53             :         {
      54           0 :             ::canvas::tools::initRenderState( renderState );
      55             :             ::canvas::tools::setRenderStateTransform( renderState,
      56           0 :                                                       outdevState.transform );
      57           0 :             renderState.Clip = outdevState.xClipPoly;
      58           0 :         }
      59             : 
      60           0 :         ::Size getBaselineOffset( const ::cppcanvas::internal::OutDevState& outdevState,
      61             :                                   const VirtualDevice&                      rVDev )
      62             :         {
      63           0 :             const ::FontMetric& aMetric = rVDev.GetFontMetric();
      64             : 
      65             :             // calc offset for text output, the XCanvas always renders
      66             :             // baseline offset.
      67           0 :             switch( outdevState.textReferencePoint )
      68             :             {
      69             :                 case ALIGN_TOP:
      70             :                     return ::Size( 0,
      71           0 :                                    aMetric.GetIntLeading() + aMetric.GetAscent() );
      72             : 
      73             :                 default:
      74           0 :                     ENSURE_OR_THROW( false,
      75             :                                       "tools::getBaselineOffset(): Unexpected TextAlign value" );
      76             :                     // FALLTHROUGH intended (to calm compiler warning - case won't happen)
      77             :                 case ALIGN_BASELINE:
      78           0 :                     return ::Size( 0, 0 );
      79             : 
      80             :                 case ALIGN_BOTTOM:
      81             :                     return ::Size( 0,
      82           0 :                                    -aMetric.GetDescent() );
      83             : 
      84           0 :             }
      85             :         }
      86             : 
      87           0 :         ::basegfx::B2DHomMatrix& calcLogic2PixelLinearTransform( ::basegfx::B2DHomMatrix&   o_rMatrix,
      88             :                                                                  const VirtualDevice&       rVDev )
      89             :         {
      90             :             // select size value in the middle of the available range,
      91             :             // to have headroom both when map mode scales up, and when
      92             :             // it scales down.
      93             :             const ::Size aSizeLogic( 0x00010000L,
      94           0 :                                      0x00010000L );
      95             : 
      96           0 :             const ::Size aSizePixel( rVDev.LogicToPixel( aSizeLogic ) );
      97             : 
      98             :             o_rMatrix = basegfx::tools::createScaleB2DHomMatrix(
      99           0 :                 aSizePixel.Width() / (double)aSizeLogic.Width(),
     100           0 :                 aSizePixel.Height() / (double)aSizeLogic.Height() );
     101             : 
     102           0 :             return o_rMatrix;
     103             :         }
     104             : 
     105           0 :         ::basegfx::B2DHomMatrix& calcLogic2PixelAffineTransform( ::basegfx::B2DHomMatrix&   o_rMatrix,
     106             :                                                                  const VirtualDevice&       rVDev )
     107             :         {
     108             :             // retrieves scale
     109           0 :             calcLogic2PixelLinearTransform(o_rMatrix, rVDev);
     110             : 
     111             :             // translate according to curr map mode/pref map mode offset
     112           0 :             const ::Point  aEmptyPoint;
     113             :             const ::Point& rTranslatedPoint(
     114           0 :                 rVDev.LogicToPixel( aEmptyPoint ));
     115             : 
     116           0 :             o_rMatrix.translate(rTranslatedPoint.X(),
     117           0 :                                 rTranslatedPoint.Y());
     118             : 
     119           0 :             return o_rMatrix;
     120             :         }
     121             : 
     122           0 :         bool modifyClip( rendering::RenderState&                            o_rRenderState,
     123             :                          const struct ::cppcanvas::internal::OutDevState&   rOutdevState,
     124             :                          const CanvasSharedPtr&                             rCanvas,
     125             :                          const ::basegfx::B2DPoint&                         rOffset,
     126             :                          const ::basegfx::B2DVector*                        pScaling,
     127             :                          const double*                                      pRotation )
     128             :         {
     129           0 :             const ::Point aEmptyPoint;
     130             : 
     131           0 :             const bool bOffsetting( !rOffset.equalZero() );
     132             :             const bool bScaling( pScaling &&
     133           0 :                                  pScaling->getX() != 1.0 &&
     134           0 :                                  pScaling->getY() != 1.0 );
     135             :             const bool bRotation( pRotation &&
     136           0 :                                   *pRotation != 0.0 );
     137             : 
     138           0 :             if( !bOffsetting && !bScaling && !bRotation )
     139           0 :                 return false; // nothing to do
     140             : 
     141           0 :             if( rOutdevState.clip.count() )
     142             :             {
     143             :                 // general polygon case
     144             : 
     145           0 :                 ::basegfx::B2DPolyPolygon aLocalClip( rOutdevState.clip );
     146           0 :                 ::basegfx::B2DHomMatrix   aTransform;
     147             : 
     148           0 :                 if( bOffsetting )
     149           0 :                     aTransform.translate( -rOffset.getX(),
     150           0 :                                           -rOffset.getY() );
     151           0 :                 if( bScaling )
     152           0 :                     aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
     153             : 
     154           0 :                 if( bRotation )
     155           0 :                     aTransform.rotate( - *pRotation );
     156             : 
     157           0 :                 aLocalClip.transform( aTransform );
     158             : 
     159             :                 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     160           0 :                     rCanvas->getUNOCanvas()->getDevice(),
     161           0 :                     aLocalClip );
     162             : 
     163           0 :                 return true;
     164             :             }
     165           0 :             else if( !rOutdevState.clipRect.IsEmpty() )
     166             :             {
     167             :                 // simple rect case
     168             : 
     169           0 :                 const ::Rectangle aLocalClipRect( rOutdevState.clipRect );
     170             : 
     171           0 :                 if( bRotation )
     172             :                 {
     173             :                     // rotation involved - convert to polygon first,
     174             :                     // then transform that
     175             :                     ::basegfx::B2DPolygon aLocalClip(
     176             :                         ::basegfx::tools::createPolygonFromRect(
     177             :                                 ::basegfx::B2DRectangle(
     178           0 :                                     (double)(aLocalClipRect.Left()),
     179           0 :                                     (double)(aLocalClipRect.Top()),
     180           0 :                                     (double)(aLocalClipRect.Right()),
     181           0 :                                     (double)(aLocalClipRect.Bottom()) ) ) );
     182           0 :                     ::basegfx::B2DHomMatrix aTransform;
     183             : 
     184           0 :                     if( bOffsetting )
     185           0 :                         aTransform.translate( -rOffset.getX(),
     186           0 :                                               -rOffset.getY() );
     187           0 :                     if( bScaling )
     188           0 :                         aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
     189             : 
     190           0 :                     aTransform.rotate( - *pRotation );
     191             : 
     192           0 :                     aLocalClip.transform( aTransform );
     193             : 
     194             :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     195           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     196           0 :                         ::basegfx::B2DPolyPolygon( aLocalClip ) );
     197             :                 }
     198           0 :                 else if( bScaling )
     199             :                 {
     200             :                     // scale and offset - do it on the fly, have to
     201             :                     // convert to float anyway.
     202             :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     203           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     204             :                         ::basegfx::B2DPolyPolygon(
     205             :                             ::basegfx::tools::createPolygonFromRect(
     206             :                                 ::basegfx::B2DRectangle(
     207           0 :                                     (double)(aLocalClipRect.Left() - rOffset.getX())/pScaling->getX(),
     208           0 :                                     (double)(aLocalClipRect.Top() - rOffset.getY())/pScaling->getY(),
     209           0 :                                     (double)(aLocalClipRect.Right() - rOffset.getX())/pScaling->getX(),
     210           0 :                                     (double)(aLocalClipRect.Bottom() - rOffset.getY())/pScaling->getY() ) ) ) );
     211             :                 }
     212             :                 else
     213             :                 {
     214             :                     // offset only - do it on the fly, have to convert
     215             :                     // to float anyway.
     216             :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     217           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     218             :                         ::basegfx::B2DPolyPolygon(
     219             :                             ::basegfx::tools::createPolygonFromRect(
     220           0 :                                 ::basegfx::B2DRectangle( aLocalClipRect.Left() - rOffset.getX(),
     221           0 :                                                          aLocalClipRect.Top() - rOffset.getY(),
     222           0 :                                                          aLocalClipRect.Right() - rOffset.getX(),
     223           0 :                                                          aLocalClipRect.Bottom() - rOffset.getY() ) ) ) );
     224             :                 }
     225             : 
     226           0 :                 return true;
     227             :             }
     228             : 
     229             :             // empty clip, nothing to do
     230           0 :             return false;
     231             :         }
     232             : 
     233             :         // create overline/underline/strikeout line info struct
     234           0 :         TextLineInfo createTextLineInfo( const ::VirtualDevice&                     rVDev,
     235             :                                          const ::cppcanvas::internal::OutDevState&  rState )
     236             :         {
     237           0 :             const sal_Bool bOldMode( rVDev.IsMapModeEnabled() );
     238             : 
     239             :             // #i68512# Force metric regeneration with mapmode enabled
     240             :             // (prolly OutDev bug)
     241           0 :             rVDev.GetFontMetric();
     242             : 
     243             :             // will restore map mode below
     244           0 :             const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( sal_False );
     245             : 
     246           0 :             const ::FontMetric aMetric = rVDev.GetFontMetric();
     247             : 
     248             :             TextLineInfo aTextInfo(
     249           0 :                 (aMetric.GetDescent() + 2) / 4.0,
     250           0 :                 ((aMetric.GetIntLeading() + 1.5) / 3.0),
     251           0 :                 (aMetric.GetIntLeading() / 2.0) - aMetric.GetAscent(),
     252           0 :                 aMetric.GetDescent() / 2.0,
     253           0 :                 (aMetric.GetIntLeading() - aMetric.GetAscent()) / 3.0,
     254             :                 rState.textOverlineStyle,
     255             :                 rState.textUnderlineStyle,
     256           0 :                 rState.textStrikeoutStyle );
     257             : 
     258           0 :             const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( bOldMode );
     259             : 
     260           0 :             return aTextInfo;
     261             :         }
     262             : 
     263             :         namespace
     264             :         {
     265           0 :             void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
     266             :                              const ::basegfx::B2DPoint& rStartPos,
     267             :                              const double               nX1,
     268             :                              const double               nY1,
     269             :                              const double               nX2,
     270             :                              const double               nY2 )
     271             :             {
     272           0 :                 const double x( rStartPos.getX() );
     273           0 :                 const double y( rStartPos.getY() );
     274             : 
     275             :                 o_rPoly.append(
     276             :                     ::basegfx::tools::createPolygonFromRect(
     277           0 :                         ::basegfx::B2DRectangle( x + nX1, y + nY1, x + nX2, y + nY2 ) ) );
     278           0 :             }
     279             : 
     280           0 :             void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
     281             :                              const double               nX1,
     282             :                              const double               nY1,
     283             :                              const double               nX2,
     284             :                              const double               nY2 )
     285             :             {
     286             :                 o_rPoly.append(
     287             :                     ::basegfx::tools::createPolygonFromRect(
     288           0 :                         ::basegfx::B2DRectangle( nX1, nY1, nX2, nY2 ) ) );
     289           0 :             }
     290             : 
     291           0 :             void appendDashes( ::basegfx::B2DPolyPolygon&   o_rPoly,
     292             :                                const double                 nX,
     293             :                                const double                 nY,
     294             :                                const double                 nLineWidth,
     295             :                                const double                 nLineHeight,
     296             :                                const double                 nDashWidth,
     297             :                                const double                 nDashSkip )
     298             :             {
     299             :                 const sal_Int32 nNumLoops(
     300             :                     static_cast< sal_Int32 >(
     301             :                         ::std::max( 1.0,
     302           0 :                                     nLineWidth / nDashSkip ) + .5) );
     303             : 
     304           0 :                 double x = nX;
     305           0 :                 for( sal_Int32 i=0; i<nNumLoops; ++i )
     306             :                 {
     307             :                     appendRect( o_rPoly,
     308             :                                 x,              nY,
     309           0 :                                 x + nDashWidth, nY + nLineHeight );
     310             : 
     311           0 :                     x += nDashSkip;
     312             :                 }
     313           0 :             }
     314             :         }
     315             : 
     316             :         // create line actions for text such as underline and
     317             :         // strikeout
     318           0 :         ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const ::basegfx::B2DPoint rStartPos,
     319             :                                                               const double&             rLineWidth,
     320             :                                                               const TextLineInfo&       rTextLineInfo )
     321             :         {
     322             :             // fill the polypolygon with all text lines
     323           0 :             ::basegfx::B2DPolyPolygon aTextLinesPolyPoly;
     324             : 
     325           0 :             switch( rTextLineInfo.mnOverlineStyle )
     326             :             {
     327             :                 case UNDERLINE_NONE:          // nothing to do
     328             :                     // FALLTHROUGH intended
     329             :                 case UNDERLINE_DONTKNOW:
     330           0 :                     break;
     331             : 
     332             :                 case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
     333             :                     // FALLTHROUGH intended
     334             :                 case UNDERLINE_WAVE:          // TODO(F3): NYI
     335             :                     // FALLTHROUGH intended
     336             :                 case UNDERLINE_SINGLE:
     337             :                     appendRect(
     338             :                         aTextLinesPolyPoly,
     339             :                         rStartPos,
     340             :                         0,
     341             :                         rTextLineInfo.mnOverlineOffset,
     342             :                         rLineWidth,
     343           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
     344           0 :                     break;
     345             : 
     346             :                 case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
     347             :                     // FALLTHROUGH intended
     348             :                 case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
     349             :                     // FALLTHROUGH intended
     350             :                 case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
     351             :                     // FALLTHROUGH intended
     352             :                 case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
     353             :                     // FALLTHROUGH intended
     354             :                 case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
     355             :                     // FALLTHROUGH intended
     356             :                 case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
     357             :                     // FALLTHROUGH intended
     358             :                 case UNDERLINE_BOLD:
     359             :                     appendRect(
     360             :                         aTextLinesPolyPoly,
     361             :                         rStartPos,
     362             :                         0,
     363             :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight,
     364             :                         rLineWidth,
     365           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
     366           0 :                     break;
     367             : 
     368             :                 case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
     369             :                     // FALLTHROUGH intended
     370             :                 case UNDERLINE_DOUBLE:
     371             :                     appendRect(
     372             :                         aTextLinesPolyPoly,
     373             :                         rStartPos,
     374             :                         0,
     375             :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight * 2.0 ,
     376             :                         rLineWidth,
     377           0 :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight );
     378             : 
     379             :                     appendRect(
     380             :                         aTextLinesPolyPoly,
     381             :                         rStartPos,
     382             :                         0,
     383             :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight,
     384             :                         rLineWidth,
     385           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight * 2.0 );
     386           0 :                     break;
     387             : 
     388             :                 case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
     389             :                     // FALLTHROUGH intended
     390             :                 case UNDERLINE_DOTTED:
     391             :                     appendDashes(
     392             :                         aTextLinesPolyPoly,
     393             :                         rStartPos.getX(),
     394           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     395             :                         rLineWidth,
     396             :                         rTextLineInfo.mnOverlineHeight,
     397             :                         rTextLineInfo.mnOverlineHeight,
     398           0 :                         2*rTextLineInfo.mnOverlineHeight );
     399           0 :                     break;
     400             : 
     401             :                 case UNDERLINE_DASHDOT:       // TODO(F3): NYI
     402             :                     // FALLTHROUGH intended
     403             :                 case UNDERLINE_DASH:
     404             :                     appendDashes(
     405             :                         aTextLinesPolyPoly,
     406             :                         rStartPos.getX(),
     407           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     408             :                         rLineWidth,
     409             :                         rTextLineInfo.mnOverlineHeight,
     410             :                         3*rTextLineInfo.mnOverlineHeight,
     411           0 :                         6*rTextLineInfo.mnOverlineHeight );
     412           0 :                     break;
     413             : 
     414             :                 case UNDERLINE_LONGDASH:
     415             :                     appendDashes(
     416             :                         aTextLinesPolyPoly,
     417             :                         rStartPos.getX(),
     418           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     419             :                         rLineWidth,
     420             :                         rTextLineInfo.mnOverlineHeight,
     421             :                         6*rTextLineInfo.mnOverlineHeight,
     422           0 :                         12*rTextLineInfo.mnOverlineHeight );
     423           0 :                     break;
     424             : 
     425             :                 default:
     426           0 :                     ENSURE_OR_THROW( false,
     427             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected overline case" );
     428             :             }
     429             : 
     430           0 :             switch( rTextLineInfo.mnUnderlineStyle )
     431             :             {
     432             :                 case UNDERLINE_NONE:          // nothing to do
     433             :                     // FALLTHROUGH intended
     434             :                 case UNDERLINE_DONTKNOW:
     435           0 :                     break;
     436             : 
     437             :                 case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
     438             :                     // FALLTHROUGH intended
     439             :                 case UNDERLINE_WAVE:          // TODO(F3): NYI
     440             :                     // FALLTHROUGH intended
     441             :                 case UNDERLINE_SINGLE:
     442             :                     appendRect(
     443             :                         aTextLinesPolyPoly,
     444             :                         rStartPos,
     445             :                         0,
     446             :                         rTextLineInfo.mnUnderlineOffset,
     447             :                         rLineWidth,
     448           0 :                         rTextLineInfo.mnUnderlineOffset + rTextLineInfo.mnLineHeight );
     449           0 :                     break;
     450             : 
     451             :                 case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
     452             :                     // FALLTHROUGH intended
     453             :                 case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
     454             :                     // FALLTHROUGH intended
     455             :                 case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
     456             :                     // FALLTHROUGH intended
     457             :                 case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
     458             :                     // FALLTHROUGH intended
     459             :                 case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
     460             :                     // FALLTHROUGH intended
     461             :                 case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
     462             :                     // FALLTHROUGH intended
     463             :                 case UNDERLINE_BOLD:
     464             :                     appendRect(
     465             :                         aTextLinesPolyPoly,
     466             :                         rStartPos,
     467             :                         0,
     468             :                         rTextLineInfo.mnUnderlineOffset,
     469             :                         rLineWidth,
     470           0 :                         rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight );
     471           0 :                     break;
     472             : 
     473             :                 case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
     474             :                     // FALLTHROUGH intended
     475             :                 case UNDERLINE_DOUBLE:
     476             :                     appendRect(
     477             :                         aTextLinesPolyPoly,
     478             :                         rStartPos,
     479             :                         0,
     480             :                         rTextLineInfo.mnUnderlineOffset - rTextLineInfo.mnLineHeight,
     481             :                         rLineWidth,
     482           0 :                         rTextLineInfo.mnUnderlineOffset );
     483             : 
     484             :                     appendRect(
     485             :                         aTextLinesPolyPoly,
     486             :                         rStartPos,
     487             :                         0,
     488             :                         rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight,
     489             :                         rLineWidth,
     490           0 :                         rTextLineInfo.mnUnderlineOffset + 3*rTextLineInfo.mnLineHeight );
     491           0 :                     break;
     492             : 
     493             :                 case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
     494             :                     // FALLTHROUGH intended
     495             :                 case UNDERLINE_DOTTED:
     496             :                     appendDashes(
     497             :                         aTextLinesPolyPoly,
     498             :                         rStartPos.getX(),
     499           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     500             :                         rLineWidth,
     501             :                         rTextLineInfo.mnLineHeight,
     502             :                         rTextLineInfo.mnLineHeight,
     503           0 :                         2*rTextLineInfo.mnLineHeight );
     504           0 :                     break;
     505             : 
     506             :                 case UNDERLINE_DASHDOT:       // TODO(F3): NYI
     507             :                     // FALLTHROUGH intended
     508             :                 case UNDERLINE_DASH:
     509             :                     appendDashes(
     510             :                         aTextLinesPolyPoly,
     511             :                         rStartPos.getX(),
     512           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     513             :                         rLineWidth,
     514             :                         rTextLineInfo.mnLineHeight,
     515             :                         3*rTextLineInfo.mnLineHeight,
     516           0 :                         6*rTextLineInfo.mnLineHeight );
     517           0 :                     break;
     518             : 
     519             :                 case UNDERLINE_LONGDASH:
     520             :                     appendDashes(
     521             :                         aTextLinesPolyPoly,
     522             :                         rStartPos.getX(),
     523           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     524             :                         rLineWidth,
     525             :                         rTextLineInfo.mnLineHeight,
     526             :                         6*rTextLineInfo.mnLineHeight,
     527           0 :                         12*rTextLineInfo.mnLineHeight );
     528           0 :                     break;
     529             : 
     530             :                 default:
     531           0 :                     ENSURE_OR_THROW( false,
     532             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected underline case" );
     533             :             }
     534             : 
     535           0 :             switch( rTextLineInfo.mnStrikeoutStyle )
     536             :             {
     537             :                 case STRIKEOUT_NONE:    // nothing to do
     538             :                     // FALLTHROUGH intended
     539             :                 case STRIKEOUT_DONTKNOW:
     540           0 :                     break;
     541             : 
     542             :                 case STRIKEOUT_SLASH:   // TODO(Q1): we should handle this in the text layer
     543             :                     // FALLTHROUGH intended
     544             :                 case STRIKEOUT_X:
     545           0 :                     break;
     546             : 
     547             :                 case STRIKEOUT_SINGLE:
     548             :                     appendRect(
     549             :                         aTextLinesPolyPoly,
     550             :                         rStartPos,
     551             :                         0,
     552             :                         rTextLineInfo.mnStrikeoutOffset,
     553             :                         rLineWidth,
     554           0 :                         rTextLineInfo.mnStrikeoutOffset + rTextLineInfo.mnLineHeight );
     555           0 :                     break;
     556             : 
     557             :                 case STRIKEOUT_BOLD:
     558             :                     appendRect(
     559             :                         aTextLinesPolyPoly,
     560             :                         rStartPos,
     561             :                         0,
     562             :                         rTextLineInfo.mnStrikeoutOffset,
     563             :                         rLineWidth,
     564           0 :                         rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight );
     565           0 :                     break;
     566             : 
     567             :                 case STRIKEOUT_DOUBLE:
     568             :                     appendRect(
     569             :                         aTextLinesPolyPoly,
     570             :                         rStartPos,
     571             :                         0,
     572             :                         rTextLineInfo.mnStrikeoutOffset - rTextLineInfo.mnLineHeight,
     573             :                         rLineWidth,
     574           0 :                         rTextLineInfo.mnStrikeoutOffset );
     575             : 
     576             :                     appendRect(
     577             :                         aTextLinesPolyPoly,
     578             :                         rStartPos,
     579             :                         0,
     580             :                         rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight,
     581             :                         rLineWidth,
     582           0 :                         rTextLineInfo.mnStrikeoutOffset + 3*rTextLineInfo.mnLineHeight );
     583           0 :                     break;
     584             : 
     585             :                 default:
     586           0 :                     ENSURE_OR_THROW( false,
     587             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected strikeout case" );
     588             :             }
     589             : 
     590           0 :             return aTextLinesPolyPoly;
     591             :         }
     592             : 
     593           0 :         ::basegfx::B2DRange calcDevicePixelBounds( const ::basegfx::B2DRange&       rBounds,
     594             :                                                    const rendering::ViewState&      viewState,
     595             :                                                    const rendering::RenderState&    renderState )
     596             :         {
     597           0 :             ::basegfx::B2DHomMatrix aTransform;
     598             :             ::canvas::tools::mergeViewAndRenderTransform( aTransform,
     599             :                                                           viewState,
     600           0 :                                                           renderState );
     601             : 
     602           0 :             ::basegfx::B2DRange aTransformedBounds;
     603             :             return ::canvas::tools::calcTransformedRectBounds( aTransformedBounds,
     604             :                                                                rBounds,
     605           0 :                                                                aTransform );
     606             :         }
     607             : 
     608             :         // create line actions for text such as underline and
     609             :         // strikeout
     610           0 :         ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const double&         rStartOffset,
     611             :                                                               const double&         rLineWidth,
     612             :                                                               const TextLineInfo&   rTextLineInfo )
     613             :         {
     614             :             return createTextLinesPolyPolygon(
     615             :                 ::basegfx::B2DPoint( rStartOffset,
     616             :                                      0.0 ),
     617             :                 rLineWidth,
     618           0 :                 rTextLineInfo );
     619             :         }
     620             :     }
     621             : }
     622             : 
     623             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10