office-gobmx/vcl/source/gdi/bmpacc3.cxx
2011-07-31 21:18:02 +01:00

318 lines
9.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <tools/poly.hxx>
#include <vcl/salbtype.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/region.hxx>
#include <vcl/bmpacc.hxx>
#include <bmpfast.hxx>
// ---------------------
// - BitmapWriteAccess -
// ---------------------
void BitmapWriteAccess::SetLineColor( const Color& rColor )
{
delete mpLineColor;
if( rColor.GetTransparency() == 255 )
mpLineColor = NULL;
else
mpLineColor = ( HasPalette() ? new BitmapColor( (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
}
// ------------------------------------------------------------------
void BitmapWriteAccess::SetFillColor( const Color& rColor )
{
delete mpFillColor;
if( rColor.GetTransparency() == 255 )
mpFillColor = NULL;
else
mpFillColor = ( HasPalette() ? new BitmapColor( (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
}
// ------------------------------------------------------------------
void BitmapWriteAccess::Erase( const Color& rColor )
{
// convert the color format from RGB to palette index if needed
// TODO: provide and use Erase( BitmapColor& method)
BitmapColor aColor = rColor;
if( HasPalette() )
aColor = BitmapColor( (sal_uInt8)GetBestPaletteIndex( rColor) );
// try fast bitmap method first
if( ImplFastEraseBitmap( *mpBuffer, aColor ) )
return;
// use the canonical method to clear the bitmap
BitmapColor* pOldFillColor = mpFillColor ? new BitmapColor( *mpFillColor ) : NULL;
const Point aPoint;
const Rectangle aRect( aPoint, maBitmap.GetSizePixel() );
SetFillColor( rColor );
FillRect( aRect );
delete mpFillColor;
mpFillColor = pOldFillColor;
}
// ------------------------------------------------------------------
void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
{
if( mpLineColor )
{
const BitmapColor& rLineColor = *mpLineColor;
long nX, nY;
if ( rStart.X() == rEnd.X() )
{
// vertikale Line
const long nEndY = rEnd.Y();
nX = rStart.X();
nY = rStart.Y();
if ( nEndY > nY )
{
for (; nY <= nEndY; nY++ )
SetPixel( nY, nX, rLineColor );
}
else
{
for (; nY >= nEndY; nY-- )
SetPixel( nY, nX, rLineColor );
}
}
else if ( rStart.Y() == rEnd.Y() )
{
// horizontale Line
const long nEndX = rEnd.X();
nX = rStart.X();
nY = rStart.Y();
if ( nEndX > nX )
{
for (; nX <= nEndX; nX++ )
SetPixel( nY, nX, rLineColor );
}
else
{
for (; nX >= nEndX; nX-- )
SetPixel( nY, nX, rLineColor );
}
}
else
{
const long nDX = labs( rEnd.X() - rStart.X() );
const long nDY = labs( rEnd.Y() - rStart.Y() );
long nX1;
long nY1;
long nX2;
long nY2;
if ( nDX >= nDY )
{
if ( rStart.X() < rEnd.X() )
{
nX1 = rStart.X();
nY1 = rStart.Y();
nX2 = rEnd.X();
nY2 = rEnd.Y();
}
else
{
nX1 = rEnd.X();
nY1 = rEnd.Y();
nX2 = rStart.X();
nY2 = rStart.Y();
}
const long nDYX = ( nDY - nDX ) << 1;
const long nDY2 = nDY << 1;
long nD = nDY2 - nDX;
sal_Bool bPos = nY1 < nY2;
for ( nX = nX1, nY = nY1; nX <= nX2; nX++ )
{
SetPixel( nY, nX, rLineColor );
if ( nD < 0 )
nD += nDY2;
else
{
nD += nDYX;
if ( bPos )
nY++;
else
nY--;
}
}
}
else
{
if ( rStart.Y() < rEnd.Y() )
{
nX1 = rStart.X();
nY1 = rStart.Y();
nX2 = rEnd.X();
nY2 = rEnd.Y();
}
else
{
nX1 = rEnd.X();
nY1 = rEnd.Y();
nX2 = rStart.X();
nY2 = rStart.Y();
}
const long nDYX = ( nDX - nDY ) << 1;
const long nDY2 = nDX << 1;
long nD = nDY2 - nDY;
sal_Bool bPos = nX1 < nX2;
for ( nX = nX1, nY = nY1; nY <= nY2; nY++ )
{
SetPixel( nY, nX, rLineColor );
if ( nD < 0 )
nD += nDY2;
else
{
nD += nDYX;
if ( bPos )
nX++;
else
nX--;
}
}
}
}
}
}
// ------------------------------------------------------------------
void BitmapWriteAccess::FillRect( const Rectangle& rRect )
{
if( mpFillColor )
{
const BitmapColor& rFillColor = *mpFillColor;
Point aPoint;
Rectangle aRect( aPoint, maBitmap.GetSizePixel() );
aRect.Intersection( rRect );
if( !aRect.IsEmpty() )
{
const long nStartX = rRect.Left();
const long nStartY = rRect.Top();
const long nEndX = rRect.Right();
const long nEndY = rRect.Bottom();
for( long nY = nStartY; nY <= nEndY; nY++ )
for( long nX = nStartX; nX <= nEndX; nX++ )
SetPixel( nY, nX, rFillColor );
}
}
}
// ------------------------------------------------------------------
void BitmapWriteAccess::DrawRect( const Rectangle& rRect )
{
if( mpFillColor )
FillRect( rRect );
if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
{
DrawLine( rRect.TopLeft(), rRect.TopRight() );
DrawLine( rRect.TopRight(), rRect.BottomRight() );
DrawLine( rRect.BottomRight(), rRect.BottomLeft() );
DrawLine( rRect.BottomLeft(), rRect.TopLeft() );
}
}
// ------------------------------------------------------------------
void BitmapWriteAccess::FillPolygon( const Polygon& rPoly )
{
const sal_uInt16 nSize = rPoly.GetSize();
if( nSize && mpFillColor )
{
const BitmapColor& rFillColor = *mpFillColor;
Region aRegion( rPoly );
Rectangle aRect;
aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
if( !aRegion.IsEmpty() )
{
RegionHandle aRegHandle( aRegion.BeginEnumRects() );
while( aRegion.GetNextEnumRect( aRegHandle, aRect ) )
for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
SetPixel( nY, nX, rFillColor );
aRegion.EndEnumRects( aRegHandle );
}
}
}
// ------------------------------------------------------------------
void BitmapWriteAccess::DrawPolygon( const Polygon& rPoly )
{
if( mpFillColor )
FillPolygon( rPoly );
if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
{
const sal_uInt16 nSize = rPoly.GetSize();
for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */