ultimatepp/uppdev/CDraw/aa2.cpp
cxl 351994a6cc Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

177 lines
3.4 KiB
C++

#include "MDraw.h"
String aa_packed;
INITBLOCK {
static const byte n_o[] = {
// 0 1 2 3 4 5
0x00, 0x80, 0xff, 0xff, 0x80, 0x00,
0x00, 0xff, 0x10, 0x10, 0xff, 0x00,
0x80, 0x80, 0x00, 0x00, 0xff, 0x80,
0xb0, 0x70, 0x00, 0x00, 0x70, 0xb0,
0xe0, 0x30, 0x00, 0x00, 0x30, 0xe0,
0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
0xe0, 0x30, 0x00, 0x00, 0x30, 0xe0,
0xb0, 0x70, 0x00, 0x00, 0x70, 0xb0,
0x80, 0x80, 0x00, 0x00, 0xff, 0x80,
0x00, 0xff, 0x10, 0x10, 0xff, 0x00,
0x00, 0x80, 0xff, 0xff, 0x80, 0x00,
};
StringBuffer pk;
for(int w = 0; w < 11; w++) {
int n = 0;
const byte *ln = n_o + w * 6;
int last = -1;
for(int q = 0; q < 6; q++)
if(ln[q]) {
int m = 0;
String data;
while(q < 6 && ln[q]) {
data.Cat(ln[q]);
m++;
q++;
}
while(n > 15) {
pk.Cat((15 << 3));
n -= 15;
}
if(m > 7) {
pk.Cat((n << 3) | 7);
m -= 7;
while(m > 7) {
pk.Cat(7);
m -= 7;
}
if(m)
pk.Cat(m);
}
else
pk.Cat((n << 3) | m);
last = pk.GetCount() - 1;
pk.Cat(data); // Not quite correct!!!
n = 1;
}
else
n++;
if(last < 0)
pk.Cat(0x80);
else
pk[last] |= 0x80;
}
pk.Cat(0);
aa_packed = pk;
LOGHEXDUMP(~aa_packed, aa_packed.GetCount());
}
#define AAP_(b) \
m = (byte *)&t[b]; \
alpha = s[b] + (s[b] >> 7); \
m[0] += alpha * (tr - m[0]) >> 8; \
m[1] += alpha * (tg - m[1]) >> 8; \
m[2] += alpha * (tb - m[2]) >> 8;
void DrawAAP(PixelBlock& w, int x, int y, Color c)
{
if(!Rect(w.GetSize()).Contains(Rect(x, y, x + 6, y + 11)))
return;
dword *a = w.PointAdr(x, y);
int d = w.LineDelta();
byte tr = c.GetR();
byte tg = c.GetG();
byte tb = c.GetB();
const byte *s = aa_packed;
dword *t = a;
byte *m;
int alpha;
for(;;) {
dword c = *s++;
if(c == 0)
break;
t += (c >> 3) & 15;
switch(c & 7) {
case 7:
AAP_(6);
case 6:
AAP_(5);
case 5:
AAP_(4);
case 4:
AAP_(3);
case 3:
AAP_(2);
case 2:
AAP_(1);
case 1:
AAP_(0);
}
t += c & 7;
s += c & 7;
if(c & 0x80) {
a += d;
t = a;
}
}
}
#define AAPMMX_(b) \
alpha = _mm_cvtsi32_si64(s[b]); \
alpha = _mm_unpacklo_pi16(alpha, alpha); \
alpha = _mm_unpacklo_pi32(alpha, alpha); \
h = _mm_srli_pi16(alpha, 7); \
alpha = _mm_adds_pi16(alpha, h); \
m = _mm_cvtsi32_si64(t[b]); \
m = _mm_unpacklo_pi8(m, zero); \
h = _mm_sub_pi16(mc, m); \
h = _mm_mullo_pi16(alpha, h); \
h = _mm_srli_pi16(h, 8); \
m = _mm_add_pi16(m, h); \
m = _mm_and_si64(m, mask); \
m = _mm_packs_pu16(m, m); \
t[b] = _mm_cvtsi64_si32(m); \
void DrawAAPMMX(PixelBlock& w, int x, int y, Color c)
{
if(!Rect(w.GetSize()).Contains(Rect(x, y, x + 6, y + 11)))
return;
dword *a = w.PointAdr(x, y);
int d = w.LineDelta();
__m64 zero = _mm_setzero_si64();
__m64 mc = _mm_unpacklo_pi8(_mm_cvtsi32_si64(c.GetRaw()), zero);
__m64 mask = _mm_set1_pi16(0xff);
const byte *s = aa_packed;
dword *t = a;
__m64 alpha;
__m64 h;
__m64 m;
for(;;) {
dword c = *s++;
if(c == 0)
break;
t += (c >> 3) & 15;
switch(c & 7) {
case 7:
AAPMMX_(6);
case 6:
AAPMMX_(5);
case 5:
AAPMMX_(4);
case 4:
AAPMMX_(3);
case 3:
AAPMMX_(2);
case 2:
AAPMMX_(1);
case 1:
AAPMMX_(0);
}
t += c & 7;
s += c & 7;
if(c & 0x80) {
a += d;
t = a;
}
}
_mm_empty();
}