LCOV - code coverage report
Current view: top level - libreoffice/vcl/generic/glyphs - gcach_rbmp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 43 123 35.0 %
Date: 2012-12-27 Functions: 4 7 57.1 %
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 "generic/glyphcache.hxx"
      22             : #include <string.h>
      23             : 
      24             : //------------------------------------------------------------------------
      25             : 
      26       17149 : RawBitmap::RawBitmap()
      27       17149 : : mpBits(0), mnAllocated(0)
      28       17149 : {}
      29             : 
      30             : //------------------------------------------------------------------------
      31             : 
      32         259 : RawBitmap::~RawBitmap()
      33             : {
      34         259 :     delete[] mpBits;
      35         259 :     mpBits = 0;
      36         259 :     mnAllocated = 0;
      37         259 : }
      38             : 
      39             : //------------------------------------------------------------------------
      40             : 
      41             : // used by 90 and 270 degree rotations on 8 bit deep bitmaps
      42        2140 : static void ImplRotate8_90( unsigned char* p1, const unsigned char* p2,
      43             :     int xmax, int ymax, int dx, int dy, int nPad )
      44             : {
      45       13886 :     for( int y = ymax; --y >= 0; p2 += dy )
      46             :     {
      47      105714 :         for( int x = xmax; --x >= 0; p2 += dx )
      48       93968 :             *(p1++) = *p2;
      49       23492 :         for( int i = nPad; --i >= 0; )
      50           0 :             *(p1++) = 0;
      51             :     }
      52        2140 : }
      53             : 
      54             : //------------------------------------------------------------------------
      55             : 
      56             : // used by inplace 180 degree rotation on 8 bit deep bitmaps
      57           0 : static void ImplRotate8_180( unsigned char* p1, int xmax, int ymax, int nPad )
      58             : {
      59           0 :     unsigned char* p2 = p1 + ymax * (xmax + nPad);
      60           0 :     for( int y = ymax/2; --y >= 0; )
      61             :     {
      62           0 :         p2 -= nPad;
      63           0 :         for( int x = xmax; --x >= 0; )
      64             :         {
      65           0 :             unsigned char cTmp = *(--p2);
      66           0 :             *p2 = *p1;
      67           0 :             *(p1++) = cTmp;
      68             :         }
      69           0 :         p1 += nPad;
      70             :     }
      71             : 
      72             :     // reverse middle line
      73           0 :     p2 -= nPad;
      74           0 :     while( p1 < p2 )
      75             :     {
      76           0 :         unsigned char cTmp = *(--p2);
      77           0 :         *p2 = *p1;
      78           0 :         *(p1++) = cTmp;
      79             :     }
      80           0 : }
      81             : 
      82             : //------------------------------------------------------------------------
      83             : 
      84             : // used by 90 or 270 degree rotations on 1 bit deep bitmaps
      85           0 : static void ImplRotate1_90( unsigned char* p1, const unsigned char* p2,
      86             :     int xmax, int ymax, int dx, int nShift, int nDeltaShift, int nPad )
      87             : {
      88           0 :     for( int y = ymax; --y >= 0; )
      89             :     {
      90           0 :         unsigned nTemp = 1;
      91           0 :         const unsigned char* p20 = p2;
      92           0 :         for( int x = xmax; --x >= 0; p2 += dx )
      93             :         {
      94             :             // build bitwise and store when byte finished
      95           0 :            nTemp += nTemp + ((*p2 >> nShift) & 1);
      96           0 :             if( nTemp >= 0x100U )
      97             :             {
      98           0 :                 *(p1++) = (unsigned char)nTemp;
      99           0 :                 nTemp = 1;
     100             :             }
     101             :         }
     102           0 :         p2 = p20;
     103             : 
     104             :         // store left aligned remainder if needed
     105           0 :         if( nTemp > 1 )
     106             :         {
     107           0 :             for(; nTemp < 0x100U; nTemp += nTemp ) ;
     108           0 :             *(p1++) = (unsigned char)nTemp;
     109             :         }
     110             :         // pad scanline with zeroes
     111           0 :         for( int i = nPad; --i >= 0;)
     112           0 :             *(p1++) = 0;
     113             : 
     114             :         // increase/decrease shift, but keep bound inside 0 to 7
     115           0 :         nShift += nDeltaShift;
     116           0 :         if( nShift != (nShift & 7) )
     117           0 :             p2 -= nDeltaShift;
     118           0 :         nShift &= 7;
     119             :     }
     120           0 : }
     121             : 
     122             : //------------------------------------------------------------------------
     123             : 
     124             : // used by 180 degrees rotations on 1 bit deep bitmaps
     125           0 : static void ImplRotate1_180( unsigned char* p1, const unsigned char* p2,
     126             :     int xmax, int ymax, int nPad )
     127             : {
     128           0 :     --p2;
     129           0 :     for( int y = ymax; --y >= 0; )
     130             :     {
     131           0 :         p2 -= nPad;
     132             : 
     133           0 :         unsigned nTemp = 1;
     134           0 :         unsigned nInp = (0x100 + *p2) >> (-xmax & 7);
     135           0 :         for( int x = xmax; --x >= 0; )
     136             :         {
     137             :             // build bitwise and store when byte finished
     138           0 :             nTemp += nTemp + (nInp & 1);
     139           0 :             if( nTemp >= 0x100 )
     140             :             {
     141           0 :                 *(p1++) = (unsigned char)nTemp;
     142           0 :                 nTemp = 1;
     143             :             }
     144             :             // update input byte if needed (and available)
     145           0 :             if( (nInp >>= 1) <= 1 && ((y != 0) || (x != 0)) )
     146           0 :                 nInp = 0x100 + *(--p2);
     147             :         }
     148             : 
     149             :         // store left aligned remainder if needed
     150           0 :         if( nTemp > 1 )
     151             :         {
     152           0 :             for(; nTemp < 0x100; nTemp += nTemp ) ;
     153           0 :             *(p1++) = (unsigned char)nTemp;
     154             :         }
     155             :         // scanline pad is already clean
     156           0 :         p1 += nPad;
     157             :     }
     158           0 : }
     159             : 
     160             : //------------------------------------------------------------------------
     161             : 
     162        2140 : bool RawBitmap::Rotate( int nAngle )
     163             : {
     164        2140 :     sal_uLong nNewScanlineSize = 0;
     165        2140 :     sal_uLong nNewHeight = 0;
     166        2140 :     sal_uLong nNewWidth = 0;
     167             : 
     168             :     // do inplace rotation or prepare double buffered rotation
     169        2140 :     switch( nAngle )
     170             :     {
     171             :         case 0:     // nothing to do
     172             :         case 3600:
     173           0 :             return true;
     174             :         default:    // non rectangular angles not allowed
     175           0 :             return false;
     176             :         case 1800:  // rotate by 180 degrees
     177           0 :             mnXOffset = -(mnXOffset + mnWidth);
     178           0 :             mnYOffset = -(mnYOffset + mnHeight);
     179           0 :             if( mnBitCount == 8 )
     180             :             {
     181           0 :                 ImplRotate8_180( mpBits, mnWidth, mnHeight, mnScanlineSize-mnWidth );
     182           0 :                 return true;
     183             :             }
     184           0 :             nNewWidth        = mnWidth;
     185           0 :             nNewHeight       = mnHeight;
     186           0 :             nNewScanlineSize = mnScanlineSize;
     187           0 :             break;
     188             :         case +900:  // left by 90 degrees
     189             :         case -900:
     190             :         case 2700:  // right by 90 degrees
     191        2140 :             nNewWidth        = mnHeight;
     192        2140 :             nNewHeight       = mnWidth;
     193        2140 :             if( mnBitCount==1 )
     194           0 :                 nNewScanlineSize = (nNewWidth + 7) / 8;
     195             :             else
     196        2140 :                 nNewScanlineSize = (nNewWidth + 3) & -4;
     197        2140 :             break;
     198             :     }
     199             : 
     200        2140 :     unsigned int nBufSize = nNewHeight * nNewScanlineSize;
     201        2140 :     unsigned char* pBuf = new unsigned char[ nBufSize ];
     202        2140 :     if( !pBuf )
     203           0 :         return false;
     204             : 
     205        2140 :     memset( pBuf, 0, nBufSize );
     206             :     int i;
     207             : 
     208             :     // dispatch non-inplace rotations
     209        2140 :     switch( nAngle )
     210             :     {
     211             :         case 1800:  // rotate by 180 degrees
     212             :             // we know we only need to deal with 1 bit depth
     213             :             ImplRotate1_180( pBuf, mpBits + mnHeight * mnScanlineSize,
     214           0 :                 mnWidth, mnHeight, mnScanlineSize - (mnWidth + 7) / 8 );
     215           0 :             break;
     216             :         case +900:  // rotate left by 90 degrees
     217        2140 :             i = mnXOffset;
     218        2140 :             mnXOffset = mnYOffset;
     219        2140 :             mnYOffset = -nNewHeight - i;
     220        2140 :             if( mnBitCount == 8 )
     221        2140 :                 ImplRotate8_90( pBuf, mpBits + mnWidth - 1,
     222             :                     nNewWidth, nNewHeight, +mnScanlineSize, -1-mnHeight*mnScanlineSize,
     223        4280 :                     nNewScanlineSize - nNewWidth );
     224             :             else
     225             :                 ImplRotate1_90( pBuf, mpBits + (mnWidth - 1) / 8,
     226             :                     nNewWidth, nNewHeight, +mnScanlineSize,
     227           0 :                     (-mnWidth & 7), +1, nNewScanlineSize - (nNewWidth + 7) / 8 );
     228        2140 :             break;
     229             :         case 2700:  // rotate right by 90 degrees
     230             :         case -900:
     231           0 :             i = mnXOffset;
     232           0 :             mnXOffset = -(nNewWidth + mnYOffset);
     233           0 :             mnYOffset = i;
     234           0 :             if( mnBitCount == 8 )
     235             :                 ImplRotate8_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
     236             :                     nNewWidth, nNewHeight, -mnScanlineSize, +1+mnHeight*mnScanlineSize,
     237           0 :                     nNewScanlineSize - nNewWidth );
     238             :             else
     239             :                 ImplRotate1_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
     240             :                     nNewWidth, nNewHeight, -mnScanlineSize,
     241           0 :                     +7, -1, nNewScanlineSize - (nNewWidth + 7) / 8 );
     242           0 :             break;
     243             :     }
     244             : 
     245        2140 :     mnWidth        = nNewWidth;
     246        2140 :     mnHeight       = nNewHeight;
     247        2140 :     mnScanlineSize = nNewScanlineSize;
     248             : 
     249        2140 :     if( nBufSize < mnAllocated )
     250             :     {
     251        2140 :         memcpy( mpBits, pBuf, nBufSize );
     252        2140 :         delete[] pBuf;
     253             :     }
     254             :     else
     255             :     {
     256           0 :         delete[] mpBits;
     257           0 :         mpBits = pBuf;
     258           0 :         mnAllocated = nBufSize;
     259             :     }
     260             : 
     261        2140 :     return true;
     262             : }
     263             : 
     264             : //------------------------------------------------------------------------
     265             : 
     266             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10