blob: ea26ca64977de3f28748711b0f9308190a1aba10 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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()
{
delete mpLineColor;
mpLineColor = NULL;
}
// ------------------------------------------------------------------
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 ) );
}
// ------------------------------------------------------------------
Color BitmapWriteAccess::GetLineColor() const
{
Color aRet;
if( mpLineColor )
aRet = (const Color&) *mpLineColor;
else
aRet.SetTransparency( 255 );
return aRet;
}
// ------------------------------------------------------------------
void BitmapWriteAccess::SetFillColor()
{
delete mpFillColor;
mpFillColor = NULL;
}
// ------------------------------------------------------------------
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 ) );
}
// ------------------------------------------------------------------
Color BitmapWriteAccess::GetFillColor() const
{
Color aRet;
if( mpFillColor )
aRet = (const Color&) *mpFillColor;
else
aRet.SetTransparency( 255 );
return aRet;
}
// ------------------------------------------------------------------
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() )
{
RectangleVector aRectangles;
aRegion.GetRegionRectangles(aRectangles);
for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
{
for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
{
for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
{
SetPixel(nY, nX, rFillColor);
}
}
}
//RegionHandle aRegHandle( aRegion.BeginEnumRects() );
//
//while( aRegion.GetEnumRects( 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 ] );
}
}
// ------------------------------------------------------------------
void BitmapWriteAccess::FillPolyPolygon( const PolyPolygon& rPolyPoly )
{
const sal_uInt16 nCount = rPolyPoly.Count();
if( nCount && mpFillColor )
{
const BitmapColor& rFillColor = *mpFillColor;
Region aRegion( rPolyPoly );
//Rectangle aRect;
aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
if( !aRegion.IsEmpty() )
{
RectangleVector aRectangles;
aRegion.GetRegionRectangles(aRectangles);
for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
{
for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
{
for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
{
SetPixel(nY, nX, rFillColor);
}
}
}
//RegionHandle aRegHandle( aRegion.BeginEnumRects() );
//
//while( aRegion.GetEnumRects( 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::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
{
if( mpFillColor )
FillPolyPolygon( rPolyPoly );
if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
{
for( sal_uInt16 n = 0, nCount = rPolyPoly.Count(); n < nCount; )
{
const Polygon& rPoly = rPolyPoly[ n++ ];
const sal_uInt16 nSize = rPoly.GetSize();
if( nSize )
{
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 ] );
}
}
}
}