#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(); }