ultimatepp/uppdev/Glyph/help.txt
cxl 27351ba2cb .uppdev
git-svn-id: svn://ultimatepp.org/upp/trunk@6106 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2013-05-26 17:35:34 +00:00

294 lines
7.2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

g = Memory at 007A18D8, size 0x45 = 69
+0 0x007A18D8 0A 0C 15 15 01 80 B8 E5 F9 E7 BD 81 02 D5 45 DA .....€¸åùç½<C3A7>.ÕEÚ
+16 0x007A18E8 01 A5 41 E6 9B 84 98 E5 41 A9 DA 41 93 03 9C 41 .¥Aæ˜åA©ÚA“.œA
+32 0x007A18F8 DC ED 47 EE FB 47 FD F0 41 8C 06 DE 41 B2 06 AB ÜíGîûGýðAŒ.ÞA².«
+48 0x007A1908 41 F7 AA 86 92 CD 41 DA 80 DB 45 F7 96 01 81 BB A÷ª†ÍAÚ€ÛE÷.<2E>»
+64 0x007A1918 E4 F9 F1 D3 94 äùñÓ”
g = Memory at 006618D8, size 0x46 = 70
+0 0x006618D8 0A 0C 15 15 01 80 B8 E5 F9 E7 BD 81 02 D5 45 DA .....€¸åùç½<C3A7>.ÕEÚ
+16 0x006618E8 01 A5 41 E6 9B 84 98 E5 41 A9 DA 41 93 03 9C 41 .¥Aæ˜åA©ÚA“.œA
+32 0x006618F8 DC ED 47 EE FB 47 FD F0 41 8C 06 DE 41 B2 06 AB ÜíGîûGýðAŒ.ÞA².«
+48 0x00661908 41 F7 AA 86 92 CD 41 DA 80 DB 45 F7 96 01 81 BB A÷ª†ÍAÚ€ÛE÷.<2E>»
+64 0x00661918 E4 F9 F1 D3 94 01 äùñÓ”.
#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>
#include "glyph.h"
using namespace Upp;
#define IMAGECLASS GlyphImg
#define IMAGEFILE <Glyph/glyph.iml>
#include <Draw/iml_header.h>
#define IMAGECLASS GlyphImg
#define IMAGEFILE <Glyph/glyph.iml>
#include <Draw/iml_source.h>
bool IsUniform(const RGBA *s, RGBA c, int add, int n)
{
while(n-- > 0) {
if(*s != c)
return false;
s += add;
}
return true;
}
Image AutoCrop(const Image& m, RGBA c)
{
Size isz = m.GetSize();
Rect r = isz;
for(r.top = 0; r.top < isz.cy && IsUniform(m[r.top], c, 1, isz.cx); r.top++)
;
for(r.bottom = isz.cy - 1; r.bottom >= r.top && IsUniform(m[r.bottom], c, 1, isz.cx); r.bottom--)
;
if(r.bottom <= r.top)
return Null;
int h = r.GetHeight();
const RGBA *p = m[r.top];
for(r.left = 0; r.left < isz.cy && IsUniform(p + r.left, c, isz.cx, h); r.left++)
;
for(r.right = isz.cx; r.right >= r.left && IsUniform(p + r.right, c, isz.cx, h); r.right--)
;
r.right++;
r.bottom++;
return WithHotSpot(Crop(m, r), 20, 20);
}
Image RenderGlyph(Font fnt, int chr)
{
int cx = fnt[chr];
int cy = fnt.GetLineHeight();
ImageBuffer ib(2 * cx, 2 * cy);
BufferPainter sw(ib, MODE_ANTIALIASED);
sw.Clear(RGBAZero());
sw.DrawText(cx / 2, cy / 2, WString(chr, 1), fnt, Black());
ib.SetHotSpot(Point(20, 20));
return ib;
}
String CompressGlyph(const Image& m)
{
const RGBA *s = m;
const RGBA *e = s + m.GetLength();
StringStream r;
Size sz = m.GetSize();
r / sz.cx / sz.cy;
Point p = m.GetHotSpot();
r / p.x / p.y;
while(s < e) {
const RGBA *b = s;
if(s->a == 0 || s->a == 255) {
byte a = s->a;
s++;
while(s < e && s - b < 63 && s->a == a)
s++;
if(a == 0 && s >= e)
return r;
r.Put((a & 0x40) | (s - b));
}
else {
r.Put((s->a >> 1) | 0x80);
s++;
}
}
return r;
}
Image DecompressGlyph(const String& g, Color c)
{
StringStream r(g);
Size sz;
r / sz.cx / sz.cy;
ImageBuffer ib(sz);
Point p;
ib.SetHotSpot(p);
r / p.x / p.y;
RGBA *t = ib;
RGBA *te = ib.End();
RGBA full = c;
while(!r.IsEof()) {
byte b = r.Get();
ASSERT(t < te);
if(b & 0x80)
*t++ = (((b & 0x7f) << 1) | ((b & 0x40) >> 6)) * c;
else {
int n = b & 63;
ASSERT(t + n <= te);
Fill(t, b & 0x40 ? full : RGBAZero(), n);
t += n;
}
}
Fill(t, RGBAZero(), te - t);
return ib;
}
struct ColorRenderer : MiniRenderer
{
Draw *draw;
Color color;
virtual void PutHorz(int x, int y, int cx) {
draw->DrawRect(x, y, cx, 1, color);
}
virtual void PutVert(int x, int y, int cy) {
draw->DrawRect(x, y, 1, cy, color);
}
};
struct MyApp : TopWindow {
Point p;
virtual void Paint(Draw& w);
virtual void MouseMove(Point p, dword keyflags);
virtual Image CursorImage(Point p, dword keyflags);
};
Image MyApp::CursorImage(Point p, dword keyflags)
{
return GlyphImg::cursor();
}
void MyApp::MouseMove(Point p_, dword keyflags)
{
p = p_;
Refresh();
}
void DrawLine(Draw& w, Point p1, Point p2)
{
DLOG("----------------");
int dirx = sgn(p2.x - p1.x);
int diry = sgn(p2.y - p1.y);
int dx = abs(p2.x - p1.x);
int dy = abs(p2.y - p1.y);
int x = p1.x;
int y = p1.y;
int x0 = x;
int y0 = y;
if(dx < dy) {
int dda = dy >> 1;
int n = dy;
for(;;) {
if(x != x0) {
if(y0 < y)
w.DrawRect(x0, y0, 1, y - y0, LtBlue());
else
w.DrawRect(x0, y + 1, 1, y0 - y, LtBlue());
x0 = x;
y0 = y;
}
y += diry;
if(n-- <= 0)
break;
dda -= dx;
if(dda < 0) {
dda += dy;
x += dirx;
}
}
if(y0 < y)
w.DrawRect(x0, y0, 1, y - y0, LtBlue());
else
w.DrawRect(x0, y + 1, 1, y0 - y, LtBlue());
}
else {
int dda = dx >> 1;
int n = dx;
for(;;) {
if(y != y0) {
if(x0 < x)
w.DrawRect(x0, y0, x - x0, 1, LtBlue());
else
w.DrawRect(x + 1, y0, x0 - x, 1, LtBlue());
x0 = x;
y0 = y;
}
x += dirx;
if(n-- <= 0)
break;
dda -= dy;
if(dda < 0) {
dda += dx;
y += diry;
}
}
if(x0 < x)
w.DrawRect(x0, y0, x - x0, 1, LtBlue());
else
w.DrawRect(x + 1, y0, x0 - x, 1, LtBlue());
}
}
void MyApp::Paint(Draw& w)
{
w.DrawRect(GetSize(), White());
// DWORD gdiCount = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
// w.DrawText(400, 0, AsString(gdiCount));
w.DrawImage(0, 0, RenderGlyph(Arial(20), 'e'));
String g = CompressGlyph(AutoCrop(RenderGlyph(Arial(20), 'e'), RGBAZero()));
w.DrawImage(20, 0, DecompressGlyph(g, White()));
w.DrawImage(0, 50, DecompressGlyph(g, Black()));
Point p0(300, 300);
w.DrawLine(p0, p, 0, LtGray());
w.DrawRect(p0.x - 1, p0.y - 1, 3, 3, LtGray());
ColorRenderer r;
r.draw = &w;
r.color = Red();
r.Line(p0, p);
// __BREAK__;
}
GUI_APP_MAIN
{
{
for(int i = 0; i < 10000; i++) {
RTIMING("RenderGlyph");
RenderGlyph(Arial(20), 'e');
}
String g = CompressGlyph(AutoCrop(RenderGlyph(Arial(20), 'e'), RGBAZero()));
RDUMPHEX(g);
for(int i = 0; i < 10000; i++) {
RTIMING("DecompressGlyph");
DecompressGlyph(g, White());
}
}
for(const char *s = "compres"; *s; s++)
for(int n = 10; n <= 100; n += 10) {
RLOG("-------------");
RLOG(n << ' ' << *s);
Size sz = AutoCrop(RenderGlyph(StdFont(n), *s), RGBAZero()).GetSize();
RDUMP(sz);
RDUMP(sz.cx * sz.cy);
RDUMP(CompressGlyph(AutoCrop(RenderGlyph(StdFont(n), *s), RGBAZero())).GetLength());
}
MyApp().Run();
}
String txt = LoadFile(GetDataFile("text.qtf"));
{
RTIMING("SDraw");
ParseQTF(txt).Paint(Zoom(2, 10), fw, 0, 0, sz.cx);
}
{
RTIMING("Draw");
// ParseQTF(txt).Paint(Zoom(2, 10), w, 0, 0, sz.cx);
}
TIMING Painter : 2.11 s - 11.39 ms ( 2.11 s / 185 ), min: 7.00 ms, max: 16.00 ms, nesting: 1 - 185
TIMING Draw : 117.99 ms - 637.79 us (118.00 ms / 185 ), min: 0.00 ns, max: 7.00 ms, nesting: 1 - 185
TIMING Render glyph : 5.99 ms - 49.95 us ( 6.00 ms / 120 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 120
TIMING Paint glyph : 944.23 ms - 6.49 us (951.00 ms / 145410 ), min: 0.00 ns, max: 3.00 ms, nesting: 1 - 145410
TIMING SDraw : 1.10 s - 5.94 ms ( 1.10 s / 185 ), min: 4.00 ms, max: 18.00 ms, nesting: 1 - 185