xref: /haiku/src/servers/app/drawing/PatternHandler.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /*
2  * Copyright (c) 2001-2007, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Author:	DarkWyrm <bpmagic@columbus.rr.com>
6  *			Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "PatternHandler.h"
10 
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include <Point.h>
15 
16 const Pattern kSolidHigh(0xFFFFFFFFFFFFFFFFLL);
17 const Pattern kSolidLow((uint64)0);
18 const Pattern kMixedColors(0xAAAAAAAAAAAAAAAALL);
19 
20 const rgb_color kBlack = (rgb_color){ 0, 0, 0, 255 };
21 const rgb_color kWhite = (rgb_color){ 255, 255, 255, 255 };
22 
23 /*!
24 	\brief Void constructor
25 
26 	The pattern is set to B_SOLID_HIGH, high color is set to black, and
27 	low color is set to white.
28 */
29 PatternHandler::PatternHandler(void)
30 	: fPattern(kSolidHigh),
31 	  fHighColor(kBlack),
32 	  fLowColor(kWhite),
33 	  fXOffset(0),
34 	  fYOffset(0),
35 	  fColorsWhenCached(ULONGLONG_MAX)
36 {
37 	memset((void*)fOpCopyColorCache, 255, 256 * sizeof(rgb_color));
38 }
39 
40 /*!
41 	\brief Constructor initializes to given pattern
42 	\param pat Pattern to use.
43 
44 	This initializes to the given pattern or B_SOLID_HIGH if the pattern
45 	is NULL. High color is set to black, and low color is set to white.
46 */
47 PatternHandler::PatternHandler(const int8* pat)
48 	: fPattern(pat ? Pattern(pat) : Pattern(kSolidHigh)),
49 	  fHighColor(kBlack),
50 	  fLowColor(kWhite),
51 	  fXOffset(0),
52 	  fYOffset(0),
53 	  fColorsWhenCached(ULONGLONG_MAX)
54 {
55 	memset((void*)fOpCopyColorCache, 255, 256 * sizeof(rgb_color));
56 }
57 
58 /*!
59 	\brief Constructor initializes to given pattern
60 	\param pat Pattern to use.
61 
62 	This initializes to the given pattern or B_SOLID_HIGH if the pattern
63 	is NULL. High color is set to black, and low color is set to white.
64 */
65 PatternHandler::PatternHandler(const uint64& pat)
66 	: fPattern(pat),
67 	  fHighColor(kBlack),
68 	  fLowColor(kWhite),
69 	  fXOffset(0),
70 	  fYOffset(0),
71 	  fColorsWhenCached(ULONGLONG_MAX)
72 {
73 	memset((void*)fOpCopyColorCache, 255, 256 * sizeof(rgb_color));
74 }
75 
76 /*!
77 	\brief Constructor initializes to given pattern
78 	\param pat Pattern to use.
79 
80 	This initializes to the given Pattern.
81 	High color is set to black, and low color is set to white.
82 */
83 PatternHandler::PatternHandler(const Pattern& pat)
84 	: fPattern(pat),
85 	  fHighColor(kBlack),
86 	  fLowColor(kWhite),
87 	  fXOffset(0),
88 	  fYOffset(0),
89 	  fColorsWhenCached(ULONGLONG_MAX)
90 {
91 	memset((void*)fOpCopyColorCache, 255, 256 * sizeof(rgb_color));
92 }
93 
94 /*!
95 	\brief Constructor initializes to given PatternHandler
96 	\param other PatternHandler to copy.
97 
98 	Copy constructor.
99 */
100 PatternHandler::PatternHandler(const PatternHandler& other)
101 	: fPattern(other.fPattern),
102 	  fHighColor(other.fHighColor),
103 	  fLowColor(other.fLowColor),
104 	  fXOffset(other.fXOffset),
105 	  fYOffset(other.fYOffset),
106 	  fColorsWhenCached(ULONGLONG_MAX)
107 {
108 	memset((void*)fOpCopyColorCache, 255, 256 * sizeof(rgb_color));
109 }
110 
111 //! Destructor does nothing
112 PatternHandler::~PatternHandler(void)
113 {
114 }
115 
116 /*!
117 	\brief Sets the pattern for the handler to the one given
118 	\param pat Pattern to use.
119 
120 	This initializes to the given pattern or B_SOLID_HIGH if the pattern
121 	is NULL.
122 */
123 void
124 PatternHandler::SetPattern(const int8* pat)
125 {
126 	if (pat)
127 		fPattern.Set(pat);
128 	else
129 		fPattern = kSolidHigh;
130 }
131 
132 /*!
133 	\brief Sets the pattern for the handler to the one given
134 	\param pat Pattern to use.
135 */
136 void
137 PatternHandler::SetPattern(const uint64& pat)
138 {
139 	fPattern = pat;
140 }
141 
142 /*!
143 	\brief Sets the pattern for the handler to the one given
144 	\param pat Pattern to use.
145 */
146 void
147 PatternHandler::SetPattern(const Pattern& pat)
148 {
149 	fPattern = pat;
150 }
151 
152 /*!
153 	\brief Sets the pattern for the handler to the one given
154 	\param pat R5 style pattern to use.
155 */
156 void
157 PatternHandler::SetPattern(const pattern& pat)
158 {
159 	fPattern = pat;
160 }
161 
162 /*!
163 	\brief Set the colors for the pattern to use
164 	\param high High color for the handler
165 	\param low Low color for the handler
166 */
167 void
168 PatternHandler::SetColors(const rgb_color& high, const rgb_color& low)
169 {
170 	fHighColor = high;
171 	fLowColor = low;
172 }
173 
174 /*!
175 	\brief Set the high color for the pattern to use
176 	\param color High color for the handler
177 */
178 void
179 PatternHandler::SetHighColor(const rgb_color& color)
180 {
181 	fHighColor = color;
182 }
183 
184 /*!
185 	\brief Set the low color for the pattern to use
186 	\param color Low color for the handler
187 */
188 void
189 PatternHandler::SetLowColor(const rgb_color& color)
190 {
191 	fLowColor = color;
192 }
193 
194 /*!
195 	\brief Obtains the color in the pattern at the specified coordinates
196 	\param pt Coordinates to get the color for
197 	\return Color for the coordinates
198 */
199 rgb_color
200 PatternHandler::ColorAt(const BPoint &pt) const
201 {
202 	return ColorAt(pt.x, pt.y);
203 }
204 
205 /*!
206 	\brief Obtains the color in the pattern at the specified coordinates
207 	\param x X coordinate to get the color for
208 	\param y Y coordinate to get the color for
209 	\return Color for the coordinates
210 */
211 rgb_color
212 PatternHandler::ColorAt(float x, float y) const
213 {
214 	return ColorAt(int(x), int(y));
215 }
216 
217 /*!
218 	\brief Obtains the value of the pattern at the specified coordinates
219 	\param pt Coordinates to get the value for
220 	\return Value for the coordinates - true if high, false if low.
221 */
222 bool
223 PatternHandler::IsHighColor(const BPoint &pt) const
224 {
225 	return IsHighColor((int)pt.x, (int)pt.y);
226 }
227 
228 /*!
229 	\brief Transfers the scrolling offset of a BView to affect the pattern.
230 	\param x Positive or negative horizontal offset
231 	\param y Positive or negative vertical offset
232 */
233 void
234 PatternHandler::SetOffsets(int32 x, int32 y)
235 {
236 	fXOffset = x & 7;
237 	fYOffset = y & 7;
238 }
239 
240 
241 void
242 PatternHandler::MakeOpCopyColorCache()
243 {
244 	uint64 t = *(uint32*)&fHighColor;
245 	uint64 colors = (t << 32) | *(uint32*)&fLowColor;
246 
247 	if (fColorsWhenCached == colors)
248 		return;
249 
250 	fColorsWhenCached = colors;
251 
252 	// ramp from low color to high color
253 	uint8 rA = fLowColor.red;
254 	uint8 gA = fLowColor.green;
255 	uint8 bA = fLowColor.blue;
256 
257 	uint8 rB = fHighColor.red;
258 	uint8 gB = fHighColor.green;
259 	uint8 bB = fHighColor.blue;
260 
261 	for (int32 i = 0; i < 256; i++) {
262 		// NOTE: rgb is twisted around, since this is
263 		// only used as uint32 in the end
264 		fOpCopyColorCache[i].red = (((bB - bA) * i) + (bA << 8)) >> 8;
265 		fOpCopyColorCache[i].green = (((gB - gA) * i) + (gA << 8)) >> 8;
266 		fOpCopyColorCache[i].blue = (((rB - rA) * i) + (rA << 8)) >> 8;
267 	}
268 }
269 
270 
271