1*20bfefbeSAndroid Build Coastguard Worker /*
2*20bfefbeSAndroid Build Coastguard Worker *
3*20bfefbeSAndroid Build Coastguard Worker * Copyright 2019, The Android Open Source Project
4*20bfefbeSAndroid Build Coastguard Worker *
5*20bfefbeSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*20bfefbeSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*20bfefbeSAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*20bfefbeSAndroid Build Coastguard Worker *
9*20bfefbeSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*20bfefbeSAndroid Build Coastguard Worker *
11*20bfefbeSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*20bfefbeSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*20bfefbeSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*20bfefbeSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*20bfefbeSAndroid Build Coastguard Worker * limitations under the License.
16*20bfefbeSAndroid Build Coastguard Worker */
17*20bfefbeSAndroid Build Coastguard Worker
18*20bfefbeSAndroid Build Coastguard Worker #include <teeui/button.h>
19*20bfefbeSAndroid Build Coastguard Worker namespace teeui {
20*20bfefbeSAndroid Build Coastguard Worker
makeSquareAtOffset(const PxPoint & offset,const pxs & sideLength)21*20bfefbeSAndroid Build Coastguard Worker ConvexObject<4> makeSquareAtOffset(const PxPoint& offset, const pxs& sideLength) {
22*20bfefbeSAndroid Build Coastguard Worker return ConvexObject<4>({offset, offset + PxPoint{sideLength, .0},
23*20bfefbeSAndroid Build Coastguard Worker offset + PxPoint{sideLength, sideLength},
24*20bfefbeSAndroid Build Coastguard Worker offset + PxPoint{.0, sideLength}});
25*20bfefbeSAndroid Build Coastguard Worker }
26*20bfefbeSAndroid Build Coastguard Worker
draw(const PixelDrawer & drawPixel,const Box<pxs> & bounds,const ConvexObjectInfo * coBegin,const ConvexObjectInfo * coEnd)27*20bfefbeSAndroid Build Coastguard Worker Error ButtonImpl::draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds,
28*20bfefbeSAndroid Build Coastguard Worker const ConvexObjectInfo* coBegin, const ConvexObjectInfo* coEnd) {
29*20bfefbeSAndroid Build Coastguard Worker
30*20bfefbeSAndroid Build Coastguard Worker using intpxs = Coordinate<px, int64_t>;
31*20bfefbeSAndroid Build Coastguard Worker Box<intpxs> intBounds(bounds);
32*20bfefbeSAndroid Build Coastguard Worker
33*20bfefbeSAndroid Build Coastguard Worker auto drawPixelBoundsEnforced = [&](uint32_t x, uint32_t y, Color color) -> Error {
34*20bfefbeSAndroid Build Coastguard Worker if (!intBounds.contains(Point<intpxs>(x, y))) {
35*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << "Bounds: " << bounds << " Pixel: " << Point<pxs>(x, y) << ENDL;
36*20bfefbeSAndroid Build Coastguard Worker return Error::OutOfBoundsDrawing;
37*20bfefbeSAndroid Build Coastguard Worker }
38*20bfefbeSAndroid Build Coastguard Worker return drawPixel(x, y, color);
39*20bfefbeSAndroid Build Coastguard Worker };
40*20bfefbeSAndroid Build Coastguard Worker
41*20bfefbeSAndroid Build Coastguard Worker auto drawBox = [&](const Box<intpxs>& box, Color c) -> Error {
42*20bfefbeSAndroid Build Coastguard Worker for (int y = 0; y < box.h().count(); ++y) {
43*20bfefbeSAndroid Build Coastguard Worker for (int x = 0; x < box.w().count(); ++x) {
44*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawPixel(box.x().count() + x, box.y().count() + y, c)) {
45*20bfefbeSAndroid Build Coastguard Worker return error;
46*20bfefbeSAndroid Build Coastguard Worker }
47*20bfefbeSAndroid Build Coastguard Worker }
48*20bfefbeSAndroid Build Coastguard Worker }
49*20bfefbeSAndroid Build Coastguard Worker return Error::OK;
50*20bfefbeSAndroid Build Coastguard Worker };
51*20bfefbeSAndroid Build Coastguard Worker
52*20bfefbeSAndroid Build Coastguard Worker #ifdef DRAW_DEBUG_MARKERS
53*20bfefbeSAndroid Build Coastguard Worker auto drawDebugBox = [&](const Box<pxs>& box, Color c) {
54*20bfefbeSAndroid Build Coastguard Worker drawBox(box, (c & 0xffffff) | 0x40000000);
55*20bfefbeSAndroid Build Coastguard Worker };
56*20bfefbeSAndroid Build Coastguard Worker
57*20bfefbeSAndroid Build Coastguard Worker drawDebugBox(intBounds, 0xff);
58*20bfefbeSAndroid Build Coastguard Worker #endif
59*20bfefbeSAndroid Build Coastguard Worker
60*20bfefbeSAndroid Build Coastguard Worker intpxs intRadius = radius_.count();
61*20bfefbeSAndroid Build Coastguard Worker
62*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << intBounds << ENDL;
63*20bfefbeSAndroid Build Coastguard Worker
64*20bfefbeSAndroid Build Coastguard Worker auto drawCorner = [&, this](intpxs right, intpxs bottom) -> Error {
65*20bfefbeSAndroid Build Coastguard Worker Box<intpxs> cBounds(intBounds.x(), intBounds.y(), intRadius, intRadius);
66*20bfefbeSAndroid Build Coastguard Worker cBounds.translateSelf(Point<intpxs>(right * (intBounds.w() - intRadius),
67*20bfefbeSAndroid Build Coastguard Worker bottom * (intBounds.h() - intRadius)));
68*20bfefbeSAndroid Build Coastguard Worker auto center = Point<pxs>((intpxs(1) - right) * intRadius, (intpxs(1) - bottom) * intRadius);
69*20bfefbeSAndroid Build Coastguard Worker center += cBounds.topLeft();
70*20bfefbeSAndroid Build Coastguard Worker center -= Point<pxs>(.5, .5);
71*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << "Radius: " << intRadius << " cBounds: " << cBounds << " center: " << center
72*20bfefbeSAndroid Build Coastguard Worker << ENDL;
73*20bfefbeSAndroid Build Coastguard Worker for (int y = 0; y < cBounds.h().count(); ++y) {
74*20bfefbeSAndroid Build Coastguard Worker for (int x = 0; x < cBounds.w().count(); ++x) {
75*20bfefbeSAndroid Build Coastguard Worker auto pos = Point<pxs>(cBounds.x().count() + x, cBounds.y().count() + y);
76*20bfefbeSAndroid Build Coastguard Worker auto color = drawCirclePoint(center, intRadius, pos, color_);
77*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawPixelBoundsEnforced(pos.x().count(), pos.y().count(), color)) {
78*20bfefbeSAndroid Build Coastguard Worker return error;
79*20bfefbeSAndroid Build Coastguard Worker }
80*20bfefbeSAndroid Build Coastguard Worker }
81*20bfefbeSAndroid Build Coastguard Worker }
82*20bfefbeSAndroid Build Coastguard Worker return Error::OK;
83*20bfefbeSAndroid Build Coastguard Worker };
84*20bfefbeSAndroid Build Coastguard Worker
85*20bfefbeSAndroid Build Coastguard Worker if (roundTopLeft_) {
86*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawCorner(0, 0)) return error;
87*20bfefbeSAndroid Build Coastguard Worker } else {
88*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(
89*20bfefbeSAndroid Build Coastguard Worker Box<intpxs>(0, 0, intRadius, intRadius).translate(intBounds.topLeft()), color_)) {
90*20bfefbeSAndroid Build Coastguard Worker return error;
91*20bfefbeSAndroid Build Coastguard Worker }
92*20bfefbeSAndroid Build Coastguard Worker }
93*20bfefbeSAndroid Build Coastguard Worker
94*20bfefbeSAndroid Build Coastguard Worker if (roundTopRight_) {
95*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawCorner(1, 0)) return error;
96*20bfefbeSAndroid Build Coastguard Worker } else {
97*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(Box<intpxs>(intBounds.w() - intRadius, 0, intRadius, intRadius)
98*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
99*20bfefbeSAndroid Build Coastguard Worker color_)) {
100*20bfefbeSAndroid Build Coastguard Worker return error;
101*20bfefbeSAndroid Build Coastguard Worker }
102*20bfefbeSAndroid Build Coastguard Worker }
103*20bfefbeSAndroid Build Coastguard Worker
104*20bfefbeSAndroid Build Coastguard Worker if (roundBottomLeft_) {
105*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawCorner(0, 1)) return error;
106*20bfefbeSAndroid Build Coastguard Worker } else {
107*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(Box<intpxs>(0, intBounds.h() - intRadius, intRadius, intRadius)
108*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
109*20bfefbeSAndroid Build Coastguard Worker color_)) {
110*20bfefbeSAndroid Build Coastguard Worker return error;
111*20bfefbeSAndroid Build Coastguard Worker }
112*20bfefbeSAndroid Build Coastguard Worker }
113*20bfefbeSAndroid Build Coastguard Worker
114*20bfefbeSAndroid Build Coastguard Worker if (roundBottomRight_) {
115*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawCorner(1, 1)) return error;
116*20bfefbeSAndroid Build Coastguard Worker } else {
117*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(Box<intpxs>(intBounds.w() - intRadius, intBounds.h() - intRadius,
118*20bfefbeSAndroid Build Coastguard Worker intRadius, intRadius)
119*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
120*20bfefbeSAndroid Build Coastguard Worker color_)) {
121*20bfefbeSAndroid Build Coastguard Worker return error;
122*20bfefbeSAndroid Build Coastguard Worker }
123*20bfefbeSAndroid Build Coastguard Worker }
124*20bfefbeSAndroid Build Coastguard Worker
125*20bfefbeSAndroid Build Coastguard Worker auto centerbox = Box<intpxs>(intRadius, intRadius, intBounds.w() - intRadius - intRadius,
126*20bfefbeSAndroid Build Coastguard Worker intBounds.h() - intRadius - intRadius)
127*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft());
128*20bfefbeSAndroid Build Coastguard Worker
129*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(centerbox, color_)) return error;
130*20bfefbeSAndroid Build Coastguard Worker
131*20bfefbeSAndroid Build Coastguard Worker if (auto error =
132*20bfefbeSAndroid Build Coastguard Worker drawBox(Box<intpxs>(0, intRadius, intRadius, intBounds.h() - intRadius - intRadius)
133*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
134*20bfefbeSAndroid Build Coastguard Worker color_)) {
135*20bfefbeSAndroid Build Coastguard Worker return error;
136*20bfefbeSAndroid Build Coastguard Worker }
137*20bfefbeSAndroid Build Coastguard Worker if (auto error =
138*20bfefbeSAndroid Build Coastguard Worker drawBox(Box<intpxs>(intRadius, 0, intBounds.w() - intRadius - intRadius, intRadius)
139*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
140*20bfefbeSAndroid Build Coastguard Worker color_)) {
141*20bfefbeSAndroid Build Coastguard Worker return error;
142*20bfefbeSAndroid Build Coastguard Worker }
143*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(Box<intpxs>(intBounds.w() - intRadius, intRadius, intRadius,
144*20bfefbeSAndroid Build Coastguard Worker intBounds.h() - intRadius - intRadius)
145*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
146*20bfefbeSAndroid Build Coastguard Worker color_)) {
147*20bfefbeSAndroid Build Coastguard Worker return error;
148*20bfefbeSAndroid Build Coastguard Worker }
149*20bfefbeSAndroid Build Coastguard Worker if (auto error = drawBox(Box<intpxs>(intRadius, intBounds.h() - intRadius,
150*20bfefbeSAndroid Build Coastguard Worker intBounds.w() - intRadius - intRadius, intRadius)
151*20bfefbeSAndroid Build Coastguard Worker .translate(intBounds.topLeft()),
152*20bfefbeSAndroid Build Coastguard Worker color_)) {
153*20bfefbeSAndroid Build Coastguard Worker return error;
154*20bfefbeSAndroid Build Coastguard Worker }
155*20bfefbeSAndroid Build Coastguard Worker
156*20bfefbeSAndroid Build Coastguard Worker bool hasCOs = coBegin != coEnd;
157*20bfefbeSAndroid Build Coastguard Worker if (hasCOs) {
158*20bfefbeSAndroid Build Coastguard Worker Box<pxs> coBBox = Box<pxs>::boundingBox(coBegin->begin, coBegin->end);
159*20bfefbeSAndroid Build Coastguard Worker for (const auto& co : makeRange(coBegin + 1, coEnd)) {
160*20bfefbeSAndroid Build Coastguard Worker coBBox = coBBox.merge(co.begin, co.end);
161*20bfefbeSAndroid Build Coastguard Worker }
162*20bfefbeSAndroid Build Coastguard Worker
163*20bfefbeSAndroid Build Coastguard Worker auto start = PxPoint{bounds.w() - coBBox.w(), bounds.h() - coBBox.h()} / pxs(2.0);
164*20bfefbeSAndroid Build Coastguard Worker start += bounds.topLeft();
165*20bfefbeSAndroid Build Coastguard Worker
166*20bfefbeSAndroid Build Coastguard Worker Box<intpxs> intBBox(start.x().floor(), start.y().floor(), 0, 0);
167*20bfefbeSAndroid Build Coastguard Worker intBBox = intBBox.merge(
168*20bfefbeSAndroid Build Coastguard Worker Point<intpxs>{(start.x() + coBBox.w()).ceil(), (start.y() + coBBox.h()).ceil()});
169*20bfefbeSAndroid Build Coastguard Worker
170*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << "coBBox: " << coBBox << ENDL;
171*20bfefbeSAndroid Build Coastguard Worker
172*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << "intBBox: " << intBBox << ENDL;
173*20bfefbeSAndroid Build Coastguard Worker for (int64_t y = 0; y < intBBox.h().count(); ++y) {
174*20bfefbeSAndroid Build Coastguard Worker for (int64_t x = 0; x < intBBox.w().count(); ++x) {
175*20bfefbeSAndroid Build Coastguard Worker PxPoint offset = coBBox.topLeft() + PxPoint{x, y};
176*20bfefbeSAndroid Build Coastguard Worker // The pixel is a square of width and height 1.0
177*20bfefbeSAndroid Build Coastguard Worker auto thePixel = makeSquareAtOffset(offset, 1.0);
178*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << thePixel << ENDL;
179*20bfefbeSAndroid Build Coastguard Worker pxs areaCovered = 0.0;
180*20bfefbeSAndroid Build Coastguard Worker for (const auto& co : makeRange(coBegin, coEnd)) {
181*20bfefbeSAndroid Build Coastguard Worker auto coveredRegion = thePixel.intersect<10>(co.begin, co.end);
182*20bfefbeSAndroid Build Coastguard Worker if (coveredRegion) areaCovered += coveredRegion->area();
183*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << " region: " << (bool)coveredRegion << " area: " << areaCovered;
184*20bfefbeSAndroid Build Coastguard Worker }
185*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << ENDL;
186*20bfefbeSAndroid Build Coastguard Worker if (areaCovered > 1.0) areaCovered = 1.0;
187*20bfefbeSAndroid Build Coastguard Worker TEEUI_LOG << "x: " << x << " y: " << y << " area: " << areaCovered << ENDL;
188*20bfefbeSAndroid Build Coastguard Worker uint32_t intensity = 0xff * areaCovered.count();
189*20bfefbeSAndroid Build Coastguard Worker if (auto error =
190*20bfefbeSAndroid Build Coastguard Worker drawPixelBoundsEnforced(intBBox.x().count() + x, intBBox.y().count() + y,
191*20bfefbeSAndroid Build Coastguard Worker intensity << 24 | (0xffffff & convexObjectColor_)))
192*20bfefbeSAndroid Build Coastguard Worker return error;
193*20bfefbeSAndroid Build Coastguard Worker }
194*20bfefbeSAndroid Build Coastguard Worker }
195*20bfefbeSAndroid Build Coastguard Worker }
196*20bfefbeSAndroid Build Coastguard Worker
197*20bfefbeSAndroid Build Coastguard Worker return Error::OK;
198*20bfefbeSAndroid Build Coastguard Worker }
199*20bfefbeSAndroid Build Coastguard Worker
200*20bfefbeSAndroid Build Coastguard Worker } // namespace teeui
201