~ubuntu-branches/debian/sid/fbterm/sid

« back to all changes in this revision

Viewing changes to src/screen_clip.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2009-12-01 23:12:53 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091201231253-0t86i1w6d7t8nhgi
Tags: 1.6-1
* New upstream release
* Change e-mail address.
* Remove DM-Upload-Allowed field.
* Update Standards-Version.
* Add README.source file.
* Update patch.
  patches/01_add_terminfo_path.dpatch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *   Copyright © 2008-2009 dragchan <zgchan317@gmail.com>
3
 
 *   This file is part of FbTerm.
4
 
 *
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.
9
 
 *
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.
14
 
 *
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.
18
 
 *
19
 
 */
20
 
 
21
 
#include <string.h>
22
 
#include "immessage.h"
23
 
 
24
 
typedef enum { InSide = 0, Intersect, OutSide } IntersectState;
25
 
 
26
 
static Rectangle clipRects[NR_IM_WINS], rotatedClipRects[NR_IM_WINS];
27
 
static u32 clipRectNum = 0;
28
 
bool clipEnable = false;
29
 
 
30
 
static inline u32 intersectRect(const Rectangle &R, const Rectangle &r)
31
 
{
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;
34
 
        return Intersect;
35
 
}
36
 
 
37
 
static u32 subtractRect(const Rectangle &R, Rectangle& r, Rectangle *rects)
38
 
{
39
 
        if (r.sx >= r.ex || r.sy >= r.ey) return 0;
40
 
 
41
 
        u32 add = 0;
42
 
        u32 state = intersectRect(R, r);
43
 
 
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) };
47
 
 
48
 
                if (ir.sy != r.sy) {
49
 
                        Rectangle tmp = { r.sx, r.sy, r.ex, ir.sy };
50
 
                        *rects++ = tmp;
51
 
                        add++;
52
 
                }
53
 
 
54
 
                if (ir.ey != r.ey) {
55
 
                        Rectangle tmp = { r.sx, ir.ey, r.ex, r.ey };
56
 
                        *rects++ = tmp;
57
 
                        add++;
58
 
                }
59
 
 
60
 
                if (ir.sx != r.sx) {
61
 
                        Rectangle tmp = { r.sx, ir.sy, ir.sx, ir.ey };
62
 
                        *rects++ = tmp;
63
 
                        add++;
64
 
                }
65
 
 
66
 
                if (ir.ex != r.ex) {
67
 
                        Rectangle tmp = { ir.ex, ir.sy, r.ex, ir.ey };
68
 
                        *rects++ = tmp;
69
 
                        add++;
70
 
                }
71
 
 
72
 
                add--;
73
 
                r = *--rects;
74
 
        } else if (state == InSide) {
75
 
                r.ex = r.sx;
76
 
                r.ey = r.sy;
77
 
        }
78
 
 
79
 
        return add;
80
 
}
81
 
 
82
 
static u32 intersectWithClipRects(const Rectangle &r)
83
 
{
84
 
        u32 ret = OutSide;
85
 
 
86
 
        for (u32 i = clipRectNum; i--;) {
87
 
                u32 state = intersectRect(clipRects[i], r);
88
 
 
89
 
                if (ret > state) ret = state;
90
 
                if (ret == InSide) break;
91
 
        }
92
 
 
93
 
        return ret;
94
 
}
95
 
 
96
 
static bool subtractWithRotatedClipRects(const Rectangle &rect, Rectangle *&rects, u32 &num)
97
 
{
98
 
        if (!clipRectNum) return false;
99
 
 
100
 
        #define NR_SUBTRACT_RECTS 40
101
 
        static Rectangle rs[NR_SUBTRACT_RECTS];
102
 
        rects = rs;
103
 
 
104
 
        rects[0] = rect;
105
 
        num = 1;
106
 
 
107
 
        u32 size = NR_SUBTRACT_RECTS;
108
 
        bool isalloc = false;
109
 
 
110
 
        for (u32 i = clipRectNum; i--;) {
111
 
                for (u32 j = num; j--;) {
112
 
                        if (num > size - 4) {
113
 
                                size *= 2;
114
 
                                Rectangle *nrects = new Rectangle[size];
115
 
                                memcpy(nrects, rects, sizeof(Rectangle) * num);
116
 
 
117
 
                                if (isalloc) delete[] rects;
118
 
 
119
 
                                isalloc = true;
120
 
                                rects = nrects;
121
 
                        }
122
 
 
123
 
                        num += subtractRect(rotatedClipRects[i], rects[j], rects + num);
124
 
                }
125
 
        }
126
 
 
127
 
        return isalloc;
128
 
}
129
 
 
130
 
void Screen::setClipRects(Rectangle *rects, u32 num)
131
 
{
132
 
        if ((!rects && num) || num > NR_IM_WINS) return;
133
 
        clipEnable = num;
134
 
 
135
 
        Rectangle oldRects[clipRectNum];
136
 
        memcpy(oldRects, clipRects, sizeof(Rectangle) * clipRectNum);
137
 
 
138
 
        u32 oldNum = clipRectNum;
139
 
        clipRectNum = 0;
140
 
 
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;
146
 
 
147
 
                if (rects[i].sx >= rects[i].ex || rects[i].sy >= rects[i].ey) continue;
148
 
 
149
 
                clipRects[clipRectNum] = rects[i];
150
 
 
151
 
                u32 x = rects[i].sx, y = rects[i].sy;
152
 
                u32 w = rects[i].ex - x, h = rects[i].ey - y;
153
 
 
154
 
                rotateRect(x, y, w, h);
155
 
 
156
 
                rotatedClipRects[clipRectNum].sx = x;
157
 
                rotatedClipRects[clipRectNum].sy = y;
158
 
                rotatedClipRects[clipRectNum].ex = x + w;
159
 
                rotatedClipRects[clipRectNum++].ey = y + h;
160
 
        }
161
 
 
162
 
        for (u32 i = 0; i < oldNum; i++) {
163
 
                if (intersectWithClipRects(oldRects[i]) == InSide) continue;
164
 
 
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);
169
 
 
170
 
                redraw(scol, srow, ecol - scol + 1, erow - srow + 1);
171
 
 
172
 
                if (ecol >= mCols) {
173
 
                        fillRect(FW(mCols), oldRects[i].sy, oldRects[i].ex - FW(mCols), oldRects[i].ey - oldRects[i].sy, 0);
174
 
                }
175
 
 
176
 
                if (erow >= mRows) {
177
 
                        fillRect(oldRects[i].sx, FH(mRows), oldRects[i].ex - oldRects[i].sx, oldRects[i].ey - FH(mRows), 0);
178
 
                }
179
 
        }
180
 
}