LCOV - code coverage report
Current view: top level - vcl/inc - sallayout.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 41 49 83.7 %
Date: 2014-11-03 Functions: 34 41 82.9 %
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             : #ifndef INCLUDED_VCL_INC_SALLAYOUT_HXX
      21             : #define INCLUDED_VCL_INC_SALLAYOUT_HXX
      22             : 
      23             : #include <iostream>
      24             : #include <list>
      25             : #include <vector>
      26             : 
      27             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      28             : #include <i18nlangtag/languagetag.hxx>
      29             : #include <tools/gen.hxx>
      30             : #include <vcl/dllapi.h>
      31             : #include <vcl/vclenum.hxx> // for typedef sal_UCS4
      32             : #include <vcl/devicecoordinate.hxx>
      33             : 
      34             : #ifndef _TOOLS_LANG_HXX
      35             : typedef unsigned short LanguageType;
      36             : #endif
      37             : 
      38             : #include "magic.h"
      39             : #include "salglyphid.hxx"
      40             : 
      41             : class SalGraphics;
      42             : class PhysicalFontFace;
      43             : 
      44             : 
      45             : // used for managing runs e.g. for BiDi, glyph and script fallback
      46     4337704 : class VCL_PLUGIN_PUBLIC ImplLayoutRuns
      47             : {
      48             : private:
      49             :     int                 mnRunIndex;
      50             :     std::vector<int>    maRuns;
      51             : 
      52             : public:
      53     4324904 :             ImplLayoutRuns() { mnRunIndex = 0; maRuns.reserve(8); }
      54             : 
      55        2660 :     void    Clear()             { maRuns.clear(); }
      56             :     bool    AddPos( int nCharPos, bool bRTL );
      57             :     bool    AddRun( int nMinRunPos, int nEndRunPos, bool bRTL );
      58             : 
      59     2158401 :     bool    IsEmpty() const     { return maRuns.empty(); }
      60     2169949 :     void    ResetPos()          { mnRunIndex = 0; }
      61     4302745 :     void    NextRun()           { mnRunIndex += 2; }
      62             :     bool    GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL ) const;
      63             :     bool    GetNextPos( int* nCharPos, bool* bRTL );
      64             :     bool    PosIsInRun( int nCharPos ) const;
      65             :     bool    PosIsInAnyRun( int nCharPos ) const;
      66             : };
      67             : 
      68     2157171 : class ImplLayoutArgs
      69             : {
      70             : public:
      71             :     // string related inputs
      72             :     LanguageTag         maLanguageTag;
      73             :     int                 mnFlags;
      74             :     int                 mnLength;
      75             :     int                 mnMinCharPos;
      76             :     int                 mnEndCharPos;
      77             :     const sal_Unicode*  mpStr;
      78             : 
      79             :     // positioning related inputs
      80             :     const DeviceCoordinate* mpDXArray;     // in pixel units
      81             :     DeviceCoordinate    mnLayoutWidth;      // in pixel units
      82             :     int                 mnOrientation;      // in 0-3600 system
      83             : 
      84             :     // data for bidi and glyph+script fallback
      85             :     ImplLayoutRuns      maRuns;
      86             :     ImplLayoutRuns      maFallbackRuns;
      87             : 
      88             : public:
      89             :                 ImplLayoutArgs( const sal_Unicode* pStr, int nLength,
      90             :                                 int nMinCharPos, int nEndCharPos, int nFlags,
      91             :                                 const LanguageTag& rLanguageTag );
      92             : 
      93     2155743 :     void        SetLayoutWidth( DeviceCoordinate nWidth )       { mnLayoutWidth = nWidth; }
      94     2155743 :     void        SetDXArray( const DeviceCoordinate* pDXArray )  { mpDXArray = pDXArray; }
      95     2155743 :     void        SetOrientation( int nOrientation )  { mnOrientation = nOrientation; }
      96             : 
      97        4088 :     void        ResetPos()
      98        4088 :                     { maRuns.ResetPos(); }
      99     2397180 :     bool        GetNextPos( int* nCharPos, bool* bRTL )
     100     2397180 :                     { return maRuns.GetNextPos( nCharPos, bRTL ); }
     101             :     bool        GetNextRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL );
     102           0 :     bool        NeedFallback( int nCharPos, bool bRTL )
     103           0 :                     { return maFallbackRuns.AddPos( nCharPos, bRTL ); }
     104        2344 :     bool        NeedFallback( int nMinRunPos, int nEndRunPos, bool bRTL )
     105        2344 :                     { return maFallbackRuns.AddRun( nMinRunPos, nEndRunPos, bRTL ); }
     106             :     // methods used by BiDi and glyph fallback
     107     2155741 :     bool        NeedFallback() const
     108     2155741 :                     { return !maFallbackRuns.IsEmpty(); }
     109             :     bool        PrepareFallback();
     110             : 
     111             : protected:
     112             :     void        AddRun( int nMinCharPos, int nEndCharPos, bool bRTL );
     113             : };
     114             : 
     115             : // For nice SAL_INFO logging of ImplLayoutArgs values
     116             : std::ostream &operator <<(std::ostream& s, ImplLayoutArgs &rArgs);
     117             : 
     118             : // helper functions often used with ImplLayoutArgs
     119             : bool IsDiacritic( sal_UCS4 );
     120             : int GetVerticalFlags( sal_UCS4 );
     121             : sal_UCS4 GetVerticalChar( sal_UCS4 );
     122             : 
     123             : // all positions/widths are in font units
     124             : // one exception: drawposition is in pixel units
     125             : 
     126             : // Unfortunately there is little documentation to help implementors of
     127             : // new classes derived from SalLayout ("layout engines"), and the code
     128             : // and data structures are far from obvious.
     129             : 
     130             : // For instance, I *think* the important virtual functions in the
     131             : // layout engines are called in this order:
     132             : 
     133             : // * InitFont()
     134             : // * LayoutText()
     135             : // * AdjustLayout(), any number of times (but presumably
     136             : // usually not at all or just once)
     137             : // * Optionally, DrawText()
     138             : 
     139             : // Functions that just return information like GetTexWidth() and
     140             : // FillDXArray() are called after LayoutText() and before DrawText().
     141             : 
     142             : // Another important questions is which parts of an ImplLayoutArgs can
     143             : // be changed by callers between LayoutText() and AdjustLayout()
     144             : // calls. It probably makes sense only if one assumes that the "string
     145             : // related inputs" part are not changed after LayoutText().
     146             : 
     147             : // But why use the same ImplLayoutArgs structure as parameter for both
     148             : // LayoutText() and AdjustLayout() in the first place? And why
     149             : // duplicate some of the fields in both SalLayout and ImplLayoutArgs
     150             : // (mnMinCharPos, mnEndCharPos, mnLayoutFlags==mnFlags,
     151             : // mnOrientation)? Lost in history...
     152             : 
     153             : class VCL_PLUGIN_PUBLIC SalLayout
     154             : {
     155             : public:
     156             :     // used by upper layers
     157     3220119 :     Point&          DrawBase()                              { return maDrawBase; }
     158       21080 :     const Point&    DrawBase() const                        { return maDrawBase; }
     159       10619 :     Point&          DrawOffset()                            { return maDrawOffset; }
     160             :     const Point&    DrawOffset() const                      { return maDrawOffset; }
     161             :     Point           GetDrawPosition( const Point& rRelative = Point(0,0) ) const;
     162             : 
     163             :     virtual bool    LayoutText( ImplLayoutArgs& ) = 0;  // first step of layouting
     164             :     virtual void    AdjustLayout( ImplLayoutArgs& );    // adjusting after fallback etc.
     165        2110 :     virtual void    InitFont() const {}
     166             :     virtual void    DrawText( SalGraphics& ) const = 0;
     167         132 :     virtual bool    DrawTextSpecial( SalGraphics& /* rGraphics */, sal_uInt32 /* flags */ ) const { return false; }
     168             : #define DRAWTEXT_F_OUTLINE ((sal_uInt32)(1<<0))
     169             : 
     170     1848549 :     int             GetUnitsPerPixel() const                { return mnUnitsPerPixel; }
     171           0 :     int             GetOrientation() const                  { return mnOrientation; }
     172             : 
     173             :     // methods using string indexing
     174             :     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra=0, int nFactor=1) const = 0;
     175             :     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const = 0;
     176           0 :     virtual DeviceCoordinate GetTextWidth() const { return FillDXArray( NULL ); }
     177             :     virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const = 0;
     178           0 :     virtual bool    IsKashidaPosValid ( int /*nCharPos*/ ) const { return true; } // i60594
     179             : 
     180             :     // methods using glyph indexing
     181             :     virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdAry, Point& rPos, int&,
     182             :                                    DeviceCoordinate* pGlyphAdvAry = NULL, int* pCharPosAry = NULL,
     183             :                                    const PhysicalFontFace** pFallbackFonts = NULL ) const = 0;
     184             :     virtual bool    GetOutline( SalGraphics&, ::basegfx::B2DPolyPolygonVector& ) const;
     185             :     virtual bool    GetBoundRect( SalGraphics&, Rectangle& ) const;
     186             : 
     187             :     virtual bool    IsSpacingGlyph( sal_GlyphId ) const;
     188             : 
     189             :     // reference counting
     190             :     void            Release() const;
     191             : 
     192             :     // used by glyph+font+script fallback
     193             :     virtual void    MoveGlyph( int nStart, long nNewXPos ) = 0;
     194             :     virtual void    DropGlyph( int nStart ) = 0;
     195             :     virtual void    Simplify( bool bIsBase ) = 0;
     196        2838 :     virtual void    DisableGlyphInjection( bool /*bDisable*/ ) {}
     197             : 
     198             : protected:
     199             :     // used by layout engines
     200             :                     SalLayout();
     201             :     virtual         ~SalLayout();
     202             : 
     203             :     // used by layout layers
     204          90 :     void            SetUnitsPerPixel( int n )               { mnUnitsPerPixel = n; }
     205          90 :     void            SetOrientation( int nOrientation )      // in 0-3600 system
     206          90 :                     { mnOrientation = nOrientation; }
     207             : 
     208             :     static int      CalcAsianKerning( sal_UCS4, bool bLeft, bool bVertical );
     209             : 
     210             : private:
     211             :     // enforce proper copy semantic
     212             :     SAL_DLLPRIVATE  SalLayout( const SalLayout& );
     213             :     SAL_DLLPRIVATE  SalLayout& operator=( const SalLayout& );
     214             : 
     215             : protected:
     216             :     int             mnMinCharPos;
     217             :     int             mnEndCharPos;
     218             :     int             mnLayoutFlags;
     219             : 
     220             :     int             mnUnitsPerPixel;
     221             :     int             mnOrientation;
     222             : 
     223             :     mutable int     mnRefCount;
     224             :     mutable Point   maDrawOffset;
     225             :     Point           maDrawBase;
     226             : };
     227             : 
     228             : class VCL_PLUGIN_PUBLIC MultiSalLayout : public SalLayout
     229             : {
     230             : public:
     231             :     virtual void    DrawText( SalGraphics& ) const SAL_OVERRIDE;
     232             :     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
     233             :     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
     234             :     virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
     235             :     virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos,
     236             :                                    int&, DeviceCoordinate* pGlyphAdvAry, int* pCharPosAry,
     237             :                                    const PhysicalFontFace** pFallbackFonts ) const SAL_OVERRIDE;
     238             :     virtual bool    GetOutline( SalGraphics&, ::basegfx::B2DPolyPolygonVector& ) const SAL_OVERRIDE;
     239             : 
     240             :     // used only by OutputDevice::ImplLayout, TODO: make friend
     241             :     explicit        MultiSalLayout( SalLayout& rBaseLayout,
     242             :                                     const PhysicalFontFace* pBaseFont = NULL );
     243             :     virtual bool    AddFallback( SalLayout& rFallbackLayout,
     244             :                                  ImplLayoutRuns&, const PhysicalFontFace* pFallbackFont );
     245             :     virtual bool    LayoutText( ImplLayoutArgs& ) SAL_OVERRIDE;
     246             :     virtual void    AdjustLayout( ImplLayoutArgs& ) SAL_OVERRIDE;
     247             :     virtual void    InitFont() const SAL_OVERRIDE;
     248             : 
     249             :     void SetInComplete(bool bInComplete = true);
     250             : 
     251             : protected:
     252             :     virtual         ~MultiSalLayout();
     253             : 
     254             : private:
     255             :     // dummy implementations
     256           0 :     virtual void    MoveGlyph( int, long ) SAL_OVERRIDE {}
     257           0 :     virtual void    DropGlyph( int ) SAL_OVERRIDE {}
     258           0 :     virtual void    Simplify( bool ) SAL_OVERRIDE {}
     259             : 
     260             :     // enforce proper copy semantic
     261             :     SAL_DLLPRIVATE  MultiSalLayout( const MultiSalLayout& );
     262             :     SAL_DLLPRIVATE  MultiSalLayout& operator=( const MultiSalLayout& );
     263             : 
     264             : private:
     265             :     SalLayout*      mpLayouts[ MAX_FALLBACK ];
     266             :     const PhysicalFontFace* mpFallbackFonts[ MAX_FALLBACK ];
     267             :     ImplLayoutRuns  maFallbackRuns[ MAX_FALLBACK ];
     268             :     int             mnLevel;
     269             :     bool            mbInComplete;
     270             : };
     271             : 
     272             : struct GlyphItem
     273             : {
     274             :     int     mnFlags;
     275             :     int     mnCharPos;      // index in string
     276             :     int     mnOrigWidth;    // original glyph width
     277             :     int     mnNewWidth;     // width after adjustments
     278             :     int     mnXOffset;
     279             :     sal_GlyphId maGlyphId;
     280             :     Point   maLinearPos;    // absolute position of non rotated string
     281             : 
     282             : public:
     283          90 :             GlyphItem()
     284             :                 : mnFlags(0)
     285             :                 , mnCharPos(0)
     286             :                 , mnOrigWidth(0)
     287             :                 , mnNewWidth(0)
     288             :                 , mnXOffset(0)
     289          90 :                 , maGlyphId(0)
     290          90 :             {}
     291             : 
     292        4172 :             GlyphItem( int nCharPos, sal_GlyphId aGlyphId, const Point& rLinearPos,
     293             :                 long nFlags, int nOrigWidth )
     294             :             :   mnFlags(nFlags), mnCharPos(nCharPos),
     295             :                 mnOrigWidth(nOrigWidth), mnNewWidth(nOrigWidth),
     296             :                 mnXOffset(0),
     297        4172 :                 maGlyphId(aGlyphId), maLinearPos(rLinearPos)
     298        4172 :             {}
     299             : 
     300    41530408 :             GlyphItem( int nCharPos, sal_GlyphId aGlyphId, const Point& rLinearPos,
     301             :                 long nFlags, int nOrigWidth, int nXOffset )
     302             :             :   mnFlags(nFlags), mnCharPos(nCharPos),
     303             :                 mnOrigWidth(nOrigWidth), mnNewWidth(nOrigWidth),
     304             :                 mnXOffset(nXOffset),
     305    41530408 :                 maGlyphId(aGlyphId), maLinearPos(rLinearPos)
     306    41530408 :             {}
     307             : 
     308             :     enum{ FALLBACK_MASK=0xFF, IS_IN_CLUSTER=0x100, IS_RTL_GLYPH=0x200, IS_DIACRITIC=0x400 };
     309             : 
     310    67369866 :     bool    IsClusterStart() const  { return ((mnFlags & IS_IN_CLUSTER) == 0); }
     311     2589294 :     bool    IsRTLGlyph() const      { return ((mnFlags & IS_RTL_GLYPH) != 0); }
     312    41558230 :     bool    IsDiacritic() const     { return ((mnFlags & IS_DIACRITIC) != 0); }
     313             : };
     314             : 
     315             : typedef std::list<GlyphItem> GlyphList;
     316             : typedef std::vector<GlyphItem> GlyphVector;
     317             : 
     318             : class VCL_PLUGIN_PUBLIC GenericSalLayout : public SalLayout
     319             : {
     320             : public:
     321             :     // used by layout engines
     322             :     void            AppendGlyph( const GlyphItem& );
     323     2156463 :     void            Reserve(int size) { m_GlyphItems.reserve(size + 1); }
     324             :     virtual void    AdjustLayout( ImplLayoutArgs& ) SAL_OVERRIDE;
     325             :     virtual void    ApplyDXArray( ImplLayoutArgs& );
     326             :     virtual void    Justify( DeviceCoordinate nNewWidth );
     327             :     void            KashidaJustify( long nIndex, int nWidth );
     328             :     void            ApplyAsianKerning( const sal_Unicode*, int nLength );
     329             :     void            SortGlyphItems();
     330             : 
     331             :     // used by upper layers
     332             :     virtual DeviceCoordinate GetTextWidth() const SAL_OVERRIDE;
     333             :     virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const SAL_OVERRIDE;
     334             :     virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const SAL_OVERRIDE;
     335             :     virtual void    GetCaretPositions( int nArraySize, long* pCaretXArray ) const SAL_OVERRIDE;
     336             : 
     337             :     // used by display layers
     338             :     virtual int     GetNextGlyphs( int nLen, sal_GlyphId* pGlyphIdxAry, Point& rPos, int&,
     339             :                                    DeviceCoordinate* pGlyphAdvAry = NULL, int* pCharPosAry = NULL,
     340             :                                    const PhysicalFontFace** pFallbackFonts = NULL ) const SAL_OVERRIDE;
     341             : 
     342             : protected:
     343             :                     GenericSalLayout();
     344             :     virtual         ~GenericSalLayout();
     345             : 
     346             :     // for glyph+font+script fallback
     347             :     virtual void    MoveGlyph( int nStart, long nNewXPos ) SAL_OVERRIDE;
     348             :     virtual void    DropGlyph( int nStart ) SAL_OVERRIDE;
     349             :     virtual void    Simplify( bool bIsBase ) SAL_OVERRIDE;
     350             : 
     351             :     bool            GetCharWidths( DeviceCoordinate* pCharWidths ) const;
     352             : 
     353             :     GlyphVector     m_GlyphItems;
     354             : 
     355             : private:
     356             :     mutable Point   maBasePoint;
     357             : 
     358             :     // enforce proper copy semantic
     359             :     SAL_DLLPRIVATE  GenericSalLayout( const GenericSalLayout& );
     360             :     SAL_DLLPRIVATE  GenericSalLayout& operator=( const GenericSalLayout& );
     361             : };
     362             : 
     363             : #undef SalGraphics
     364             : 
     365             : #endif // INCLUDED_VCL_INC_SALLAYOUT_HXX
     366             : 
     367             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10