LCOV - code coverage report
Current view: top level - cppcanvas/source/mtfrenderer - mtftools.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 174 0.0 %
Date: 2014-04-14 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           0 :             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 bool bOffsetting( !rOffset.equalZero() );
     130           0 :             const bool bScaling( pScaling &&
     131           0 :                                  pScaling->getX() != 1.0 &&
     132           0 :                                  pScaling->getY() != 1.0 );
     133           0 :             const bool bRotation( pRotation &&
     134           0 :                                   *pRotation != 0.0 );
     135             : 
     136           0 :             if( !bOffsetting && !bScaling && !bRotation )
     137           0 :                 return false; // nothing to do
     138             : 
     139           0 :             if( rOutdevState.clip.count() )
     140             :             {
     141             :                 // general polygon case
     142             : 
     143           0 :                 ::basegfx::B2DPolyPolygon aLocalClip( rOutdevState.clip );
     144           0 :                 ::basegfx::B2DHomMatrix   aTransform;
     145             : 
     146           0 :                 if( bOffsetting )
     147           0 :                     aTransform.translate( -rOffset.getX(),
     148           0 :                                           -rOffset.getY() );
     149           0 :                 if( bScaling )
     150           0 :                     aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
     151             : 
     152           0 :                 if( bRotation )
     153           0 :                     aTransform.rotate( - *pRotation );
     154             : 
     155           0 :                 aLocalClip.transform( aTransform );
     156             : 
     157           0 :                 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     158           0 :                     rCanvas->getUNOCanvas()->getDevice(),
     159           0 :                     aLocalClip );
     160             : 
     161           0 :                 return true;
     162             :             }
     163           0 :             else if( !rOutdevState.clipRect.IsEmpty() )
     164             :             {
     165             :                 // simple rect case
     166             : 
     167           0 :                 const ::Rectangle aLocalClipRect( rOutdevState.clipRect );
     168             : 
     169           0 :                 if( bRotation )
     170             :                 {
     171             :                     // rotation involved - convert to polygon first,
     172             :                     // then transform that
     173             :                     ::basegfx::B2DPolygon aLocalClip(
     174             :                         ::basegfx::tools::createPolygonFromRect(
     175             :                                 ::basegfx::B2DRectangle(
     176           0 :                                     (double)(aLocalClipRect.Left()),
     177           0 :                                     (double)(aLocalClipRect.Top()),
     178           0 :                                     (double)(aLocalClipRect.Right()),
     179           0 :                                     (double)(aLocalClipRect.Bottom()) ) ) );
     180           0 :                     ::basegfx::B2DHomMatrix aTransform;
     181             : 
     182           0 :                     if( bOffsetting )
     183           0 :                         aTransform.translate( -rOffset.getX(),
     184           0 :                                               -rOffset.getY() );
     185           0 :                     if( bScaling )
     186           0 :                         aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
     187             : 
     188           0 :                     aTransform.rotate( - *pRotation );
     189             : 
     190           0 :                     aLocalClip.transform( aTransform );
     191             : 
     192           0 :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     193           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     194           0 :                         ::basegfx::B2DPolyPolygon( aLocalClip ) );
     195             :                 }
     196           0 :                 else if( bScaling )
     197             :                 {
     198             :                     // scale and offset - do it on the fly, have to
     199             :                     // convert to float anyway.
     200           0 :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     201           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     202             :                         ::basegfx::B2DPolyPolygon(
     203             :                             ::basegfx::tools::createPolygonFromRect(
     204             :                                 ::basegfx::B2DRectangle(
     205           0 :                                     (double)(aLocalClipRect.Left() - rOffset.getX())/pScaling->getX(),
     206           0 :                                     (double)(aLocalClipRect.Top() - rOffset.getY())/pScaling->getY(),
     207           0 :                                     (double)(aLocalClipRect.Right() - rOffset.getX())/pScaling->getX(),
     208           0 :                                     (double)(aLocalClipRect.Bottom() - rOffset.getY())/pScaling->getY() ) ) ) );
     209             :                 }
     210             :                 else
     211             :                 {
     212             :                     // offset only - do it on the fly, have to convert
     213             :                     // to float anyway.
     214           0 :                     o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
     215           0 :                         rCanvas->getUNOCanvas()->getDevice(),
     216             :                         ::basegfx::B2DPolyPolygon(
     217             :                             ::basegfx::tools::createPolygonFromRect(
     218           0 :                                 ::basegfx::B2DRectangle( aLocalClipRect.Left() - rOffset.getX(),
     219           0 :                                                          aLocalClipRect.Top() - rOffset.getY(),
     220           0 :                                                          aLocalClipRect.Right() - rOffset.getX(),
     221           0 :                                                          aLocalClipRect.Bottom() - rOffset.getY() ) ) ) );
     222             :                 }
     223             : 
     224           0 :                 return true;
     225             :             }
     226             : 
     227             :             // empty clip, nothing to do
     228           0 :             return false;
     229             :         }
     230             : 
     231             :         // create overline/underline/strikeout line info struct
     232           0 :         TextLineInfo createTextLineInfo( const ::VirtualDevice&                     rVDev,
     233             :                                          const ::cppcanvas::internal::OutDevState&  rState )
     234             :         {
     235           0 :             const bool bOldMode( rVDev.IsMapModeEnabled() );
     236             : 
     237             :             // #i68512# Force metric regeneration with mapmode enabled
     238             :             // (prolly OutDev bug)
     239           0 :             rVDev.GetFontMetric();
     240             : 
     241             :             // will restore map mode below
     242           0 :             const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( false );
     243             : 
     244           0 :             const ::FontMetric aMetric = rVDev.GetFontMetric();
     245             : 
     246             :             TextLineInfo aTextInfo(
     247           0 :                 (aMetric.GetDescent() + 2) / 4.0,
     248           0 :                 ((aMetric.GetIntLeading() + 1.5) / 3.0),
     249           0 :                 (aMetric.GetIntLeading() / 2.0) - aMetric.GetAscent(),
     250           0 :                 aMetric.GetDescent() / 2.0,
     251           0 :                 (aMetric.GetIntLeading() - aMetric.GetAscent()) / 3.0,
     252             :                 rState.textOverlineStyle,
     253             :                 rState.textUnderlineStyle,
     254           0 :                 rState.textStrikeoutStyle );
     255             : 
     256           0 :             const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( bOldMode );
     257             : 
     258           0 :             return aTextInfo;
     259             :         }
     260             : 
     261             :         namespace
     262             :         {
     263           0 :             void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
     264             :                              const ::basegfx::B2DPoint& rStartPos,
     265             :                              const double               nX1,
     266             :                              const double               nY1,
     267             :                              const double               nX2,
     268             :                              const double               nY2 )
     269             :             {
     270           0 :                 const double x( rStartPos.getX() );
     271           0 :                 const double y( rStartPos.getY() );
     272             : 
     273             :                 o_rPoly.append(
     274             :                     ::basegfx::tools::createPolygonFromRect(
     275           0 :                         ::basegfx::B2DRectangle( x + nX1, y + nY1, x + nX2, y + nY2 ) ) );
     276           0 :             }
     277             : 
     278           0 :             void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
     279             :                              const double               nX1,
     280             :                              const double               nY1,
     281             :                              const double               nX2,
     282             :                              const double               nY2 )
     283             :             {
     284             :                 o_rPoly.append(
     285             :                     ::basegfx::tools::createPolygonFromRect(
     286           0 :                         ::basegfx::B2DRectangle( nX1, nY1, nX2, nY2 ) ) );
     287           0 :             }
     288             : 
     289           0 :             void appendDashes( ::basegfx::B2DPolyPolygon&   o_rPoly,
     290             :                                const double                 nX,
     291             :                                const double                 nY,
     292             :                                const double                 nLineWidth,
     293             :                                const double                 nLineHeight,
     294             :                                const double                 nDashWidth,
     295             :                                const double                 nDashSkip )
     296             :             {
     297             :                 const sal_Int32 nNumLoops(
     298             :                     static_cast< sal_Int32 >(
     299             :                         ::std::max( 1.0,
     300           0 :                                     nLineWidth / nDashSkip ) + .5) );
     301             : 
     302           0 :                 double x = nX;
     303           0 :                 for( sal_Int32 i=0; i<nNumLoops; ++i )
     304             :                 {
     305             :                     appendRect( o_rPoly,
     306             :                                 x,              nY,
     307           0 :                                 x + nDashWidth, nY + nLineHeight );
     308             : 
     309           0 :                     x += nDashSkip;
     310             :                 }
     311           0 :             }
     312             :         }
     313             : 
     314             :         // create line actions for text such as underline and
     315             :         // strikeout
     316           0 :         ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const ::basegfx::B2DPoint rStartPos,
     317             :                                                               const double&             rLineWidth,
     318             :                                                               const TextLineInfo&       rTextLineInfo )
     319             :         {
     320             :             // fill the polypolygon with all text lines
     321           0 :             ::basegfx::B2DPolyPolygon aTextLinesPolyPoly;
     322             : 
     323           0 :             switch( rTextLineInfo.mnOverlineStyle )
     324             :             {
     325             :                 case UNDERLINE_NONE:          // nothing to do
     326             :                     // FALLTHROUGH intended
     327             :                 case UNDERLINE_DONTKNOW:
     328           0 :                     break;
     329             : 
     330             :                 case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
     331             :                     // FALLTHROUGH intended
     332             :                 case UNDERLINE_WAVE:          // TODO(F3): NYI
     333             :                     // FALLTHROUGH intended
     334             :                 case UNDERLINE_SINGLE:
     335             :                     appendRect(
     336             :                         aTextLinesPolyPoly,
     337             :                         rStartPos,
     338             :                         0,
     339             :                         rTextLineInfo.mnOverlineOffset,
     340             :                         rLineWidth,
     341           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
     342           0 :                     break;
     343             : 
     344             :                 case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
     345             :                     // FALLTHROUGH intended
     346             :                 case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
     347             :                     // FALLTHROUGH intended
     348             :                 case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
     349             :                     // FALLTHROUGH intended
     350             :                 case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
     351             :                     // FALLTHROUGH intended
     352             :                 case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
     353             :                     // FALLTHROUGH intended
     354             :                 case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
     355             :                     // FALLTHROUGH intended
     356             :                 case UNDERLINE_BOLD:
     357             :                     appendRect(
     358             :                         aTextLinesPolyPoly,
     359             :                         rStartPos,
     360             :                         0,
     361             :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight,
     362             :                         rLineWidth,
     363           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
     364           0 :                     break;
     365             : 
     366             :                 case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
     367             :                     // FALLTHROUGH intended
     368             :                 case UNDERLINE_DOUBLE:
     369             :                     appendRect(
     370             :                         aTextLinesPolyPoly,
     371             :                         rStartPos,
     372             :                         0,
     373           0 :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight * 2.0 ,
     374             :                         rLineWidth,
     375           0 :                         rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight );
     376             : 
     377             :                     appendRect(
     378             :                         aTextLinesPolyPoly,
     379             :                         rStartPos,
     380             :                         0,
     381             :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight,
     382             :                         rLineWidth,
     383           0 :                         rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight * 2.0 );
     384           0 :                     break;
     385             : 
     386             :                 case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
     387             :                     // FALLTHROUGH intended
     388             :                 case UNDERLINE_DOTTED:
     389             :                     appendDashes(
     390             :                         aTextLinesPolyPoly,
     391             :                         rStartPos.getX(),
     392           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     393             :                         rLineWidth,
     394             :                         rTextLineInfo.mnOverlineHeight,
     395             :                         rTextLineInfo.mnOverlineHeight,
     396           0 :                         2*rTextLineInfo.mnOverlineHeight );
     397           0 :                     break;
     398             : 
     399             :                 case UNDERLINE_DASHDOT:       // TODO(F3): NYI
     400             :                     // FALLTHROUGH intended
     401             :                 case UNDERLINE_DASH:
     402             :                     appendDashes(
     403             :                         aTextLinesPolyPoly,
     404             :                         rStartPos.getX(),
     405           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     406             :                         rLineWidth,
     407             :                         rTextLineInfo.mnOverlineHeight,
     408             :                         3*rTextLineInfo.mnOverlineHeight,
     409           0 :                         6*rTextLineInfo.mnOverlineHeight );
     410           0 :                     break;
     411             : 
     412             :                 case UNDERLINE_LONGDASH:
     413             :                     appendDashes(
     414             :                         aTextLinesPolyPoly,
     415             :                         rStartPos.getX(),
     416           0 :                         rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
     417             :                         rLineWidth,
     418             :                         rTextLineInfo.mnOverlineHeight,
     419             :                         6*rTextLineInfo.mnOverlineHeight,
     420           0 :                         12*rTextLineInfo.mnOverlineHeight );
     421           0 :                     break;
     422             : 
     423             :                 default:
     424           0 :                     ENSURE_OR_THROW( false,
     425             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected overline case" );
     426             :             }
     427             : 
     428           0 :             switch( rTextLineInfo.mnUnderlineStyle )
     429             :             {
     430             :                 case UNDERLINE_NONE:          // nothing to do
     431             :                     // FALLTHROUGH intended
     432             :                 case UNDERLINE_DONTKNOW:
     433           0 :                     break;
     434             : 
     435             :                 case UNDERLINE_SMALLWAVE:     // TODO(F3): NYI
     436             :                     // FALLTHROUGH intended
     437             :                 case UNDERLINE_WAVE:          // TODO(F3): NYI
     438             :                     // FALLTHROUGH intended
     439             :                 case UNDERLINE_SINGLE:
     440             :                     appendRect(
     441             :                         aTextLinesPolyPoly,
     442             :                         rStartPos,
     443             :                         0,
     444             :                         rTextLineInfo.mnUnderlineOffset,
     445             :                         rLineWidth,
     446           0 :                         rTextLineInfo.mnUnderlineOffset + rTextLineInfo.mnLineHeight );
     447           0 :                     break;
     448             : 
     449             :                 case UNDERLINE_BOLDDOTTED:    // TODO(F3): NYI
     450             :                     // FALLTHROUGH intended
     451             :                 case UNDERLINE_BOLDDASH:      // TODO(F3): NYI
     452             :                     // FALLTHROUGH intended
     453             :                 case UNDERLINE_BOLDLONGDASH:  // TODO(F3): NYI
     454             :                     // FALLTHROUGH intended
     455             :                 case UNDERLINE_BOLDDASHDOT:   // TODO(F3): NYI
     456             :                     // FALLTHROUGH intended
     457             :                 case UNDERLINE_BOLDDASHDOTDOT:// TODO(F3): NYI
     458             :                     // FALLTHROUGH intended
     459             :                 case UNDERLINE_BOLDWAVE:      // TODO(F3): NYI
     460             :                     // FALLTHROUGH intended
     461             :                 case UNDERLINE_BOLD:
     462             :                     appendRect(
     463             :                         aTextLinesPolyPoly,
     464             :                         rStartPos,
     465             :                         0,
     466             :                         rTextLineInfo.mnUnderlineOffset,
     467             :                         rLineWidth,
     468           0 :                         rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight );
     469           0 :                     break;
     470             : 
     471             :                 case UNDERLINE_DOUBLEWAVE:    // TODO(F3): NYI
     472             :                     // FALLTHROUGH intended
     473             :                 case UNDERLINE_DOUBLE:
     474             :                     appendRect(
     475             :                         aTextLinesPolyPoly,
     476             :                         rStartPos,
     477             :                         0,
     478             :                         rTextLineInfo.mnUnderlineOffset - rTextLineInfo.mnLineHeight,
     479             :                         rLineWidth,
     480           0 :                         rTextLineInfo.mnUnderlineOffset );
     481             : 
     482             :                     appendRect(
     483             :                         aTextLinesPolyPoly,
     484             :                         rStartPos,
     485             :                         0,
     486           0 :                         rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight,
     487             :                         rLineWidth,
     488           0 :                         rTextLineInfo.mnUnderlineOffset + 3*rTextLineInfo.mnLineHeight );
     489           0 :                     break;
     490             : 
     491             :                 case UNDERLINE_DASHDOTDOT:    // TODO(F3): NYI
     492             :                     // FALLTHROUGH intended
     493             :                 case UNDERLINE_DOTTED:
     494             :                     appendDashes(
     495             :                         aTextLinesPolyPoly,
     496             :                         rStartPos.getX(),
     497           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     498             :                         rLineWidth,
     499             :                         rTextLineInfo.mnLineHeight,
     500             :                         rTextLineInfo.mnLineHeight,
     501           0 :                         2*rTextLineInfo.mnLineHeight );
     502           0 :                     break;
     503             : 
     504             :                 case UNDERLINE_DASHDOT:       // TODO(F3): NYI
     505             :                     // FALLTHROUGH intended
     506             :                 case UNDERLINE_DASH:
     507             :                     appendDashes(
     508             :                         aTextLinesPolyPoly,
     509             :                         rStartPos.getX(),
     510           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     511             :                         rLineWidth,
     512             :                         rTextLineInfo.mnLineHeight,
     513             :                         3*rTextLineInfo.mnLineHeight,
     514           0 :                         6*rTextLineInfo.mnLineHeight );
     515           0 :                     break;
     516             : 
     517             :                 case UNDERLINE_LONGDASH:
     518             :                     appendDashes(
     519             :                         aTextLinesPolyPoly,
     520             :                         rStartPos.getX(),
     521           0 :                         rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
     522             :                         rLineWidth,
     523             :                         rTextLineInfo.mnLineHeight,
     524             :                         6*rTextLineInfo.mnLineHeight,
     525           0 :                         12*rTextLineInfo.mnLineHeight );
     526           0 :                     break;
     527             : 
     528             :                 default:
     529           0 :                     ENSURE_OR_THROW( false,
     530             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected underline case" );
     531             :             }
     532             : 
     533           0 :             switch( rTextLineInfo.mnStrikeoutStyle )
     534             :             {
     535             :                 case STRIKEOUT_NONE:    // nothing to do
     536             :                     // FALLTHROUGH intended
     537             :                 case STRIKEOUT_DONTKNOW:
     538           0 :                     break;
     539             : 
     540             :                 case STRIKEOUT_SLASH:   // TODO(Q1): we should handle this in the text layer
     541             :                     // FALLTHROUGH intended
     542             :                 case STRIKEOUT_X:
     543           0 :                     break;
     544             : 
     545             :                 case STRIKEOUT_SINGLE:
     546             :                     appendRect(
     547             :                         aTextLinesPolyPoly,
     548             :                         rStartPos,
     549             :                         0,
     550             :                         rTextLineInfo.mnStrikeoutOffset,
     551             :                         rLineWidth,
     552           0 :                         rTextLineInfo.mnStrikeoutOffset + rTextLineInfo.mnLineHeight );
     553           0 :                     break;
     554             : 
     555             :                 case STRIKEOUT_BOLD:
     556             :                     appendRect(
     557             :                         aTextLinesPolyPoly,
     558             :                         rStartPos,
     559             :                         0,
     560             :                         rTextLineInfo.mnStrikeoutOffset,
     561             :                         rLineWidth,
     562           0 :                         rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight );
     563           0 :                     break;
     564             : 
     565             :                 case STRIKEOUT_DOUBLE:
     566             :                     appendRect(
     567             :                         aTextLinesPolyPoly,
     568             :                         rStartPos,
     569             :                         0,
     570             :                         rTextLineInfo.mnStrikeoutOffset - rTextLineInfo.mnLineHeight,
     571             :                         rLineWidth,
     572           0 :                         rTextLineInfo.mnStrikeoutOffset );
     573             : 
     574             :                     appendRect(
     575             :                         aTextLinesPolyPoly,
     576             :                         rStartPos,
     577             :                         0,
     578           0 :                         rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight,
     579             :                         rLineWidth,
     580           0 :                         rTextLineInfo.mnStrikeoutOffset + 3*rTextLineInfo.mnLineHeight );
     581           0 :                     break;
     582             : 
     583             :                 default:
     584           0 :                     ENSURE_OR_THROW( false,
     585             :                                       "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected strikeout case" );
     586             :             }
     587             : 
     588           0 :             return aTextLinesPolyPoly;
     589             :         }
     590             : 
     591           0 :         ::basegfx::B2DRange calcDevicePixelBounds( const ::basegfx::B2DRange&       rBounds,
     592             :                                                    const rendering::ViewState&      viewState,
     593             :                                                    const rendering::RenderState&    renderState )
     594             :         {
     595           0 :             ::basegfx::B2DHomMatrix aTransform;
     596             :             ::canvas::tools::mergeViewAndRenderTransform( aTransform,
     597             :                                                           viewState,
     598           0 :                                                           renderState );
     599             : 
     600           0 :             ::basegfx::B2DRange aTransformedBounds;
     601             :             return ::canvas::tools::calcTransformedRectBounds( aTransformedBounds,
     602             :                                                                rBounds,
     603           0 :                                                                aTransform );
     604             :         }
     605             : 
     606             :         // create line actions for text such as underline and
     607             :         // strikeout
     608           0 :         ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const double&         rStartOffset,
     609             :                                                               const double&         rLineWidth,
     610             :                                                               const TextLineInfo&   rTextLineInfo )
     611             :         {
     612             :             return createTextLinesPolyPolygon(
     613             :                 ::basegfx::B2DPoint( rStartOffset,
     614             :                                      0.0 ),
     615             :                 rLineWidth,
     616           0 :                 rTextLineInfo );
     617             :         }
     618             :     }
     619             : }
     620             : 
     621             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10