1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/**
17 * @brief Defines Base renderer
18 * @since 1.0
19 * @version 1.0.
20 */
21
22#include "render_base.h"
23
24namespace OHOS {
25void RenderBase::Attach(RenderPixfmtRgbaBlend& ren)
26{
27    pixfmtType_ = &ren;
28    clipBox_.SetRect(0, 0, ren.GetWidth() - 1, ren.GetHeight() - 1);
29}
30
31bool RenderBase::ClipBox(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
32{
33    Rect32 cb(x1, y1, x2, y2);
34    cb.Normalize();
35    if (cb.Intersect(cb, Rect32(0, 0, GetWidth() - 1, GetHeight() - 1))) {
36        clipBox_.SetRect(cb.GetLeft(), cb.GetTop(), cb.GetRight(), cb.GetBottom());
37        return true;
38    }
39    ClipBoxNaked(1, 1, 0, 0);
40    return false;
41}
42
43void RenderBase::ResetClipping(bool visibility)
44{
45    if (visibility) {
46        ClipBoxNaked(0, 0, GetWidth() - 1, GetHeight() - 1);
47    } else {
48        ClipBoxNaked(1, 1, 0, 0);
49    }
50}
51
52void RenderBase::ClipBoxNaked(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
53{
54    clipBox_.SetRect(x1, y1, x2, y2);
55}
56
57void RenderBase::Clear(const Rgba8T& color)
58{
59    if (GetWidth()) {
60        for (uint32_t y = 0; y < GetHeight(); y++) {
61            pixfmtType_->CopyHLine(0, y, GetWidth(), color);
62        }
63    }
64}
65
66void RenderBase::BlendHLine(int32_t x1, int32_t y, int32_t x2, const Rgba8T& color, uint8_t cover)
67{
68    if (x1 > x2) {
69        int32_t swapTemp = x1;
70        x1 = x2;
71        x2 = swapTemp;
72    }
73    if (y > GetYMax() || y < GetYMin() || x1 > GetXMax() || x2 < GetXMin()) {
74        return;
75    }
76    if (x1 < GetXMin()) {
77        x1 = GetXMin();
78    }
79
80    if (x2 > GetXMax()) {
81        x2 = GetXMax();
82    }
83    pixfmtType_->BlendHLine(x1, y, x2 - x1 + 1, color, cover);
84}
85
86void RenderBase::BlendSolidHSpan(int32_t x, int32_t y, int32_t len, const Rgba8T& color, const uint8_t* covers)
87{
88    if (y > GetYMax() || y < GetYMin()) {
89        return;
90    }
91    if (x < GetXMin()) {
92        len -= GetXMin() - x;
93        if (len <= 0) {
94            return;
95        }
96        covers += GetXMin() - x;
97        x = GetXMin();
98    }
99    if (x + len > GetXMax()) {
100        len = GetXMax() - x + 1;
101        if (len <= 0) {
102            return;
103        }
104    }
105    pixfmtType_->BlendSolidHSpan(x, y, len, color, covers);
106}
107
108void RenderBase::CopyColorHSpan(int32_t x, int32_t y, int32_t len, const Rgba8T* colors)
109{
110    const uint8_t* covers = nullptr;
111    if (!ColorHSpanHandler(x, y, len, colors, covers)) {
112        return;
113    }
114    pixfmtType_->CopyColorHSpan(x, y, len, colors);
115}
116
117void RenderBase::BlendColorHSpan(int32_t x, int32_t y, int32_t len, const Rgba8T* colors, const uint8_t* covers,
118                                 uint8_t cover)
119{
120    if (!ColorHSpanHandler(x, y, len, colors, covers)) {
121        return;
122    }
123    pixfmtType_->BlendColorHSpan(x, y, len, colors, covers, cover);
124}
125
126bool RenderBase::ColorHSpanHandler(int32_t& x, const int32_t& y, int32_t& len, const Rgba8T*& colors,
127                                   const uint8_t*& covers) const
128{
129    if (y > GetYMax() || y < GetYMin()) {
130        return false;
131    }
132    if (x < GetXMin()) {
133        int32_t d = GetXMin() - x;
134        len -= d;
135        if (len <= 0) {
136            return false;
137        }
138        if (covers) {
139            covers += d;
140        }
141        colors += d;
142        x = GetXMin();
143    }
144    if (x + len > GetXMax()) {
145        len = GetXMax() - x + 1;
146        if (len <= 0) {
147            return false;
148        }
149    }
150    return true;
151}
152} // namespace OHOS
153