2
* Copyright © 2008-2009 dragchan <zgchan317@gmail.com>
3
* This file is part of FbTerm.
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
#include "immessage.h"
24
typedef enum { InSide = 0, Intersect, OutSide } IntersectState;
26
static Rectangle clipRects[NR_IM_WINS], rotatedClipRects[NR_IM_WINS];
27
static u32 clipRectNum = 0;
28
bool clipEnable = false;
30
static inline u32 intersectRect(const Rectangle &R, const Rectangle &r)
32
if (R.sy >= r.ey || R.ey <= r.sy || R.sx >= r.ex || R.ex <= r.sx) return OutSide;
33
if (r.sy >= R.sy && r.ey <= R.ey && r.sx >= R.sx && r.ex <= R.ex) return InSide;
37
static u32 subtractRect(const Rectangle &R, Rectangle& r, Rectangle *rects)
39
if (r.sx >= r.ex || r.sy >= r.ey) return 0;
42
u32 state = intersectRect(R, r);
44
if (state == OutSide) ;
45
else if (state == Intersect) {
46
Rectangle ir = { MAX(R.sx, r.sx), MAX(R.sy, r.sy), MIN(R.ex, r.ex), MIN(R.ey, r.ey) };
49
Rectangle tmp = { r.sx, r.sy, r.ex, ir.sy };
55
Rectangle tmp = { r.sx, ir.ey, r.ex, r.ey };
61
Rectangle tmp = { r.sx, ir.sy, ir.sx, ir.ey };
67
Rectangle tmp = { ir.ex, ir.sy, r.ex, ir.ey };
74
} else if (state == InSide) {
82
static u32 intersectWithClipRects(const Rectangle &r)
86
for (u32 i = clipRectNum; i--;) {
87
u32 state = intersectRect(clipRects[i], r);
89
if (ret > state) ret = state;
90
if (ret == InSide) break;
96
static bool subtractWithRotatedClipRects(const Rectangle &rect, Rectangle *&rects, u32 &num)
98
if (!clipRectNum) return false;
100
#define NR_SUBTRACT_RECTS 40
101
static Rectangle rs[NR_SUBTRACT_RECTS];
107
u32 size = NR_SUBTRACT_RECTS;
108
bool isalloc = false;
110
for (u32 i = clipRectNum; i--;) {
111
for (u32 j = num; j--;) {
112
if (num > size - 4) {
114
Rectangle *nrects = new Rectangle[size];
115
memcpy(nrects, rects, sizeof(Rectangle) * num);
117
if (isalloc) delete[] rects;
123
num += subtractRect(rotatedClipRects[i], rects[j], rects + num);
130
void Screen::setClipRects(Rectangle *rects, u32 num)
132
if ((!rects && num) || num > NR_IM_WINS) return;
135
Rectangle oldRects[clipRectNum];
136
memcpy(oldRects, clipRects, sizeof(Rectangle) * clipRectNum);
138
u32 oldNum = clipRectNum;
141
for (u32 i = 0; i < num; i++) {
142
if (rects[i].sx >= screenw) rects[i].sx = screenw;
143
if (rects[i].ex >= screenw) rects[i].ex = screenw;
144
if (rects[i].sy >= screenh) rects[i].sy = screenh;
145
if (rects[i].ey >= screenh) rects[i].ey = screenh;
147
if (rects[i].sx >= rects[i].ex || rects[i].sy >= rects[i].ey) continue;
149
clipRects[clipRectNum] = rects[i];
151
u32 x = rects[i].sx, y = rects[i].sy;
152
u32 w = rects[i].ex - x, h = rects[i].ey - y;
154
rotateRect(x, y, w, h);
156
rotatedClipRects[clipRectNum].sx = x;
157
rotatedClipRects[clipRectNum].sy = y;
158
rotatedClipRects[clipRectNum].ex = x + w;
159
rotatedClipRects[clipRectNum++].ey = y + h;
162
for (u32 i = 0; i < oldNum; i++) {
163
if (intersectWithClipRects(oldRects[i]) == InSide) continue;
165
u16 scol = oldRects[i].sx / FW(1);
166
u16 ecol = (oldRects[i].ex - 1) / FW(1);
167
u16 srow = oldRects[i].sy / FH(1);
168
u16 erow = (oldRects[i].ey - 1) / FH(1);
170
redraw(scol, srow, ecol - scol + 1, erow - srow + 1);
173
fillRect(FW(mCols), oldRects[i].sy, oldRects[i].ex - FW(mCols), oldRects[i].ey - oldRects[i].sy, 0);
177
fillRect(oldRects[i].sx, FH(mRows), oldRects[i].ex - oldRects[i].sx, oldRects[i].ey - FH(mRows), 0);