LibreOffice Module vcl (master)  1
bmpacc3.cxx
Go to the documentation of this file.
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 #include <vcl/bitmap.hxx>
21 
22 #include <bmpfast.hxx>
23 #include <bitmapwriteaccess.hxx>
24 
26 {
27  if (rColor.GetTransparency() == 255)
28  {
29  mpLineColor.reset();
30  }
31  else
32  {
33  if (HasPalette())
34  {
35  mpLineColor = BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor)));
36  }
37  else
38  {
39  mpLineColor = BitmapColor(rColor);
40  }
41  }
42 }
43 
45 {
46  mpFillColor.reset();
47 }
48 
50 {
51  if (rColor.GetTransparency() == 255)
52  {
53  mpFillColor.reset();
54  }
55  else
56  {
57  if (HasPalette())
58  {
59  mpFillColor = BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor)));
60  }
61  else
62  {
63  mpFillColor = BitmapColor(rColor);
64  }
65  }
66 }
67 
68 void BitmapWriteAccess::Erase( const Color& rColor )
69 {
70  // convert the color format from RGB to palette index if needed
71  // TODO: provide and use Erase( BitmapColor& method)
72  BitmapColor aColor = rColor;
73  if (HasPalette())
74  {
75  aColor = BitmapColor(static_cast<sal_uInt8>(GetBestPaletteIndex(rColor)));
76  }
77 
78  // try fast bitmap method first
79  if (ImplFastEraseBitmap(*mpBuffer, aColor))
80  return;
81 
83  if (aRect.IsEmpty())
84  return;
85  // clear the bitmap by filling the first line pixel by pixel,
86  // then dup the first line over each other line
87  Scanline pFirstScanline = GetScanline(0);
88  const long nEndX = aRect.Right();
89  for (long nX = 0; nX <= nEndX; ++nX)
90  SetPixelOnData(pFirstScanline, nX, rColor);
91  const auto nScanlineSize = GetScanlineSize();
92  const long nEndY = aRect.Bottom();
93  for (long nY = 1; nY <= nEndY; nY++)
94  {
95  Scanline pDestScanline = GetScanline(nY);
96  memcpy(pDestScanline, pFirstScanline, nScanlineSize);
97  }
98 }
99 
100 void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
101 {
102  if (mpLineColor)
103  {
104  const BitmapColor& rLineColor = *mpLineColor;
105  long nX, nY;
106 
107  if (rStart.X() == rEnd.X())
108  {
109  // Vertical Line
110  const long nEndY = rEnd.Y();
111 
112  nX = rStart.X();
113  nY = rStart.Y();
114 
115  if (nEndY > nY)
116  {
117  for (; nY <= nEndY; nY++ )
118  SetPixel( nY, nX, rLineColor );
119  }
120  else
121  {
122  for (; nY >= nEndY; nY-- )
123  SetPixel( nY, nX, rLineColor );
124  }
125  }
126  else if (rStart.Y() == rEnd.Y())
127  {
128  // Horizontal Line
129  const long nEndX = rEnd.X();
130 
131  nX = rStart.X();
132  nY = rStart.Y();
133 
134  if (nEndX > nX)
135  {
136  for (; nX <= nEndX; nX++)
137  SetPixel(nY, nX, rLineColor);
138  }
139  else
140  {
141  for (; nX >= nEndX; nX--)
142  SetPixel(nY, nX, rLineColor);
143  }
144  }
145  else
146  {
147  const long nDX = labs( rEnd.X() - rStart.X() );
148  const long nDY = labs( rEnd.Y() - rStart.Y() );
149  long nX1;
150  long nY1;
151  long nX2;
152  long nY2;
153 
154  if (nDX >= nDY)
155  {
156  if (rStart.X() < rEnd.X())
157  {
158  nX1 = rStart.X();
159  nY1 = rStart.Y();
160  nX2 = rEnd.X();
161  nY2 = rEnd.Y();
162  }
163  else
164  {
165  nX1 = rEnd.X();
166  nY1 = rEnd.Y();
167  nX2 = rStart.X();
168  nY2 = rStart.Y();
169  }
170 
171  const long nDYX = (nDY - nDX) << 1;
172  const long nDY2 = nDY << 1;
173  long nD = nDY2 - nDX;
174  bool bPos = nY1 < nY2;
175 
176  for (nX = nX1, nY = nY1; nX <= nX2; nX++)
177  {
178  SetPixel(nY, nX, rLineColor);
179 
180  if (nD < 0)
181  nD += nDY2;
182  else
183  {
184  nD += nDYX;
185 
186  if (bPos)
187  nY++;
188  else
189  nY--;
190  }
191  }
192  }
193  else
194  {
195  if (rStart.Y() < rEnd.Y())
196  {
197  nX1 = rStart.X();
198  nY1 = rStart.Y();
199  nX2 = rEnd.X();
200  nY2 = rEnd.Y();
201  }
202  else
203  {
204  nX1 = rEnd.X();
205  nY1 = rEnd.Y();
206  nX2 = rStart.X();
207  nY2 = rStart.Y();
208  }
209 
210  const long nDYX = (nDX - nDY) << 1;
211  const long nDY2 = nDX << 1;
212  long nD = nDY2 - nDY;
213  bool bPos = nX1 < nX2;
214 
215  for (nX = nX1, nY = nY1; nY <= nY2; nY++)
216  {
217  SetPixel(nY, nX, rLineColor);
218 
219  if (nD < 0)
220  nD += nDY2;
221  else
222  {
223  nD += nDYX;
224 
225  if (bPos)
226  nX++;
227  else
228  nX--;
229  }
230  }
231  }
232  }
233  }
234 }
235 
237 {
238  if (mpFillColor)
239  {
240  const BitmapColor& rFillColor = *mpFillColor;
242 
243  aRect.Intersection(rRect);
244 
245  if (!aRect.IsEmpty())
246  {
247  const long nStartX = rRect.Left();
248  const long nStartY = rRect.Top();
249  const long nEndX = rRect.Right();
250  const long nEndY = rRect.Bottom();
251 
252  for (long nY = nStartY; nY <= nEndY; nY++)
253  {
254  Scanline pScanline = GetScanline( nY );
255  for (long nX = nStartX; nX <= nEndX; nX++)
256  {
257  SetPixelOnData(pScanline, nX, rFillColor);
258  }
259  }
260  }
261  }
262 }
263 
265 {
266  if (mpFillColor)
267  FillRect(rRect);
268 
269  if (mpLineColor && (!mpFillColor || ( *mpFillColor != *mpLineColor)))
270  {
271  DrawLine(rRect.TopLeft(), rRect.TopRight());
272  DrawLine(rRect.TopRight(), rRect.BottomRight());
273  DrawLine(rRect.BottomRight(), rRect.BottomLeft());
274  DrawLine(rRect.BottomLeft(), rRect.TopLeft());
275  }
276 }
277 
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
Scanline GetScanline(long nY) const
void DrawRect(const tools::Rectangle &rRect)
Definition: bmpacc3.cxx:264
Point BottomLeft() const
sal_uInt8 GetTransparency() const
void SetPixel(long nY, long nX, const BitmapColor &rBitmapColor)
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rBitmapColor) const
Definition: bmpacc.cxx:81
Size GetSizePixel() const
boost::optional< BitmapColor > mpLineColor
void FillRect(const tools::Rectangle &rRect)
Definition: bmpacc3.cxx:236
long Right() const
void SetPixelOnData(sal_uInt8 *pData, long nX, const BitmapColor &rBitmapColor)
long Top() const
BitmapBuffer * mpBuffer
Point BottomRight() const
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
sal_uInt32 GetScanlineSize() const
bool HasPalette() const
void Erase(const Color &rColor)
Definition: bmpacc3.cxx:68
long Bottom() const
boost::optional< BitmapColor > mpFillColor
long X() const
void SetLineColor(const Color &rColor)
Definition: bmpacc3.cxx:25
void DrawLine(const Point &rStart, const Point &rEnd)
Definition: bmpacc3.cxx:100
long Left() const
void SetFillColor()
Definition: bmpacc3.cxx:44
Point TopRight() const
long Y() const
bool ImplFastEraseBitmap(BitmapBuffer &rDst, const BitmapColor &rColor)
Definition: bmpfast.cxx:672