mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
minor repository reorganization: obsolete directories moved to archive
git-svn-id: svn://ultimatepp.org/upp/trunk@1997 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
bc24b89946
commit
4bee3373e7
171 changed files with 73 additions and 76 deletions
567
archive/olddraw/Draw/Cham.cpp
Normal file
567
archive/olddraw/Draw/Cham.cpp
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
#if defined(_DEBUG) && 0
|
||||
#include <plugin/png/png.h>
|
||||
|
||||
inline void LOGPNG(const char *name, const Image& m)
|
||||
{
|
||||
PNGEncoder png;
|
||||
png.SaveFile(ConfigFile(name) + ".png", m);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define LOGPNG(a, b)
|
||||
|
||||
#endif
|
||||
|
||||
struct ChImageMaker : ImageMaker {
|
||||
Size sz;
|
||||
Rect sr;
|
||||
Image img;
|
||||
|
||||
virtual String Key() const;
|
||||
virtual Image Make() const;
|
||||
};
|
||||
|
||||
String ChImageMaker::Key() const
|
||||
{
|
||||
LTIMING("ChImageMaker::Key");
|
||||
StringBuffer b;
|
||||
int64 id = img.GetSerialId();
|
||||
b.Cat((const char *)&id, sizeof(id));
|
||||
b.Cat((const char *)&sz.cx, sizeof(sz.cx));
|
||||
b.Cat((const char *)&sz.cy, sizeof(sz.cy));
|
||||
b.Cat((const char *)&sr.left, sizeof(sr.left));
|
||||
b.Cat((const char *)&sr.right, sizeof(sr.right));
|
||||
b.Cat((const char *)&sr.top, sizeof(sr.top));
|
||||
b.Cat((const char *)&sr.bottom, sizeof(sr.bottom));
|
||||
return b;
|
||||
}
|
||||
|
||||
Image ChImageMaker::Make() const
|
||||
{
|
||||
LTIMING("ChImageMaker::Make");
|
||||
return Rescale(img, sz, sr);
|
||||
}
|
||||
|
||||
void ChDraw(Draw& w, int x, int y, int cx, int cy, const Image& img, const Rect& src)
|
||||
{
|
||||
LTIMING("ChDraw");
|
||||
if(cx > 0 && cy > 0) {
|
||||
ChImageMaker m;
|
||||
m.sz = Size(cx, cy);
|
||||
m.sr = src;
|
||||
m.img = img;
|
||||
w.DrawImage(x, y, MakeImage(m));
|
||||
}
|
||||
}
|
||||
|
||||
void ChDraw(Draw& w, const Rect& r, const Image& img, const Rect& src)
|
||||
{
|
||||
ChDraw(w, r.left, r.top, r.GetWidth(), r.GetHeight(), img, src);
|
||||
}
|
||||
|
||||
struct sChLookWith {
|
||||
Value look;
|
||||
Image img;
|
||||
Color (*colorfn)(int i);
|
||||
int ii;
|
||||
Color color;
|
||||
Point offset;
|
||||
};
|
||||
|
||||
Value ChLookWith(const Value& look, const Image& img, Point offset)
|
||||
{
|
||||
sChLookWith x;
|
||||
x.look = look;
|
||||
x.img = img;
|
||||
x.colorfn = NULL;
|
||||
x.color = Null;
|
||||
x.offset = offset;
|
||||
return RawToValue(x);
|
||||
}
|
||||
|
||||
Value ChLookWith(const Value& look, const Image& img, Color color, Point offset)
|
||||
{
|
||||
sChLookWith x;
|
||||
x.look = look;
|
||||
x.img = img;
|
||||
x.colorfn = NULL;
|
||||
x.color = color;
|
||||
x.offset = offset;
|
||||
return RawToValue(x);
|
||||
}
|
||||
|
||||
Value ChLookWith(const Value& look, const Image& img, Color (*color)(int i), int i, Point offset)
|
||||
{
|
||||
sChLookWith x;
|
||||
x.look = look;
|
||||
x.img = img;
|
||||
x.colorfn = color;
|
||||
x.ii = i;
|
||||
x.offset = offset;
|
||||
return RawToValue(x);
|
||||
}
|
||||
|
||||
Value sChOp(Draw& w, const Rect& r, const Value& v, int op);
|
||||
|
||||
struct sChBorder {
|
||||
const ColorF *border;
|
||||
Value face;
|
||||
};
|
||||
|
||||
Value ChBorder(const ColorF *colors, const Value& face)
|
||||
{
|
||||
sChBorder b;
|
||||
b.border = colors;
|
||||
b.face = face;
|
||||
return RawToValue(b);
|
||||
}
|
||||
|
||||
Value StdChLookFn(Draw& w, const Rect& r, const Value& v, int op)
|
||||
{
|
||||
if(IsType<sChLookWith>(v)) {
|
||||
const sChLookWith& x = ValueTo<sChLookWith>(v);
|
||||
if(op == LOOK_PAINT) {
|
||||
LOGPNG(AsString(x.img.GetSerialId()), x.img);
|
||||
ChPaint(w, r, x.look);
|
||||
Point p = r.CenterPos(x.img.GetSize()) + x.offset;
|
||||
if(x.colorfn)
|
||||
w.DrawImage(p.x, p.y, x.img, (*x.colorfn)(x.ii));
|
||||
else
|
||||
if(!IsNull(x.color))
|
||||
w.DrawImage(p.x, p.y, x.img, x.color);
|
||||
else
|
||||
w.DrawImage(p.x, p.y, x.img);
|
||||
return 1;
|
||||
}
|
||||
return sChOp(w, r, x.look, op);
|
||||
}
|
||||
if(IsType<sChBorder>(v)) {
|
||||
sChBorder b = ValueTo<sChBorder>(v);
|
||||
int n = (int)(intptr_t)*b.border;
|
||||
switch(op) {
|
||||
case LOOK_PAINT:
|
||||
ChPaint(w, r.Deflated(n), b.face);
|
||||
case LOOK_PAINTEDGE:
|
||||
DrawBorder(w, r, b.border);
|
||||
return 0;
|
||||
case LOOK_MARGINS:
|
||||
return Rect(n, n, n, n);
|
||||
case LOOK_ISBODYOPAQUE:
|
||||
case LOOK_ISOPAQUE:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(IsType<Color>(v)) {
|
||||
Color c = v;
|
||||
switch(op) {
|
||||
case LOOK_PAINT:
|
||||
w.DrawRect(r, c);
|
||||
return 0;
|
||||
case LOOK_PAINTEDGE:
|
||||
DrawFrame(w, r, c);
|
||||
return 0;
|
||||
case LOOK_MARGINS:
|
||||
return Rect(1, 1, 1, 1);
|
||||
case LOOK_ISBODYOPAQUE:
|
||||
case LOOK_ISOPAQUE:
|
||||
return !IsNull(c);
|
||||
}
|
||||
}
|
||||
if(IsType<Image>(v)) {
|
||||
Image img = v;
|
||||
Size isz = img.GetSize();
|
||||
Size sz = r.GetSize();
|
||||
Point p = img.GetHotSpot();
|
||||
Point p2 = img.Get2ndSpot();
|
||||
int tile = 0;
|
||||
if(p2.x || p2.y) {
|
||||
if(p2.x < p.x) {
|
||||
Swap(p2.x, p.x);
|
||||
tile = 1;
|
||||
}
|
||||
if(p2.y < p.y) {
|
||||
Swap(p2.y, p.y);
|
||||
tile += 2;
|
||||
}
|
||||
p2.x++;
|
||||
p2.y++;
|
||||
}
|
||||
else {
|
||||
p2.x = isz.cx - p.x;
|
||||
p2.y = isz.cy - p.y;
|
||||
if(p.x > isz.cx / 2) {
|
||||
tile = 1;
|
||||
p2.x = p.x;
|
||||
p.x = isz.cx - p.x - 1;
|
||||
}
|
||||
if(p.y > isz.cy / 2) {
|
||||
tile += 2;
|
||||
p2.y = p.y;
|
||||
p.y = isz.cy - p.y - 1;
|
||||
}
|
||||
}
|
||||
if(op == LOOK_MARGINS)
|
||||
return Rect(p.x, p.y, isz.cx - p2.x, isz.cy - p2.y);
|
||||
if(op == LOOK_ISOPAQUE)
|
||||
return img.GetKind() == IMAGE_OPAQUE;
|
||||
if(IsNull(img))
|
||||
return 1;
|
||||
if(op == LOOK_ISBODYOPAQUE) {
|
||||
static VectorMap<int64, bool> btc;
|
||||
int64 key = img.GetSerialId();
|
||||
int q = btc.Find(key);
|
||||
if(q < 0) {
|
||||
bool opaque = true;
|
||||
Rect m = ChMargins(img);
|
||||
Rect r = img.GetSize();
|
||||
r.left += max(m.left, 0);
|
||||
r.right -= max(m.right, 0);
|
||||
r.top += m.top;
|
||||
r.bottom -= m.bottom;
|
||||
int cx = r.right - r.left;
|
||||
if(cx >= 0)
|
||||
for(int y = r.top; y < r.bottom && opaque; y++) {
|
||||
const RGBA *s = img[y] + r.left;
|
||||
const RGBA *e = s + cx;
|
||||
while(s < e) {
|
||||
if(s->a != 255) {
|
||||
opaque = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(btc.GetCount() > 100)
|
||||
btc.Clear();
|
||||
btc.Add(key, q);
|
||||
return opaque;
|
||||
}
|
||||
return btc[q];
|
||||
}
|
||||
if(op == LOOK_PAINT || op == LOOK_PAINTEDGE) {
|
||||
LTIMING("ChPaint Image");
|
||||
w.Clipoff(r);
|
||||
Rect sr(p, p2);
|
||||
Size sz2(isz.cx - sr.right, isz.cy - sr.bottom);
|
||||
Rect r = RectC(p.x, p.y, sz.cx - sr.left - sz2.cx, sz.cy - sr.top - sz2.cy);
|
||||
int top = minmax(sz.cy / 2, 0, isz.cy);
|
||||
int bottom = minmax(sz.cy - top, 0, isz.cy);
|
||||
int yy = isz.cy - bottom;
|
||||
int left = minmax(sz.cx / 2, 0, isz.cx);
|
||||
int right = minmax(sz.cx - left, 0, isz.cx);
|
||||
int xx = isz.cx - right;
|
||||
if(!r.IsEmpty()) {
|
||||
w.DrawImage(0, 0, img, RectC(0, 0, p.x, p.y));
|
||||
w.DrawImage(0, r.bottom, img, RectC(0, sr.bottom, p.x, sz2.cy));
|
||||
w.DrawImage(r.right, 0, img, RectC(sr.right, 0, sz2.cx, p.y));
|
||||
w.DrawImage(r.right, r.bottom, img, RectC(sr.right, sr.bottom, sz2.cx, sz2.cy));
|
||||
ChDraw(w, p.x, 0, r.Width(), p.y, img, RectC(p.x, 0, sr.Width(), p.y));
|
||||
ChDraw(w, p.x, r.bottom, r.Width(), sz2.cy, img, RectC(p.x, sr.bottom, sr.Width(), sz2.cy));
|
||||
ChDraw(w, 0, p.y, p.x, r.Height(), img, RectC(0, p.y, p.x, sr.Height()));
|
||||
ChDraw(w, r.right, p.y, sz2.cx, r.Height(), img,
|
||||
RectC(sr.right, p.y, sz2.cx, sr.Height()));
|
||||
if(op == LOOK_PAINT) {
|
||||
if(IsNull(r) || IsNull(sr))
|
||||
return 1;
|
||||
if(tile) {
|
||||
LTIMING("Ch-Tiles");
|
||||
LTIMING("Ch-Tiles");
|
||||
img = Rescale(img, Size((tile & 1 ? sr : r).GetWidth(),
|
||||
(tile & 2 ? sr : r).GetHeight()), sr);
|
||||
DrawTiles(w, r, img);
|
||||
}
|
||||
else {
|
||||
static VectorMap<int64, int> btc;
|
||||
int64 key = img.GetSerialId();
|
||||
int q;
|
||||
{
|
||||
LTIMING("Find");
|
||||
q = btc.Find(key);
|
||||
}
|
||||
if(q < 0) {
|
||||
LTIMING("ClassifyContent");
|
||||
q = ClassifyContent(img, sr);
|
||||
if(btc.GetCount() > 100)
|
||||
btc.Clear();
|
||||
btc.Add(key, q);
|
||||
}
|
||||
else
|
||||
q = btc[q];
|
||||
switch(q) {
|
||||
case IMAGECONTENT_VERTDUP|IMAGECONTENT_HORZDUP:
|
||||
{
|
||||
LTIMING("Ch-singlecolor");
|
||||
RGBA c = img[sr.top][sr.left];
|
||||
if(c.a == 255) {
|
||||
w.DrawRect(r, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
ChDraw(w, r, img, sr);
|
||||
break;
|
||||
LTIMING("Ch-linedup");
|
||||
img = CachedRescalePaintOnly(
|
||||
img,
|
||||
Size((q & IMAGECONTENT_HORZDUP) ? max(min(40, r.GetWidth()), sr.GetWidth())
|
||||
: r.GetWidth(),
|
||||
(q & IMAGECONTENT_VERTDUP) ? max(min(40, r.GetHeight()), sr.GetHeight())
|
||||
: r.GetHeight()),
|
||||
sr
|
||||
);
|
||||
LTIMING("Ch-linedup-drawtiles");
|
||||
DrawTiles(w, r, img);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(r.left < r.right) {
|
||||
w.DrawImage(0, 0, img, RectC(0, 0, p.x, top));
|
||||
w.DrawImage(0, sz.cy - bottom, img, RectC(0, yy, p.x, bottom));
|
||||
w.DrawImage(r.right, 0, img, RectC(sr.right, 0, sz2.cx, top));
|
||||
w.DrawImage(r.right, sz.cy - bottom, img, RectC(sr.right, yy, sz2.cx, bottom));
|
||||
ChDraw(w, p.x, 0, r.Width(), top, img, RectC(p.x, 0, sr.Width(), top));
|
||||
ChDraw(w, p.x, sz.cy - bottom, r.Width(), bottom, img, RectC(p.x, yy, sr.Width(), bottom));
|
||||
}
|
||||
else
|
||||
if(r.top < r.bottom) {
|
||||
w.DrawImage(0, 0, img, RectC(0, 0, left, p.y));
|
||||
w.DrawImage(0, r.bottom, img, RectC(0, sr.bottom, left, sz2.cy));
|
||||
w.DrawImage(sz.cx - right, 0, img, RectC(xx, 0, right, p.y));
|
||||
w.DrawImage(sz.cx - right, r.bottom, img, RectC(xx, sr.bottom, right, sz2.cy));
|
||||
ChDraw(w, 0, p.y, left, r.Height(), img, RectC(0, p.y, left, sr.Height()));
|
||||
ChDraw(w, sz.cx - right, p.y, right, r.Height(), img, RectC(xx, p.y, right, sr.Height()));
|
||||
}
|
||||
else {
|
||||
w.DrawImage(0, 0, img, RectC(0, 0, left, top));
|
||||
w.DrawImage(0, sz.cy - bottom, img, RectC(0, yy, left, top));
|
||||
w.DrawImage(sz.cx - right, 0, img, RectC(xx, 0, right, top));
|
||||
w.DrawImage(sz.cx - right, sz.cy - bottom, img, RectC(xx, yy, right, bottom));
|
||||
}
|
||||
w.End();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
typedef Value (*ChPainterFn)(Draw& w, const Rect& r, const Value& v, int op);
|
||||
|
||||
Vector<ChPainterFn>& sChps()
|
||||
{
|
||||
static Vector<ChPainterFn> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void ChLookFn(Value (*fn)(Draw& w, const Rect& r, const Value& v, int op))
|
||||
{
|
||||
if(FindIndex(sChps(), fn) < 0)
|
||||
sChps().Add(fn);
|
||||
}
|
||||
|
||||
struct sStyleCh : Moveable<sStyleCh> {
|
||||
byte *status;
|
||||
void (*init)();
|
||||
};
|
||||
|
||||
Vector<sStyleCh>& sChStyle()
|
||||
{
|
||||
static Vector<sStyleCh> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void ChRegisterStyle__(byte& state, byte& registered, void (*init)())
|
||||
{
|
||||
if(!registered) {
|
||||
sStyleCh& s = sChStyle().Add();
|
||||
s.status = &state;
|
||||
s.init = init;
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ChReset()
|
||||
{
|
||||
for(int i = 0; i < sChStyle().GetCount(); i++)
|
||||
*sChStyle()[i].status = 0;
|
||||
ChLookFn(StdChLookFn);
|
||||
}
|
||||
|
||||
void ChFinish()
|
||||
{
|
||||
for(int i = 0; i < sChStyle().GetCount(); i++)
|
||||
sChStyle()[i].init();
|
||||
}
|
||||
|
||||
Value sChOp(Draw& w, const Rect& r, const Value& v, int op)
|
||||
{
|
||||
Value q;
|
||||
if(!IsNull(v))
|
||||
for(int i = sChps().GetCount() - 1; i >= 0; i--) {
|
||||
q = (*sChps()[i])(w, r, v, op);
|
||||
if(!IsNull(q))
|
||||
break;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
void ChPaint(Draw& w, const Rect& r, const Value& look)
|
||||
{
|
||||
sChOp(w, r, look, LOOK_PAINT);
|
||||
}
|
||||
|
||||
void ChPaint(Draw& w, int x, int y, int cx, int cy, const Value& look)
|
||||
{
|
||||
sChOp(w, RectC(x, y, cx, cy), look, LOOK_PAINT);
|
||||
}
|
||||
|
||||
void ChPaintEdge(Draw& w, const Rect& r, const Value& look)
|
||||
{
|
||||
sChOp(w, r, look, LOOK_PAINTEDGE);
|
||||
}
|
||||
|
||||
void ChPaintEdge(Draw& w, int x, int y, int cx, int cy, const Value& look)
|
||||
{
|
||||
sChOp(w, RectC(x, y, cx, cy), look, LOOK_PAINTEDGE);
|
||||
}
|
||||
|
||||
void ChPaintBody(Draw& w, const Rect& r, const Value& look)
|
||||
{
|
||||
Rect m = ChMargins(look);
|
||||
w.Clip(r);
|
||||
ChPaint(w, Rect(r.left - m.left, r.top - m.top, r.right + m.right, r.bottom + m.bottom),
|
||||
look);
|
||||
w.End();
|
||||
}
|
||||
|
||||
void ChPaintBody(Draw& w, int x, int y, int cx, int cy, const Value& look)
|
||||
{
|
||||
ChPaintBody(w, RectC(x, y, cx, cy), look);
|
||||
}
|
||||
|
||||
Rect ChMargins(const Value& look)
|
||||
{
|
||||
NilDraw w;
|
||||
return sChOp(w, Null, look, LOOK_MARGINS);
|
||||
}
|
||||
|
||||
bool ChIsOpaque(const Value& look)
|
||||
{
|
||||
NilDraw w;
|
||||
return sChOp(w, Null, look, LOOK_ISOPAQUE);
|
||||
}
|
||||
|
||||
bool ChIsBodyOpaque(const Value& look)
|
||||
{
|
||||
NilDraw w;
|
||||
return sChOp(w, Null, look, LOOK_ISBODYOPAQUE);
|
||||
}
|
||||
|
||||
void DeflateMargins(Rect& r, const Rect& m)
|
||||
{
|
||||
r = Rect(r.left + m.left, r.top + m.top, r.right - m.right, r.bottom - m.bottom);
|
||||
}
|
||||
|
||||
void ChDeflateMargins(Rect& r, const Value& look)
|
||||
{
|
||||
return DeflateMargins(r, ChMargins(look));
|
||||
}
|
||||
|
||||
void DeflateMargins(Size& sz, const Rect& m)
|
||||
{
|
||||
sz = Size(sz.cx + m.left + m.right, sz.cy + m.top + m.bottom);
|
||||
}
|
||||
|
||||
void ChDeflateMargins(Size& sz, const Value& look)
|
||||
{
|
||||
DeflateMargins(sz, ChMargins(look));
|
||||
}
|
||||
|
||||
void InflateMargins(Rect& r, const Rect& m)
|
||||
{
|
||||
r = Rect(r.left - m.left, r.top - m.top, r.right + m.right, r.bottom + m.bottom);
|
||||
}
|
||||
|
||||
void ChInflateMargins(Rect& r, const Value& look)
|
||||
{
|
||||
return InflateMargins(r, ChMargins(look));
|
||||
}
|
||||
|
||||
void InflateMargins(Size& sz, const Rect& m)
|
||||
{
|
||||
sz = Size(sz.cx + m.left + m.right, sz.cy + m.top + m.bottom);
|
||||
}
|
||||
|
||||
void ChInflateMargins(Size& sz, const Value& look)
|
||||
{
|
||||
InflateMargins(sz, ChMargins(look));
|
||||
}
|
||||
|
||||
Image AdjustColors(const Image& img) {
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
RGBA *t = w;
|
||||
Color black = SColorText();
|
||||
Color shadow = SColorShadow();
|
||||
Color face = SColorFace();
|
||||
Color light = SColorLight();
|
||||
Color highlight = SColorHighlight();
|
||||
Color hot = highlight;
|
||||
Color paper = SColorPaper();
|
||||
while(s < e) {
|
||||
*t = *s;
|
||||
if(s->r == s->g && s->g == s->b)
|
||||
if(s->r < 128)
|
||||
*t = Blend(black, shadow, 2 * s->r);
|
||||
else
|
||||
if(s->r >= 128 && s->r < 192)
|
||||
*t = Blend(shadow, face, 4 * (s->r - 128));
|
||||
else
|
||||
*t = Blend(face, light, 4 * (s->r - 192));
|
||||
else
|
||||
if(s->r == 0 && s->g == 0)
|
||||
*t = Blend(black, highlight, 2 * (s->b - 128));
|
||||
else
|
||||
if(s->b == 0 && s->g == 0)
|
||||
*t = Blend(black, hot, 2 * (s->r - 128));
|
||||
else
|
||||
if(s->r == s->g && s->b == 0)
|
||||
*t = Blend(black, paper, s->r);
|
||||
t->a = s->a;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
w.SetHotSpot(img.GetHotSpot());
|
||||
w.Set2ndSpot(img.Get2ndSpot());
|
||||
return w;
|
||||
}
|
||||
|
||||
void Override(Iml& target, Iml& source, bool colored)
|
||||
{
|
||||
for(int i = 0; i < target.GetCount(); i++) {
|
||||
int q = source.Find(target.GetId(i));
|
||||
if(q >= 0) {
|
||||
Image m = source.Get(q);
|
||||
if(colored)
|
||||
m = AdjustColors(m);
|
||||
target.Set(i, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ColoredOverride(Iml& target, Iml& source)
|
||||
{
|
||||
Override(target, source, true);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
117
archive/olddraw/Draw/Cham.h
Normal file
117
archive/olddraw/Draw/Cham.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
enum LookOp {
|
||||
LOOK_PAINT,
|
||||
LOOK_MARGINS,
|
||||
LOOK_PAINTEDGE,
|
||||
LOOK_ISOPAQUE,
|
||||
LOOK_ISBODYOPAQUE,
|
||||
};
|
||||
|
||||
void ChLookFn(Value (*fn)(Draw& w, const Rect& r, const Value& look, int lookop));
|
||||
|
||||
Image AdjustColors(const Image& img);
|
||||
|
||||
void Override(Iml& target, Iml& source, bool colored = false);
|
||||
void ColoredOverride(Iml& target, Iml& source);
|
||||
|
||||
void ChReset();
|
||||
void ChFinish();
|
||||
|
||||
void ChPaint(Draw& w, const Rect& r, const Value& look);
|
||||
void ChPaint(Draw& w, int x, int y, int cx, int cy, const Value& look);
|
||||
void ChPaintEdge(Draw& w, const Rect& r, const Value& look);
|
||||
void ChPaintEdge(Draw& w, int x, int y, int cx, int cy, const Value& look);
|
||||
void ChPaintBody(Draw& w, const Rect& r, const Value& look);
|
||||
void ChPaintBody(Draw& w, int x, int y, int cx, int cy, const Value& look);
|
||||
Rect ChMargins(const Value& look);
|
||||
bool ChIsOpaque(const Value& look);
|
||||
bool ChIsBodyOpaque(const Value& look);
|
||||
|
||||
void DeflateMargins(Rect& r, const Rect& margin);
|
||||
void ChDeflateMargins(Rect& r, const Value& look);
|
||||
void DeflateMargins(Size& sz, const Rect& m);
|
||||
void ChDeflateMargins(Size& sz, const Value& look);
|
||||
void InflateMargins(Rect& r, const Rect& m);
|
||||
void ChInflateMargins(Rect& r, const Value& look);
|
||||
void InflateMargins(Size& sz, const Rect& m);
|
||||
void ChInflateMargins(Size& sz, const Value& look);
|
||||
|
||||
template <class T>
|
||||
struct ChStyle {
|
||||
byte status;
|
||||
byte registered;
|
||||
T *standard;
|
||||
|
||||
const T& Standard() const { return *standard; }
|
||||
T& Write() const { T& x = *(T *)this; x.status = 2; return x; }
|
||||
void Assign(const T& src) { *(T *)this = src; }
|
||||
|
||||
ChStyle() { status = 0; registered = 0; standard = NULL; }
|
||||
};
|
||||
|
||||
#define CH_STYLE(klass, type, style) \
|
||||
struct COMBINE5(klass, __, type, __, style) : klass::type { \
|
||||
void Init(); \
|
||||
static void InitIt(); \
|
||||
}; \
|
||||
\
|
||||
void COMBINE5(klass, __, type, __, style)::InitIt() { \
|
||||
klass::style(); \
|
||||
} \
|
||||
\
|
||||
const klass::Style& klass::style() \
|
||||
{ \
|
||||
static COMBINE5(klass, __, type, __, style) b, standard; \
|
||||
if(b.status == 0) { \
|
||||
ChRegisterStyle__(b.status, b.registered, COMBINE5(klass, __, type, __, style)::InitIt); \
|
||||
b.Init(); \
|
||||
b.status = 1; \
|
||||
standard = b; \
|
||||
standard.standard = b.standard = &standard; \
|
||||
} \
|
||||
return b; \
|
||||
} \
|
||||
\
|
||||
void COMBINE5(klass, __, type, __, style)::Init()
|
||||
|
||||
#define CH_VAR(chtype, type, name, init) \
|
||||
chtype& COMBINE(ch_var__, name)(); \
|
||||
void COMBINE(ch_init__, name)() { \
|
||||
COMBINE(ch_var__, name)(); \
|
||||
} \
|
||||
\
|
||||
chtype& COMBINE(ch_var__, name)() { \
|
||||
static chtype b; \
|
||||
if(b.status == 0) { \
|
||||
ChRegisterStyle__(b.status, b.registered, COMBINE(ch_init__, name)); \
|
||||
b.value = init; \
|
||||
b.status = 1; \
|
||||
} \
|
||||
return b; \
|
||||
} \
|
||||
\
|
||||
type name() { return COMBINE(ch_var__, name)().value; } \
|
||||
void COMBINE(name, _Write)(type v) { COMBINE(ch_var__, name)().Write().value = v; }
|
||||
|
||||
struct ChColor : ChStyle<ChColor> { Color value; };
|
||||
#define CH_COLOR(name, init) CH_VAR(ChColor, Color, name, init)
|
||||
|
||||
struct ChInt : ChStyle<ChInt> { int value; };
|
||||
#define CH_INT(name, init) CH_VAR(ChInt, int, name, init)
|
||||
|
||||
struct ChValue : ChStyle<ChValue> { Value value; };
|
||||
#define CH_VALUE(name, init) CH_VAR(ChValue, Value, name, init)
|
||||
|
||||
struct ChImage : ChStyle<ChImage> { Image value; };
|
||||
#define CH_IMAGE(name, init) CH_VAR(ChImage, Image, name, init)
|
||||
|
||||
void ChPaint(Draw& w, const Rect& r, const Value& element);
|
||||
void ChPaint(Draw& w, int x, int y, int cx, int cy, const Value& element);
|
||||
|
||||
Value ChLookWith(const Value& look, const Image& img, Point offset = Point(0, 0));
|
||||
Value ChLookWith(const Value& look, const Image& img, Color color, Point offset = Point(0, 0));
|
||||
Value ChLookWith(const Value& look, const Image& img, Color (*color)(int i), int i, Point offset = Point(0, 0));
|
||||
|
||||
//private:
|
||||
void ChRegisterStyle__(byte& state, byte& registered, void (*init)());
|
||||
|
||||
Value ChBorder(const ColorF *colors, const Value& face = SColorFace());
|
||||
275
archive/olddraw/Draw/ComposeText.cpp
Normal file
275
archive/olddraw/Draw/ComposeText.cpp
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
enum {
|
||||
CG_NONE,
|
||||
CG_CAPITAL,
|
||||
CG_SMALL
|
||||
};
|
||||
|
||||
enum {
|
||||
CG_GRAVE = 0x60,
|
||||
CG_ACUTE = 0xb4,
|
||||
CG_CEDILLA = 0xb8,
|
||||
CG_MACRON = 175,
|
||||
CG_CIRCUMFLEX = 0x2c6,
|
||||
CG_TILDE = 0x2dc,
|
||||
CG_DOT_ABOVE = 0x2d9,
|
||||
CG_OGONEK = 0x2db,
|
||||
CG_STROKE = '-',
|
||||
CG_BREVE = 0x2d8,
|
||||
CG_CARON = 0x2c7,
|
||||
CG_MIDDLE_DOT = 0xb7,
|
||||
CG_DOUBLE_ACUTE = 0x2dd,
|
||||
CG_DIAERESIS = 0xa8,
|
||||
CG_RING_ABOVE = 0x2da,
|
||||
CG_COMMA_T = ',',
|
||||
CG_COMMA_UR = 1,
|
||||
CG_COMMA_URI,
|
||||
};
|
||||
|
||||
struct CGInfo {
|
||||
byte type;
|
||||
char ascii;
|
||||
wchar mark;
|
||||
}
|
||||
gc_info[128] = {
|
||||
{ CG_CAPITAL, 'A', CG_MACRON },
|
||||
{ CG_SMALL, 'a', CG_MACRON },
|
||||
{ CG_CAPITAL, 'A', CG_BREVE },
|
||||
{ CG_SMALL, 'a', CG_BREVE },
|
||||
{ CG_CAPITAL, 'A', CG_OGONEK },
|
||||
{ CG_SMALL, 'a', CG_OGONEK },
|
||||
{ CG_CAPITAL, 'C', CG_ACUTE },
|
||||
{ CG_SMALL, 'c', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'C', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'c', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'C', CG_DOT_ABOVE },
|
||||
{ CG_SMALL, 'c', CG_DOT_ABOVE },
|
||||
{ CG_CAPITAL, 'C', CG_CARON },
|
||||
{ CG_SMALL, 'c', CG_CARON },
|
||||
{ CG_CAPITAL, 'D', CG_CARON },
|
||||
{ CG_SMALL, 'd', CG_COMMA_UR },
|
||||
{ CG_CAPITAL, 'D', CG_STROKE },
|
||||
{ CG_SMALL, 'd', CG_STROKE },
|
||||
{ CG_CAPITAL, 'E', CG_MACRON },
|
||||
{ CG_SMALL, 'e', CG_MACRON },
|
||||
{ CG_CAPITAL, 'E', CG_BREVE },
|
||||
{ CG_SMALL, 'e', CG_BREVE },
|
||||
{ CG_CAPITAL, 'E', CG_DOT_ABOVE },
|
||||
{ CG_SMALL, 'e', CG_DOT_ABOVE },
|
||||
{ CG_CAPITAL, 'E', CG_OGONEK },
|
||||
{ CG_SMALL, 'e', CG_OGONEK },
|
||||
{ CG_CAPITAL, 'E', CG_CARON },
|
||||
{ CG_SMALL, 'e', CG_CARON },
|
||||
{ CG_CAPITAL, 'G', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'g', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'G', CG_BREVE },
|
||||
{ CG_SMALL, 'g', CG_BREVE },
|
||||
{ CG_CAPITAL, 'G', CG_DOT_ABOVE },
|
||||
{ CG_SMALL, 'g', CG_DOT_ABOVE },
|
||||
{ CG_CAPITAL, 'G', CG_CEDILLA },
|
||||
{ CG_SMALL, 'g', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'H', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'h', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'H', CG_STROKE },
|
||||
{ CG_SMALL, 'h', CG_STROKE },
|
||||
{ CG_CAPITAL, 'I', CG_TILDE },
|
||||
{ CG_SMALL, 'i', CG_TILDE },
|
||||
{ CG_CAPITAL, 'I', CG_MACRON },
|
||||
{ CG_SMALL, 'i', CG_MACRON },
|
||||
{ CG_CAPITAL, 'I', CG_BREVE },
|
||||
{ CG_SMALL, 'i', CG_BREVE },
|
||||
{ CG_CAPITAL, 'I', CG_OGONEK },
|
||||
{ CG_SMALL, 'i', CG_OGONEK },
|
||||
{ CG_CAPITAL, 'I', CG_DOT_ABOVE },
|
||||
{ CG_NONE, 0, 0 }, // , CG_SMALL, 'DOTLESS I
|
||||
{ CG_NONE, 0, 0 }, // LATIN CAPITAL LIGATURE IJ
|
||||
{ CG_NONE, 0, 0 }, // LATIN SMALL LIGATURE IJ
|
||||
{ CG_CAPITAL, 'J', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'j', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'K', CG_CEDILLA },
|
||||
{ CG_SMALL, 'k', CG_CEDILLA },
|
||||
{ CG_NONE, 0, 0 }, // CG_SMALL, 'KRA
|
||||
{ CG_CAPITAL, 'L', CG_ACUTE },
|
||||
{ CG_SMALL, 'l', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'L', CG_CEDILLA },
|
||||
{ CG_SMALL, 'l', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'L', CG_COMMA_URI },
|
||||
{ CG_SMALL, 'l', CG_COMMA_UR },
|
||||
{ CG_CAPITAL, 'L', CG_MIDDLE_DOT },
|
||||
{ CG_SMALL, 'l', CG_MIDDLE_DOT },
|
||||
{ CG_CAPITAL, 'L', CG_STROKE },
|
||||
{ CG_SMALL, 'l', CG_STROKE },
|
||||
{ CG_CAPITAL, 'N', CG_ACUTE },
|
||||
{ CG_SMALL, 'n', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'N', CG_CEDILLA },
|
||||
{ CG_SMALL, 'n', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'N', CG_CARON },
|
||||
{ CG_SMALL, 'n', CG_CARON },
|
||||
{ CG_NONE, 0, 0 }, // CG_SMALL, 'N PRECEDED BY APOSTROPHE
|
||||
{ CG_NONE, 0, 0 }, //CG_CAPITAL, 'ENG
|
||||
{ CG_NONE, 0, 0 }, //CG_SMALL, 'ENG
|
||||
{ CG_CAPITAL, 'O', CG_MACRON },
|
||||
{ CG_SMALL, 'o', CG_MACRON },
|
||||
{ CG_CAPITAL, 'O', CG_BREVE },
|
||||
{ CG_SMALL, 'o', CG_BREVE },
|
||||
{ CG_CAPITAL, 'O', CG_DOUBLE_ACUTE },
|
||||
{ CG_SMALL, 'o', CG_DOUBLE_ACUTE },
|
||||
{ CG_NONE, 0, 0 }, // LATIN CAPITAL LIGATURE OE
|
||||
{ CG_NONE, 0, 0 }, // LATIN SMALL LIGATURE OE
|
||||
{ CG_CAPITAL, 'R', CG_ACUTE },
|
||||
{ CG_SMALL, 'r', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'R', CG_CEDILLA },
|
||||
{ CG_SMALL, 'r', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'R', CG_CARON },
|
||||
{ CG_SMALL, 'r', CG_CARON },
|
||||
{ CG_CAPITAL, 'S', CG_ACUTE },
|
||||
{ CG_SMALL, 's', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'S', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 's', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'S', CG_CEDILLA },
|
||||
{ CG_SMALL, 's', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'S', CG_CARON },
|
||||
{ CG_SMALL, 's', CG_CARON },
|
||||
{ CG_CAPITAL, 'T', CG_CEDILLA },
|
||||
{ CG_SMALL, 't', CG_CEDILLA },
|
||||
{ CG_CAPITAL, 'T', CG_CARON },
|
||||
{ CG_SMALL, 't', CG_COMMA_T },
|
||||
{ CG_CAPITAL, 'T', CG_STROKE },
|
||||
{ CG_SMALL, 't', CG_STROKE },
|
||||
{ CG_CAPITAL, 'U', CG_TILDE },
|
||||
{ CG_SMALL, 'u', CG_TILDE },
|
||||
{ CG_CAPITAL, 'U', CG_MACRON },
|
||||
{ CG_SMALL, 'u', CG_MACRON },
|
||||
{ CG_CAPITAL, 'U', CG_BREVE },
|
||||
{ CG_SMALL, 'u', CG_BREVE },
|
||||
{ CG_CAPITAL, 'U', CG_RING_ABOVE },
|
||||
{ CG_SMALL, 'u', CG_RING_ABOVE },
|
||||
{ CG_CAPITAL, 'U', CG_DOUBLE_ACUTE },
|
||||
{ CG_SMALL, 'u', CG_DOUBLE_ACUTE },
|
||||
{ CG_CAPITAL, 'U', CG_OGONEK },
|
||||
{ CG_SMALL, 'u', CG_OGONEK },
|
||||
{ CG_CAPITAL, 'W', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'w', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'Y', CG_CIRCUMFLEX },
|
||||
{ CG_SMALL, 'y', CG_CIRCUMFLEX },
|
||||
{ CG_CAPITAL, 'Y', CG_DIAERESIS },
|
||||
{ CG_CAPITAL, 'Z', CG_ACUTE },
|
||||
{ CG_SMALL, 'z', CG_ACUTE },
|
||||
{ CG_CAPITAL, 'Z', CG_DOT_ABOVE },
|
||||
{ CG_SMALL, 'z', CG_DOT_ABOVE },
|
||||
{ CG_CAPITAL, 'Z', CG_CARON },
|
||||
{ CG_SMALL, 'z', CG_CARON },
|
||||
{ CG_NONE, 0, 0 } // CG_SMALL, 'LONG S
|
||||
};
|
||||
|
||||
Draw& ScreenInfo();
|
||||
|
||||
void FontInfo::ComposeMetrics(Font fnt, CharMetrics *m, int page) const
|
||||
{
|
||||
if(fnt.GetFaceInfo() & Font::COMPOSED) {
|
||||
FontInfo fi = ScreenInfo().GetFontInfoW(fnt);
|
||||
for(int i = 0; i < 32; i++) {
|
||||
int c = gc_info[i + (page - 8) * 32].ascii;
|
||||
m[i].lspc = fi.GetLeftSpace(c);
|
||||
m[i].width = fi[c];
|
||||
m[i].rspc = fi.GetRightSpace(c);
|
||||
if(gc_info[i].type == CG_COMMA_UR && !fi.IsFixedPitch())
|
||||
m[i].rspc += m[i].width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::ComposeText(int x, int y, int angle, const wchar *text, Font font, Color ink,
|
||||
int n, const int *dx) {
|
||||
if(font.GetFaceInfo() & Font::COMPOSED) {
|
||||
for(int i = 0; i < n; i++)
|
||||
if(text[i] >= 256 && text[i] < 256 + 128) {
|
||||
FontInfo fi = GetFontInfoW(font);
|
||||
Clip(x, y, 9999, fi.GetHeight());
|
||||
Buffer<wchar> ntext(n);
|
||||
double sina;
|
||||
double cosa;
|
||||
Size offset;
|
||||
if(angle)
|
||||
SinCos(angle, sina, cosa); //TODO global sin tables!
|
||||
int xp = 0;
|
||||
for(int i = 0; i < n; i++) {
|
||||
wchar chr = text[i];
|
||||
ntext[i] = chr;
|
||||
if(chr >= 256 && chr < 256 + 128) {
|
||||
CGInfo f = gc_info[chr - 256];
|
||||
if(f.type != CG_NONE) {
|
||||
ntext[i] = chr = f.ascii;
|
||||
Font mfnt = font;
|
||||
FontInfo mfi = fi;
|
||||
int my = 0;
|
||||
int mx = 0;
|
||||
int cw = fi[f.ascii];
|
||||
int mw = mfi[f.mark];
|
||||
wchar mark = f.mark;
|
||||
if(mark == CG_COMMA_UR && fi.IsFixedPitch())
|
||||
mark = CG_CARON;
|
||||
if(mark == CG_COMMA_T) {
|
||||
my -= 3 * font.GetHeight() / 4;
|
||||
mx += 4 * cw / 10;
|
||||
if(font.IsItalic())
|
||||
mx += mw / 2;
|
||||
}
|
||||
else
|
||||
if(mark == CG_COMMA_UR) {
|
||||
my -= 2 * font.GetHeight() / 3;
|
||||
mx += cw - mw / 4;
|
||||
mark = ',';
|
||||
if(font.IsItalic())
|
||||
mx += mw / 3;
|
||||
}
|
||||
else
|
||||
if(mark == CG_COMMA_URI) {
|
||||
my -= 2 * font.GetHeight() / 3;
|
||||
mx += cw - mw / 2;
|
||||
mark = ',';
|
||||
if(font.IsItalic())
|
||||
mx += mw / 3;
|
||||
}
|
||||
else
|
||||
if(mark != CG_STROKE) {
|
||||
if(f.mark != CG_OGONEK && f.mark != CG_CEDILLA && f.type == CG_CAPITAL) {
|
||||
mfnt = font(9 * font.GetHeight() / 10);
|
||||
mfi = GetFontInfoW(mfnt);
|
||||
my -= mark == CG_RING_ABOVE ? font.GetHeight() / 19
|
||||
: font.GetHeight() / 13;
|
||||
}
|
||||
mw = mfi[f.mark];
|
||||
mx += (cw - mw) / 2;
|
||||
if(font.IsItalic())
|
||||
mx += mw / 5;
|
||||
}
|
||||
if(angle)
|
||||
DrawText(int(x + cosa * (xp + mx) + sina * my),
|
||||
int(y - sina * (xp + mx) + cosa * my),
|
||||
angle, &mark, mfnt, ink, 1);
|
||||
else
|
||||
DrawText(x + xp + mx, y + my, &mark, mfnt, ink, 1);
|
||||
}
|
||||
}
|
||||
if(angle)
|
||||
DrawTextOp(int(x + cosa * xp), int(y - sina * xp),
|
||||
angle, &chr, font, ink, 1, dx);
|
||||
if(dx)
|
||||
xp += dx[i];
|
||||
else
|
||||
xp += fi[chr];
|
||||
}
|
||||
if(!angle)
|
||||
DrawTextOp(x, y, angle, ntext, font, ink, n, dx);
|
||||
End();
|
||||
return;
|
||||
}
|
||||
}
|
||||
DrawTextOp(x, y, angle, text, font, ink, n, dx);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
21
archive/olddraw/Draw/Copying
Normal file
21
archive/olddraw/Draw/Copying
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Copyright 1998-2008 The U++ Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE U++ PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
564
archive/olddraw/Draw/Debug.cpp
Normal file
564
archive/olddraw/Draw/Debug.cpp
Normal file
|
|
@ -0,0 +1,564 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
String DumpLanguage(int language)
|
||||
{
|
||||
if(IsNull(language))
|
||||
return "Null";
|
||||
char out[5];
|
||||
out[0] = (char)(language >> 24);
|
||||
out[1] = (char)(language >> 16);
|
||||
out[2] = '-';
|
||||
out[3] = (char)(language >> 8);
|
||||
out[4] = (char)(language >> 0);
|
||||
return String(out, 5);
|
||||
}
|
||||
|
||||
String DumpAlign(int align)
|
||||
{
|
||||
String ss;
|
||||
switch(align)
|
||||
{
|
||||
case ALIGN_NULL: return "ALIGN_NULL";
|
||||
case ALIGN_LEFT: return "ALIGN_LEFT";
|
||||
case ALIGN_CENTER: return "ALIGN_CENTER";
|
||||
case ALIGN_RIGHT: return "ALIGN_RIGHT";
|
||||
case ALIGN_JUSTIFY: return "ALIGN_JUSTIFY";
|
||||
default: return ss << "ALIGNMENT(" << (int)align << ")";
|
||||
}
|
||||
}
|
||||
|
||||
String DumpColor(Color color)
|
||||
{
|
||||
if(IsNull(color))
|
||||
return "Null";
|
||||
int r = color.GetR(), g = color.GetG(), b = color.GetB();
|
||||
byte xr = -r, xg = -g, xb = -b;
|
||||
static const char *stdc[] = { "Black", "LtBlue", "LtGreen", "LtCyan", "LtRed", "LtMagenta", "Yellow", "White" };
|
||||
if((xr | xg | xb) <= 1)
|
||||
return stdc[4 * xr + 2 * xg + xb];
|
||||
String ss;
|
||||
return ss << "Color(" << r << ", " << g << ", " << b << ")";
|
||||
}
|
||||
|
||||
String DumpFont(Font font)
|
||||
{
|
||||
String out;
|
||||
if(IsNull(font))
|
||||
out << "Font(Null)";
|
||||
else
|
||||
{
|
||||
out << "Font()";
|
||||
out << ".Face(" << font.GetFace() << ")";
|
||||
out << ".FaceName(\"" << font.GetFaceName() << "\")";
|
||||
out << ".Height(" << font.GetHeight() << ")";
|
||||
out << ".Width(" << font.GetWidth() << ")";
|
||||
|
||||
if(font.IsItalic()) out << ".Italic()";
|
||||
if(font.IsBold()) out << ".Bold()";
|
||||
if(font.IsUnderline()) out << ".Underline()";
|
||||
if(font.IsStrikeout()) out << ".Strikeout()";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
String DumpFontInfo(FontInfo fi)
|
||||
{
|
||||
String out;
|
||||
out << "FontInfo(font = " << fi.GetFont() << "\n"
|
||||
"\tempty = " << fi.IsEmpty() << "\n"
|
||||
"\tascent = " << fi.GetAscent() << "\n"
|
||||
"\tdescent = " << fi.GetDescent() << "\n"
|
||||
"\texternal leading = " << fi.GetExternal() << "\n"
|
||||
"\tinternal leading = " << fi.GetInternal() << "\n"
|
||||
"\theight = " << fi.GetHeight() << "\n"
|
||||
"\tline height = " << fi.GetLineHeight() << "\n"
|
||||
"\toverhang = " << fi.GetOverhang() << "\n"
|
||||
"\taverage width = " << fi.GetAveWidth() << "\n"
|
||||
"\tmaximum width = " << fi.GetMaxWidth() << "\n"
|
||||
"\tfixed pitch = " << fi.IsFixedPitch() << "\n"
|
||||
"\tscaleable = " << fi.IsScaleable() << "\n"
|
||||
"\tfont height = " << fi.GetFontHeight() << "\n";
|
||||
|
||||
out << "\n\twidth:\n";
|
||||
int i;
|
||||
for(i = 0; i < 256; i++)
|
||||
out << NFormat(i & 15 ? " " : "\n\t%02x\t", i) << NFormat("%2>d", fi[i]);
|
||||
out << "\n\n\tleft space:\n";
|
||||
for(i = 0; i < 256; i++)
|
||||
out << NFormat(i & 15 ? " " : "\n\t%02x\t", i) << NFormat("%2>d", fi.GetLeftSpace(i));
|
||||
out << "\n\n\tright space:\n";
|
||||
for(i = 0; i < 256; i++)
|
||||
out << NFormat(i & 15 ? " " : "\n\t%02x\t", i) << NFormat("%2>d", fi.GetRightSpace(i));
|
||||
out << "\n\n\tkerning:\n";
|
||||
int kp = 0;
|
||||
for(i = 0; i < 256; i++)
|
||||
for(int j = 0; j < 256; j++)
|
||||
if(int k = fi.GetKerning(i, j))
|
||||
out << (kp++ & 7 ? " " : "\n\t") << NFormat("(%02x,%02x)=%2>d", i, j, k);
|
||||
out << (kp ? "\n" : "\tnone\n");
|
||||
return out;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
enum
|
||||
{
|
||||
GCAllMask = GCFunction
|
||||
| GCPlaneMask
|
||||
| GCForeground
|
||||
| GCBackground
|
||||
| GCLineWidth
|
||||
| GCLineStyle
|
||||
| GCCapStyle
|
||||
| GCJoinStyle
|
||||
| GCFillStyle
|
||||
| GCFillRule
|
||||
| GCArcMode
|
||||
| GCTile
|
||||
| GCStipple
|
||||
| GCTileStipXOrigin
|
||||
| GCTileStipYOrigin
|
||||
| GCFont
|
||||
| GCSubwindowMode
|
||||
| GCGraphicsExposures
|
||||
| GCClipXOrigin
|
||||
| GCClipYOrigin
|
||||
// | GCClipMask
|
||||
| GCDashOffset
|
||||
// | GCDashList
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpPixmap(Pixmap pixmap)
|
||||
{
|
||||
String out;
|
||||
if(pixmap == Pixmap(-1))
|
||||
out << "NULL";
|
||||
else
|
||||
{
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned width, height, border_width, depth;
|
||||
XGetGeometry(Xdisplay, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
|
||||
out << (int)width << " x " << (int)height << ", depth = " << (int)depth;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpXFont(XFont font)
|
||||
{
|
||||
XFontStruct *fs = XQueryFont(Xdisplay, font);
|
||||
String out = DumpXFontStruct(fs);
|
||||
if(fs)
|
||||
XFreeFontInfo(NULL, fs, 0);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpXFontStruct(XFontStruct *fs)
|
||||
{
|
||||
String out;
|
||||
if(!fs)
|
||||
out << "NULL\n";
|
||||
else
|
||||
{
|
||||
out <<
|
||||
"direction=" << (int)fs -> direction << "\n"
|
||||
"min_char_or_byte2=" << (int)fs -> min_char_or_byte2 << "\n"
|
||||
"max_char_or_byte2=" << (int)fs -> max_char_or_byte2 << "\n"
|
||||
"min_byte1=" << (int)fs -> min_byte1 << "\n"
|
||||
"max_byte1=" << (int)fs -> max_byte1 << "\n"
|
||||
"all_chars_exist=" << (int)fs -> all_chars_exist << "\n"
|
||||
"default_char=" << (int)fs -> default_char << "\n"
|
||||
"n_properties=" << (int)fs -> n_properties << "\n";
|
||||
for(int i = 0; i < fs -> n_properties; i++)
|
||||
{
|
||||
char *name = XGetAtomName(Xdisplay, fs -> properties[i].name);
|
||||
out << "properties[" << i << "]=" << name << ", card32 = " << (int)fs -> properties[i].card32 << "\n";
|
||||
XFree(name);
|
||||
}
|
||||
out <<
|
||||
"min_bounds=" << (int)fs -> min_bounds.width << " x "
|
||||
<< (int)fs -> min_bounds.ascent << " + " << (int)fs -> min_bounds.descent << "\n"
|
||||
"max_bounds=" << (int)fs -> max_bounds.width << " x "
|
||||
<< (int)fs -> max_bounds.ascent << " + " << (int)fs -> max_bounds.descent << "\n";
|
||||
out <<
|
||||
"ascent=" << (int)fs -> ascent << "\n"
|
||||
"descent=" << (int)fs -> descent << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpGC(GC gc)
|
||||
{
|
||||
XGCValues values;
|
||||
Zero(values);
|
||||
XGetGCValues(Xdisplay, gc, GCAllMask & ~GCFont, &values);
|
||||
String out = DumpGCValues(values);
|
||||
XFontStruct *gc_font = XQueryFont(Xdisplay, (XID)gc);
|
||||
out << "GCFont=" << DumpXFontStruct(gc_font) << "\n";
|
||||
if(gc_font)
|
||||
XFreeFontInfo(NULL, gc_font, 0);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpGCValues(const XGCValues& gc_values, int mask)
|
||||
{
|
||||
String out;
|
||||
if(mask & GCFunction)
|
||||
{
|
||||
static const char *names[] =
|
||||
{
|
||||
"X11_ROP2_ZERO",
|
||||
"X11_ROP2_AND",
|
||||
"X11_ROP2_AND_NOT",
|
||||
"X11_ROP2_COPY",
|
||||
"X11_ROP2_NOT_AND",
|
||||
"X11_ROP2_NOP",
|
||||
"X11_ROP2_XOR",
|
||||
"X11_ROP2_OR",
|
||||
"X11_ROP2_NOT_AND_NOT",
|
||||
"X11_ROP2_NOT_XOR",
|
||||
"X11_ROP2_INVERT",
|
||||
"X11_ROP2_OR_NOT",
|
||||
"X11_ROP2_NOT_COPY",
|
||||
"X11_ROP2_NOT_OR",
|
||||
"X11_ROP2_NOT_OR_NOT",
|
||||
"X11_ROP2_ONE",
|
||||
};
|
||||
ASSERT(__countof(names) == 16);
|
||||
out << "GCFunction=" << (int)gc_values.function << ", " << names[gc_values.function & 15] << "\n";
|
||||
}
|
||||
if(mask & GCPlaneMask)
|
||||
out << "GCPlaneMask=" << Format("%08x", (int)gc_values.plane_mask) << "\n";
|
||||
if(mask & GCForeground)
|
||||
out << "GCForeground=" << Format("%08x", (int)gc_values.foreground) << "\n";
|
||||
if(mask & GCBackground)
|
||||
out << "GCBackground=" << Format("%08x", (int)gc_values.background) << "\n";
|
||||
if(mask & GCLineWidth)
|
||||
out << "GCLineWidth=" << (int)gc_values.line_width << "\n";
|
||||
if(mask & GCLineStyle)
|
||||
{
|
||||
out << "GCLineStyle=" << (int)gc_values.line_style << ", ";
|
||||
switch(gc_values.line_style)
|
||||
{
|
||||
case LineSolid: out << "LineSolid"; break;
|
||||
case LineOnOffDash: out << "LineOnOffDash"; break;
|
||||
case LineDoubleDash: out << "LineDoubleDash"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCCapStyle)
|
||||
{
|
||||
out << "GCCapStyle=" << (int)gc_values.cap_style << ", ";
|
||||
switch(gc_values.cap_style)
|
||||
{
|
||||
case CapNotLast: out << "CapNotLast"; break;
|
||||
case CapButt: out << "CapButt"; break;
|
||||
case CapRound: out << "CapRound"; break;
|
||||
case CapProjecting: out << "CapProjecting"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCJoinStyle)
|
||||
{
|
||||
out << "GCJoinStyle=" << (int)gc_values.join_style << ", ";
|
||||
switch(gc_values.join_style)
|
||||
{
|
||||
case JoinMiter: out << "JoinMiter"; break;
|
||||
case JoinRound: out << "JoinRound"; break;
|
||||
case JoinBevel: out << "JoinBevel"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCFillStyle)
|
||||
{
|
||||
out << "GCFillStyle=" << (int)gc_values.fill_style << ", ";
|
||||
switch(gc_values.fill_style)
|
||||
{
|
||||
case FillSolid: out << "FillSolid"; break;
|
||||
case FillTiled: out << "FillTiled"; break;
|
||||
case FillStippled: out << "FillStippled"; break;
|
||||
case FillOpaqueStippled: out << "FillOpaqueStippled"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCFillRule)
|
||||
{
|
||||
out << "GCFillRule=" << (int)gc_values.fill_rule << ", ";
|
||||
switch(gc_values.fill_rule)
|
||||
{
|
||||
case EvenOddRule: out << "EvenOddRule"; break;
|
||||
case WindingRule: out << "WindingRule"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCArcMode)
|
||||
{
|
||||
out << "GCArcMode=" << (int)gc_values.arc_mode << ", ";
|
||||
switch(gc_values.arc_mode)
|
||||
{
|
||||
case ArcChord: out << "ArcChord"; break;
|
||||
case ArcPieSlice: out << "ArcPieSlice"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
if(mask & GCTile)
|
||||
out << "GCTile=" << DumpPixmap(gc_values.tile) << "\n";
|
||||
if(mask & GCStipple)
|
||||
out << "GCStipple=" << DumpPixmap(gc_values.stipple) << "\n";
|
||||
if(mask & GCTileStipXOrigin)
|
||||
out << "GCTileStipXOrigin=" << (int)gc_values.ts_x_origin << "\n";
|
||||
if(mask & GCTileStipYOrigin)
|
||||
out << "GCTileStipYOrigin=" << (int)gc_values.ts_y_origin << "\n";
|
||||
if(mask & GCFont)
|
||||
out << "GCFont=" << DumpXFont(gc_values.font) << "\n";
|
||||
if(mask & GCSubwindowMode)
|
||||
{
|
||||
out << "GCSubwindowMode=" << (int)gc_values.subwindow_mode << ", ";
|
||||
switch(gc_values.subwindow_mode)
|
||||
{
|
||||
case ClipByChildren: out << "ClipByChildren"; break;
|
||||
case IncludeInferiors: out << "IncludeInferiors"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
}
|
||||
if(mask & GCGraphicsExposures)
|
||||
out << "GCGraphicsExposures=" << (gc_values.graphics_exposures ? "true" : "false") << "\n";
|
||||
if(mask & GCClipXOrigin)
|
||||
out << "GCClipXOrigin=" << (int)gc_values.clip_x_origin;
|
||||
if(mask & GCClipYOrigin)
|
||||
out << "GCClipYOrigin=" << (int)gc_values.clip_y_origin;
|
||||
// if(mask & GCClipMask)
|
||||
// out << "GCClipMask=" << DumpPixmap(gc_values.clip_mask);
|
||||
if(mask & GCDashOffset)
|
||||
out << "GCDashOffset=" << (int)gc_values.dash_offset;
|
||||
// if(mask & GCDashList)
|
||||
// out << "GCDashList=" << Format("%02x\n", gc_values.dashes);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpEvent(XEvent *event)
|
||||
{
|
||||
String out;
|
||||
if(!event)
|
||||
out << "NULL";
|
||||
else
|
||||
{
|
||||
out << "event_type=" << (int)event -> type << ", ";
|
||||
switch(event -> type)
|
||||
{
|
||||
case KeyPress:
|
||||
out << "KeyPress, state=" << (int)event -> xkey.state << ", keycode=" << (int)event -> xkey.keycode;
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
out << "KeyRelease, state=" << (int)event -> xkey.state << ", keycode=" << (int)event -> xkey.keycode;
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
out << "ButtonPress, x=" << (int)event -> xbutton.x << ", y=" << (int)event -> xbutton.y << ", state=" << (int)event -> xbutton.state << ", button=" << (int)event -> xbutton.button;
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
out << "ButtonRelease, x=" << (int)event -> xbutton.x << ", y=" << (int)event -> xbutton.y << ", state=" << (int)event -> xbutton.state << ", button=" << (int)event -> xbutton.button;
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
out << "MotionNotify, x=" << (int)event -> xmotion.x << ", y=" << (int)event -> xmotion.y << ", state=" << (int)event -> xmotion.state;
|
||||
break;
|
||||
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
out << (event -> type == EnterNotify ? "EnterNotify" : "LeaveNotify") << ", mode=";
|
||||
switch(event -> xcrossing.mode)
|
||||
{
|
||||
case NotifyNormal: out << "NotifyNormal"; break;
|
||||
case NotifyGrab: out << "NotifyGrab"; break;
|
||||
case NotifyUngrab: out << "NotifyUngrab"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << ", detail=";
|
||||
switch(event -> xcrossing.detail)
|
||||
{
|
||||
case NotifyAncestor: out << "NotifyAncestor"; break;
|
||||
case NotifyVirtual: out << "NotifyVirtual"; break;
|
||||
case NotifyInferior: out << "NotifyInferior"; break;
|
||||
case NotifyNonlinear: out << "NotifyNonlinear"; break;
|
||||
case NotifyNonlinearVirtual: out << "NotifyNonlinearVirtual"; break;
|
||||
default: out << "unknown (" << (int)event -> xcrossing.detail << ")"; break;
|
||||
}
|
||||
out << ", same_screen=" << (event -> xcrossing.same_screen ? "true" : "false")
|
||||
<< ", focus=" << (event -> xcrossing.focus ? "true" : "false")
|
||||
<< ", state=" << (int)event -> xcrossing.state;
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
case FocusOut:
|
||||
out << (event -> type == FocusIn ? "FocusIn" : "FocusOut") << ", mode=";
|
||||
switch(event -> xfocus.mode)
|
||||
{
|
||||
case NotifyNormal: out << "NotifyNormal"; break;
|
||||
case NotifyGrab: out << "NotifyGrab"; break;
|
||||
case NotifyUngrab: out << "NotifyUngrab"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << ", detail=";
|
||||
switch(event -> xfocus.detail)
|
||||
{
|
||||
case NotifyAncestor: out << "NotifyAncestor"; break;
|
||||
case NotifyVirtual: out << "NotifyVirtual"; break;
|
||||
case NotifyInferior: out << "NotifyInferior"; break;
|
||||
case NotifyNonlinear: out << "NotifyNonlinear"; break;
|
||||
case NotifyNonlinearVirtual: out << "NotifyNonlinearVirtual"; break;
|
||||
case NotifyPointer: out << "NotifyPointer"; break;
|
||||
case NotifyPointerRoot: out << "NotifyPointerRoot"; break;
|
||||
case NotifyDetailNone: out << "NotifyDetailNone"; break;
|
||||
default: out << "unknown (" << (int)event -> xfocus.detail << ")"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeymapNotify:
|
||||
out << "KeymapNotify";
|
||||
break;
|
||||
|
||||
case Expose:
|
||||
out << "Expose [" << event -> xexpose.x << ", " << event -> xexpose.y
|
||||
<< " - " << (event -> xexpose.x + event -> xexpose.width)
|
||||
<< ", " << (event -> xexpose.y + event -> xexpose.height) << "], count=" << event -> xexpose.count;
|
||||
break;
|
||||
|
||||
case GraphicsExpose:
|
||||
out << "GraphicsExpose [" << event -> xgraphicsexpose.x << ", " << event -> xgraphicsexpose.y
|
||||
<< " - " << (event -> xgraphicsexpose.x + event -> xgraphicsexpose.width)
|
||||
<< ", " << (event -> xgraphicsexpose.y + event -> xgraphicsexpose.height) << "], "
|
||||
"count=" << event -> xgraphicsexpose.count
|
||||
<< ", major_code=" << (int)event -> xgraphicsexpose.major_code
|
||||
<< ", minor_code=" << (int)event -> xgraphicsexpose.minor_code;
|
||||
break;
|
||||
|
||||
case NoExpose:
|
||||
out << "NoExpose"
|
||||
<< ", major_code=" << (int)event -> xnoexpose.major_code
|
||||
<< ", minor_code=" << (int)event -> xnoexpose.minor_code;
|
||||
break;
|
||||
|
||||
case VisibilityNotify:
|
||||
out << "VisibilityNotify, state=" << (int)event -> xvisibility.state;
|
||||
break;
|
||||
|
||||
case CreateNotify:
|
||||
out << "CreateNotify [" << event -> xcreatewindow.x << ", " << event -> xcreatewindow.y
|
||||
<< " - " << (event -> xcreatewindow.x + event -> xcreatewindow.width)
|
||||
<< ", " << (event -> xcreatewindow.y + event -> xcreatewindow.height) << "], "
|
||||
"border_width=" << event -> xcreatewindow.border_width << ", "
|
||||
"override_redirect=" << (event -> xcreatewindow.override_redirect ? "true" : "false");
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
out << "DestroyNotify";
|
||||
break;
|
||||
|
||||
case UnmapNotify:
|
||||
out << "UnmapNotify";
|
||||
break;
|
||||
|
||||
case MapNotify:
|
||||
out << "MapNotify";
|
||||
break;
|
||||
|
||||
case MapRequest:
|
||||
out << "MapRequest";
|
||||
break;
|
||||
|
||||
case ReparentNotify:
|
||||
out << "ReparentNotify";
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
out << "ConfigureNotify";
|
||||
break;
|
||||
|
||||
case ConfigureRequest:
|
||||
out << "ConfigureRequest";
|
||||
break;
|
||||
|
||||
case GravityNotify:
|
||||
out << "GravityNotify";
|
||||
break;
|
||||
|
||||
case ResizeRequest:
|
||||
out << "ResizeRequest";
|
||||
break;
|
||||
|
||||
case CirculateNotify:
|
||||
out << "CirculateNotify";
|
||||
break;
|
||||
|
||||
case CirculateRequest:
|
||||
out << "CirculateRequest";
|
||||
break;
|
||||
|
||||
case PropertyNotify:
|
||||
out << "PropertyNotify";
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
out << "SelectionClear";
|
||||
break;
|
||||
|
||||
case SelectionRequest:
|
||||
out << "SelectionRequest";
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
out << "SelectionNotify";
|
||||
break;
|
||||
|
||||
case ColormapNotify:
|
||||
out << "ColormapNotify";
|
||||
break;
|
||||
|
||||
case ClientMessage:
|
||||
out << "ClientMessage";
|
||||
break;
|
||||
|
||||
case MappingNotify:
|
||||
out << "MappingNotify";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
int GdiGetFreeSpace()
|
||||
{
|
||||
Vector<HPEN> objects;
|
||||
for(HPEN pen; pen = CreatePen(PS_SOLID, 0, LtGray()); objects.Add(pen))
|
||||
;
|
||||
for(int i = 0; i < objects.GetCount(); DeleteObject(objects[i++]))
|
||||
;
|
||||
return objects.GetCount();
|
||||
}
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
46
archive/olddraw/Draw/Debug.h
Normal file
46
archive/olddraw/Draw/Debug.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
String DumpLanguage(int language);
|
||||
String DumpColor(Color color);
|
||||
String DumpFont(Font font);
|
||||
String DumpFontInfo(FontInfo fi);
|
||||
String DumpAlign(int align);
|
||||
#ifdef PLATFORM_X11
|
||||
String DumpPixmap(Pixmap pixmap);
|
||||
String DumpXFont(XFont font);
|
||||
String DumpXFontStruct(XFontStruct *fs);
|
||||
String DumpGC(GC gc);
|
||||
String DumpGCValues(const XGCValues& gc_values, int mask = -1);
|
||||
String DumpEvent(XEvent *event);
|
||||
#endif//PLATFORM_X11
|
||||
|
||||
class SimpleTiming
|
||||
{
|
||||
public:
|
||||
SimpleTiming(const char *name) : name(name)
|
||||
{
|
||||
last_ticks = start_ticks = GetTickCount();
|
||||
RLOG(name << " (open) & " << start_ticks);
|
||||
}
|
||||
|
||||
void Show(const char *part)
|
||||
{
|
||||
int ticks = GetTickCount();
|
||||
RLOG(name << " in " << (ticks - start_ticks) <<
|
||||
", " << part << " in " << (ticks - last_ticks));
|
||||
last_ticks = ticks;
|
||||
}
|
||||
|
||||
~SimpleTiming()
|
||||
{
|
||||
int ticks = GetTickCount();
|
||||
String out;
|
||||
RLOG(name << " done in " << (ticks - start_ticks)
|
||||
<< ", last part in " << (ticks - last_ticks));
|
||||
}
|
||||
|
||||
private:
|
||||
String name;
|
||||
int start_ticks;
|
||||
int last_ticks;
|
||||
};
|
||||
|
||||
int GdiGetFreeSpace();
|
||||
321
archive/olddraw/Draw/Display.cpp
Normal file
321
archive/olddraw/Draw/Display.cpp
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define IMAGECLASS DrawImg
|
||||
#define IMAGEFILE <Draw/DrawImg.iml>
|
||||
#include <Draw/iml.h>
|
||||
|
||||
#define LLOG(x) // RLOG(x)
|
||||
|
||||
AttrText::operator Value() const
|
||||
{
|
||||
return RawToValue(*this);
|
||||
}
|
||||
|
||||
void AttrText::Init()
|
||||
{
|
||||
ink = Null;
|
||||
paper = Null;
|
||||
font = Null;
|
||||
align = Null;
|
||||
}
|
||||
|
||||
AttrText::AttrText(const char *_text)
|
||||
{
|
||||
text = _text;
|
||||
Init();
|
||||
}
|
||||
|
||||
AttrText::AttrText(const wchar *_text)
|
||||
{
|
||||
text = _text;
|
||||
Init();
|
||||
}
|
||||
|
||||
AttrText::AttrText(const WString& _text)
|
||||
{
|
||||
text = _text;
|
||||
Init();
|
||||
}
|
||||
|
||||
class StdDisplayClass : public Display
|
||||
{
|
||||
public:
|
||||
StdDisplayClass(int align = ALIGN_LEFT) : align(align) {}
|
||||
|
||||
virtual void Paint0(Draw& draw, const Rect& rc, const Value& v, Color ink, Color paper, dword style) const;
|
||||
virtual void Paint(Draw& draw, const Rect& rc, const Value& v, Color ink, Color paper, dword style) const;
|
||||
virtual Size GetStdSize(const Value& q) const;
|
||||
|
||||
private:
|
||||
int align;
|
||||
};
|
||||
|
||||
void Display::PaintBackground(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
if(IsType<AttrText>(q)) {
|
||||
const AttrText& t = ValueTo<AttrText>(q);
|
||||
if(!IsNull(t.paper))
|
||||
paper = t.paper;
|
||||
}
|
||||
w.DrawRect(r, paper);
|
||||
}
|
||||
|
||||
void Display::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
|
||||
{
|
||||
StdDisplay().Paint(w, r, q, ink, paper, style);
|
||||
}
|
||||
|
||||
Size Display::RatioSize(const Value& q, int cx, int cy) const {
|
||||
return Size(cx, cy);
|
||||
}
|
||||
|
||||
Size Display::GetStdSize(const Value& q) const
|
||||
{
|
||||
return Size(8, 8);
|
||||
}
|
||||
|
||||
void StdDisplayClass::Paint0(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword s) const {
|
||||
LLOG("Display::Paint0: " << q << " ink:" << ink << " paper:" << paper);
|
||||
WString txt;
|
||||
Font font = StdFont();
|
||||
int a = align;
|
||||
if(IsType<AttrText>(q)) {
|
||||
const AttrText& t = ValueTo<AttrText>(q);
|
||||
txt = t.text;
|
||||
if(!IsNull(t.paper))
|
||||
paper = t.paper;
|
||||
if(!IsNull(t.ink))
|
||||
ink = t.ink;
|
||||
if(!IsNull(t.font))
|
||||
font = t.font;
|
||||
if(!IsNull(t.align))
|
||||
a = t.align;
|
||||
}
|
||||
else
|
||||
txt = IsString(q) ? q : StdConvert().Format(q);
|
||||
int x = r.left;
|
||||
Size tsz = GetTLTextSize(txt, font);
|
||||
if(a == ALIGN_RIGHT)
|
||||
x = r.right - tsz.cx;
|
||||
if(a == ALIGN_CENTER)
|
||||
x += (r.Width() - tsz.cx) / 2;
|
||||
int tcy = GetTLTextHeight(txt, font);
|
||||
int tt = r.top + max((r.Height() - tcy) / 2, 0);
|
||||
if(tsz.cx > r.GetWidth()) {
|
||||
Size isz = DrawImg::threedots().GetSize();
|
||||
int wd = r.GetWidth() - isz.cx;
|
||||
w.Clip(r.left, r.top, wd, r.GetHeight());
|
||||
DrawTLText(w, x, tt, r.Width(), txt, font, ink);
|
||||
w.End();
|
||||
w.DrawImage(r.left + wd, tt + font.Info().GetAscent() - isz.cy, DrawImg::threedots(), ink);
|
||||
}
|
||||
else
|
||||
DrawTLText(w, x, tt, r.Width(), txt, font, ink);
|
||||
}
|
||||
|
||||
void StdDisplayClass::Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword s) const {
|
||||
LLOG("Display::Paint: " << q << " ink:" << ink << " paper:" << paper);
|
||||
PaintBackground(w, r, q, ink, paper, s);
|
||||
Paint0(w, r, q, ink, paper, s);
|
||||
}
|
||||
|
||||
Size StdDisplayClass::GetStdSize(const Value& q) const
|
||||
{
|
||||
Font font = StdFont();
|
||||
WString txt;
|
||||
if(IsType<AttrText>(q)) {
|
||||
const AttrText& t = ValueTo<AttrText>(q);
|
||||
txt = t.text;
|
||||
if(!IsNull(t.font))
|
||||
font = t.font;
|
||||
}
|
||||
else
|
||||
txt = IsString(q) ? q : StdConvert().Format(q);
|
||||
return GetTLTextSize(txt, font);
|
||||
}
|
||||
|
||||
#ifdef flagSO
|
||||
Display::Display() {}
|
||||
#endif
|
||||
|
||||
Display::~Display() {}
|
||||
|
||||
const Display& GLOBAL_V_INIT(StdDisplayClass, StdDisplay)
|
||||
const Display& GLOBAL_VP_INIT(StdDisplayClass, StdCenterDisplay, (ALIGN_CENTER))
|
||||
const Display& GLOBAL_VP_INIT(StdDisplayClass, StdRightDisplay, (ALIGN_RIGHT))
|
||||
|
||||
#ifdef flagSO
|
||||
ColorDisplayNull::ColorDisplayNull(String nulltext) : nulltext(nulltext) {}
|
||||
ColorDisplayNull::~ColorDisplayNull() {}
|
||||
#endif
|
||||
|
||||
void ColorDisplayNull::Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
if(IsNull(q))
|
||||
StdDisplay().Paint(w, r, nulltext, ink, paper, style);
|
||||
else
|
||||
w.DrawRect(r, Color(q));
|
||||
}
|
||||
|
||||
const Display& ColorDisplay() { return Single<ColorDisplayNull>(); }
|
||||
|
||||
class SizeTextDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const;
|
||||
};
|
||||
|
||||
void SizeTextDisplayCls::Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color, dword) const {
|
||||
w.DrawText(r.left, r.top, r.Width(), (String)q, Arial(-r.Height()), ink);
|
||||
}
|
||||
|
||||
const Display& SizeTextDisplay() { return Single<SizeTextDisplayCls>(); }
|
||||
|
||||
static inline int NScale(int sz, int r) {
|
||||
return sz ? sz < r ? r / sz * sz : r : 0;
|
||||
}
|
||||
|
||||
class CenteredImageDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
Image m = q;
|
||||
Size sz = m.GetSize();
|
||||
if(!IsNull(m))
|
||||
w.DrawImage(r.left + (r.Width() - sz.cx) / 2, r.top + (r.Height() - sz.cy) / 2, m);
|
||||
}
|
||||
virtual Size GetStdSize(const Value& q) const
|
||||
{
|
||||
return Image(q).GetSize();
|
||||
}
|
||||
};
|
||||
|
||||
const Display& CenteredImageDisplay() { return Single<CenteredImageDisplayCls>(); }
|
||||
|
||||
class CenteredHighlightImageDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
Image m = q;
|
||||
Size sz = m.GetSize();
|
||||
if(!IsNull(m))
|
||||
DrawHighlightImage(w, r.left + (r.Width() - sz.cx) / 2,
|
||||
r.top + (r.Height() - sz.cy) / 2, m);
|
||||
}
|
||||
virtual Size GetStdSize(const Value& q) const
|
||||
{
|
||||
return Image(q).GetSize();
|
||||
}
|
||||
};
|
||||
|
||||
const Display& CenteredHighlightImageDisplay()
|
||||
{
|
||||
return Single<CenteredHighlightImageDisplayCls>();
|
||||
}
|
||||
|
||||
class ImageDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
Image m = q;
|
||||
if(!IsNull(m))
|
||||
w.DrawImage(r.left, r.top, Rescale(m, r.GetSize()));
|
||||
}
|
||||
virtual Size GetStdSize(const Value& q) const
|
||||
{
|
||||
return Image(q).GetSize();
|
||||
}
|
||||
};
|
||||
|
||||
const Display& ImageDisplay() { return Single<ImageDisplayCls>(); }
|
||||
|
||||
class FittedImageDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
Image m = q;
|
||||
if(!IsNull(m)) {
|
||||
Size sz = GetFitSize(m.GetSize(), r.Size());
|
||||
Point p = r.CenterPos(sz);
|
||||
w.DrawImage(p.x, p.y, m);
|
||||
}
|
||||
}
|
||||
virtual Size GetStdSize(const Value& q) const
|
||||
{
|
||||
return Image(q).GetSize();
|
||||
}
|
||||
};
|
||||
|
||||
const Display& FittedImageDisplay() { return Single<FittedImageDisplayCls>(); }
|
||||
|
||||
class DrawingDisplayCls : public Display {
|
||||
public:
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const;
|
||||
virtual Size GetStdSize(const Value& q) const;
|
||||
virtual Size RatioSize(const Value& q, int cx, int cy) const;
|
||||
};
|
||||
|
||||
void DrawingDisplayCls::Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color, Color, dword) const {
|
||||
w.DrawDrawing(r, q);
|
||||
}
|
||||
|
||||
Size DrawingDisplayCls::GetStdSize(const Value& q) const {
|
||||
return ((const Drawing&) q).GetSize();
|
||||
}
|
||||
|
||||
Size DrawingDisplayCls::RatioSize(const Value& q, int cx, int cy) const {
|
||||
return ((const Drawing&) q).RatioSize(cx, cy);
|
||||
}
|
||||
|
||||
const Display& DrawingDisplay() { return Single<DrawingDisplayCls>(); }
|
||||
|
||||
Size PaintRect::GetStdSize() const {
|
||||
return display ? display->GetStdSize(value) : Size(0, 0);
|
||||
}
|
||||
|
||||
Size PaintRect::RatioSize(int cx, int cy) const {
|
||||
return display ? display->RatioSize(value, cx, cy) : Size(0, 0);
|
||||
}
|
||||
|
||||
void PaintRect::Paint(Draw& w, const Rect& r,
|
||||
Color ink, Color paper, dword style) const {
|
||||
if(display)
|
||||
display->Paint(w, r, value, ink, paper, style);
|
||||
}
|
||||
|
||||
void PaintRect::Paint(Draw& w, int x, int y, int cx, int cy,
|
||||
Color ink, Color paper, dword style) const {
|
||||
Paint(w, RectC(x, y, cx, cy), ink, paper, style);
|
||||
}
|
||||
|
||||
PaintRect::PaintRect() {
|
||||
display = NULL;
|
||||
}
|
||||
|
||||
PaintRect::PaintRect(const Display& _display) {
|
||||
display = &_display;
|
||||
}
|
||||
|
||||
PaintRect::PaintRect(const Display& _display, const Value& _val) {
|
||||
display = &_display;
|
||||
value = _val;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
100
archive/olddraw/Draw/Display.h
Normal file
100
archive/olddraw/Draw/Display.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
class Display {
|
||||
public:
|
||||
enum {
|
||||
CURSOR = 0x01,
|
||||
FOCUS = 0x02,
|
||||
SELECT = 0x04,
|
||||
READONLY = 0x08,
|
||||
};
|
||||
|
||||
virtual void PaintBackground(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const;
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const;
|
||||
virtual Size GetStdSize(const Value& q) const;
|
||||
virtual Size RatioSize(const Value& q, int cx, int cy) const;
|
||||
#ifdef flagSO
|
||||
Display();
|
||||
#endif
|
||||
virtual ~Display();
|
||||
};
|
||||
|
||||
struct AttrText {
|
||||
WString text;
|
||||
Font font;
|
||||
Color ink;
|
||||
Color paper;
|
||||
int align;
|
||||
|
||||
AttrText& Ink(Color c) { ink = c; return *this; }
|
||||
AttrText& Paper(Color c) { paper = c; return *this; }
|
||||
AttrText& SetFont(Font f) { font = f; return *this; }
|
||||
AttrText& Align(int a) { align = a; return *this; }
|
||||
AttrText& Left() { return Align(ALIGN_LEFT); }
|
||||
AttrText& Center() { return Align(ALIGN_CENTER); }
|
||||
AttrText& Right() { return Align(ALIGN_RIGHT); }
|
||||
|
||||
operator Value() const;
|
||||
|
||||
AttrText(const char *text);
|
||||
AttrText(const wchar *text);
|
||||
AttrText(const WString& text);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
};
|
||||
|
||||
const Display& StdDisplay();
|
||||
const Display& StdCenterDisplay();
|
||||
const Display& StdRightDisplay();
|
||||
|
||||
const Display& ColorDisplay();
|
||||
const Display& SizeTextDisplay();
|
||||
const Display& ImageDisplay();
|
||||
const Display& FittedImageDisplay();
|
||||
const Display& CenteredImageDisplay();
|
||||
const Display& CenteredHighlightImageDisplay();
|
||||
const Display& DrawingDisplay();
|
||||
|
||||
class ColorDisplayNull : public Display {
|
||||
public:
|
||||
#ifdef flagSO
|
||||
ColorDisplayNull(String nulltext = Null);
|
||||
virtual ~ColorDisplayNull();
|
||||
#else
|
||||
ColorDisplayNull(String nulltext = Null) : nulltext(nulltext) {}
|
||||
#endif
|
||||
virtual void Paint(Draw& w, const Rect& r, const Value& q,
|
||||
Color ink, Color paper, dword style) const;
|
||||
private:
|
||||
String nulltext;
|
||||
};
|
||||
|
||||
class PaintRect : Moveable<PaintRect> {
|
||||
protected:
|
||||
Value value;
|
||||
const Display *display;
|
||||
|
||||
public:
|
||||
void Paint(Draw& w, const Rect& r,
|
||||
Color ink = SColorText, Color paper = SColorPaper, dword style = 0) const;
|
||||
void Paint(Draw& w, int x, int y, int cx, int cy,
|
||||
Color ink = SColorText, Color paper = SColorPaper, dword style = 0) const;
|
||||
Size GetStdSize() const;
|
||||
Size RatioSize(int cx, int cy) const;
|
||||
Size RatioSize(Size sz) const { return RatioSize(sz.cx, sz.cy); }
|
||||
|
||||
void SetDisplay(const Display& d) { display = &d; }
|
||||
void SetValue(const Value& v) { value = v; }
|
||||
void Set(const Display& d, const Value& v) { display = &d; value = v; }
|
||||
void Clear() { display = NULL; }
|
||||
|
||||
const Value& GetValue() const { return value; }
|
||||
const Display& GetDisplay() const { return *display; }
|
||||
|
||||
operator bool() const { return display; }
|
||||
|
||||
PaintRect();
|
||||
PaintRect(const Display& display);
|
||||
PaintRect(const Display& display, const Value& val);
|
||||
};
|
||||
432
archive/olddraw/Draw/Draw.cpp
Normal file
432
archive/olddraw/Draw/Draw.cpp
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // RLOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
INITBLOCK {
|
||||
RichValue<Painting>::Register();
|
||||
RichValue<Drawing>::Register();
|
||||
}
|
||||
|
||||
Size Draw::GetNativeDpi() const
|
||||
{
|
||||
return nativeDpi;
|
||||
}
|
||||
|
||||
int Draw::GetNativeX(int x) const
|
||||
{
|
||||
return inchPixels != nativeDpi ? iscale(x, nativeDpi.cx, 600) : x;
|
||||
}
|
||||
|
||||
int Draw::GetNativeY(int y) const
|
||||
{
|
||||
return inchPixels != nativeDpi ? iscale(y, nativeDpi.cy, 600) : y;
|
||||
}
|
||||
|
||||
void Draw::Native(int& x, int& y) const
|
||||
{
|
||||
x = GetNativeX(x);
|
||||
y = GetNativeY(y);
|
||||
}
|
||||
|
||||
void Draw::Native(Point& p) const
|
||||
{
|
||||
Native(p.x, p.y);
|
||||
}
|
||||
|
||||
void Draw::Native(Size& sz) const
|
||||
{
|
||||
Native(sz.cx, sz.cy);
|
||||
}
|
||||
|
||||
void Draw::Native(Rect& r) const
|
||||
{
|
||||
Native(r.left, r.top);
|
||||
Native(r.right, r.bottom);
|
||||
}
|
||||
|
||||
void Draw::StartPage() {}
|
||||
void Draw::EndPage() {}
|
||||
|
||||
// -------------------------------
|
||||
|
||||
bool Draw::IsDrawing() const
|
||||
{
|
||||
return dynamic_cast<const DrawingDraw *>(this);
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
|
||||
void Draw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("DrawImageOp");
|
||||
bool tonative = !IsNative();
|
||||
if(tonative) {
|
||||
BeginNative();
|
||||
Native(x, y);
|
||||
Native(cx, cy);
|
||||
}
|
||||
Size sz = Size(cx, cy);
|
||||
if((cx > 2000 || cy > 1500) && IsNull(color) && IsPrinter()) {
|
||||
int yy = 0;
|
||||
ImageRaster ir(img);
|
||||
RescaleImage rm;
|
||||
rm.Create(Size(cx, cy), ir, src);
|
||||
while(yy < cy) {
|
||||
int ccy = min(cy - yy, 16);
|
||||
ImageBuffer ib(cx, ccy);
|
||||
for(int q = 0; q < ccy; q++)
|
||||
rm.Get(ib[q]);
|
||||
DrawImageBandRLE(*this, x, y + yy, ib, 16);
|
||||
yy += ccy;
|
||||
}
|
||||
}
|
||||
else
|
||||
if(src.GetSize() == sz)
|
||||
img.PaintImage(*this, x, y, src, color);
|
||||
else {
|
||||
Image h = Rescale(img, Size(cx, cy), src);
|
||||
h.PaintImage(*this, x, y, h.GetSize(), color);
|
||||
}
|
||||
if(tonative)
|
||||
EndNative();
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
|
||||
void Draw::DrawRect(const Rect& rect, Color color)
|
||||
{
|
||||
DrawRect(rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src)
|
||||
{
|
||||
DrawImageOp(x, y, cx, cy, img, src, Null);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, int cx, int cy, const Image& img)
|
||||
{
|
||||
DrawImage(x, y, cx, cy, img, img.GetSize());
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
DrawImageOp(x, y, cx, cy, img, src, color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, int cx, int cy, const Image& img, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
DrawImage(x, y, cx, cy, img, img.GetSize(), color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(const Rect& r, const Image& img, const Rect& src)
|
||||
{
|
||||
DrawImage(r.left, r.top, r.Width(), r.Height(), img, src);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(const Rect& r, const Image& img)
|
||||
{
|
||||
DrawImage(r.left, r.top, r.Width(), r.Height(), img);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(const Rect& r, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
DrawImage(r.left, r.top, r.Width(), r.Height(), img, src, color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(const Rect& r, const Image& img, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
DrawImage(r.left, r.top, r.Width(), r.Height(), img, color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, const Image& img, const Rect& src)
|
||||
{
|
||||
Size sz = src.GetSize();
|
||||
DrawImageOp(x, y, sz.cx, sz.cy, img, src, Null);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, const Image& img)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
DrawImageOp(x, y, sz.cx, sz.cy, img, img.GetSize(), Null);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
Size sz = img.GetSize();
|
||||
DrawImageOp(x, y, sz.cx, sz.cy, img, src, color);
|
||||
}
|
||||
|
||||
void Draw::DrawImage(int x, int y, const Image& img, Color color)
|
||||
{
|
||||
if(IsNull(color)) return;
|
||||
Size sz = img.GetSize();
|
||||
DrawImageOp(x, y, sz.cx, sz.cy, img, img.GetSize(), color);
|
||||
}
|
||||
|
||||
void Draw::DrawData(int x, int y, int cx, int cy, const String& data, const char *type)
|
||||
{
|
||||
DrawDataOp(x, y, cx, cy, data, type);
|
||||
}
|
||||
|
||||
void Draw::DrawData(const Rect& r, const String& data, const char *type)
|
||||
{
|
||||
DrawDataOp(r.left, r.top, r.GetWidth(), r.GetHeight(), data, type);
|
||||
}
|
||||
|
||||
void Draw::DrawLine(Point p1, Point p2, int width, Color color)
|
||||
{
|
||||
DrawLine(p1.x, p1.y, p2.x, p2.y, width, color);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
void Draw::DrawPolyPolyline(const Vector<Point>& vertices, const Vector<int>& counts,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
DrawPolyPolyline(vertices.Begin(), vertices.GetCount(),
|
||||
counts.Begin(), counts.GetCount(),
|
||||
width, color, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyline(const Point *vertices, int count,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
DrawPolyPolyline(vertices, count, &count, 1, width, color, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyline(const Vector<Point>& vertices,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
DrawPolyline(vertices.Begin(), vertices.GetCount(), width, color, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolyPolygon(const Vector<Point>& vertices,
|
||||
const Vector<int>& subpolygon_counts,
|
||||
const Vector<int>& disjunct_polygon_counts,
|
||||
Color color, int width, Color outline,
|
||||
uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolyPolyPolygon(vertices.Begin(), vertices.GetCount(),
|
||||
subpolygon_counts.Begin(), subpolygon_counts.GetCount(),
|
||||
disjunct_polygon_counts.Begin(), disjunct_polygon_counts.GetCount(),
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolygon(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolyPolyPolygon(vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count, &vertex_count, 1,
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolygon(const Vector<Point>& vertices, const Vector<int>& subpolygon_counts,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolyPolygon(vertices.Begin(), vertices.GetCount(),
|
||||
subpolygon_counts.Begin(), subpolygon_counts.GetCount(),
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolygons(const Point *vertices, int vertex_count,
|
||||
const int *polygon_counts, int polygon_count_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolyPolyPolygon(vertices, vertex_count,
|
||||
polygon_counts, polygon_count_count,
|
||||
polygon_counts, polygon_count_count,
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolygons(const Vector<Point>& vertices, const Vector<int>& polygon_counts,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolygons(vertices.Begin(), vertices.GetCount(),
|
||||
polygon_counts.Begin(), polygon_counts.GetCount(),
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolygon(const Point *vertices, int vertex_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolyPolyPolygon(vertices, vertex_count, &vertex_count, 1, &vertex_count, 1,
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
|
||||
void Draw::DrawPolygon(const Vector<Point>& vertices,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawPolygon(vertices.Begin(), vertices.GetCount(), color, width, outline, pattern, doxor);
|
||||
}
|
||||
#endif
|
||||
void Draw::DrawEllipse(int x, int y, int cx, int cy, Color color, int pen, Color pencolor)
|
||||
{
|
||||
DrawEllipse(RectC(x, y, cx, cy), color, pen, pencolor);
|
||||
}
|
||||
|
||||
void Draw::Offset(int x, int y)
|
||||
{
|
||||
Offset(Point(x, y));
|
||||
}
|
||||
|
||||
bool Draw::Clip(int x, int y, int cx, int cy)
|
||||
{
|
||||
return Clip(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
bool Draw::Clipoff(int x, int y, int cx, int cy)
|
||||
{
|
||||
return Clipoff(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
bool Draw::ExcludeClip(int x, int y, int cx, int cy)
|
||||
{
|
||||
return ExcludeClip(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
bool Draw::IntersectClip(int x, int y, int cx, int cy)
|
||||
{
|
||||
return IntersectClip(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
bool Draw::IsPainting(int x, int y, int cx, int cy) const
|
||||
{
|
||||
return IsPainting(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
static void (*sIgfn)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos, int mode);
|
||||
static void (*sIwfn)(ImageBuffer& ib, const Drawing& p, int mode);
|
||||
|
||||
void RegisterPaintingFns__(void (*ig)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos, int mode),
|
||||
void (*iw)(ImageBuffer& ib, const Drawing& p, int mode))
|
||||
{
|
||||
sIgfn = ig;
|
||||
sIwfn = iw;
|
||||
}
|
||||
|
||||
bool HasPainter()
|
||||
{
|
||||
return sIgfn && sIwfn;
|
||||
}
|
||||
|
||||
void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos, int mode)
|
||||
{
|
||||
if(sIgfn)
|
||||
(*sIgfn)(ib, p, sz, pos, mode);
|
||||
}
|
||||
|
||||
void PaintImageBuffer(ImageBuffer& ib, const Painting& p, int mode)
|
||||
{
|
||||
PaintImageBuffer(ib, p, ib.GetSize(), Point(0, 0), mode);
|
||||
}
|
||||
|
||||
void PaintImageBuffer(ImageBuffer& ib, const Drawing& iw, int mode)
|
||||
{
|
||||
if(sIwfn)
|
||||
(*sIwfn)(ib, iw, mode);
|
||||
}
|
||||
|
||||
void Draw::DrawPaintingOp(const Rect& target, const Painting& pw)
|
||||
{
|
||||
if(!HasPainter())
|
||||
return;
|
||||
Size sz = target.GetSize();
|
||||
if((sz.cx > 2000 || sz.cy > 1500) && IsPrinter()) {
|
||||
int yy = 0;
|
||||
while(yy < sz.cy) {
|
||||
int ccy = min(sz.cy - yy, 100);
|
||||
ImageBuffer ib(sz.cx, ccy);
|
||||
Fill(~ib, White(), ib.GetLength());
|
||||
PaintImageBuffer(ib, pw, sz, Point(0, yy), true);
|
||||
DrawImageBandRLE(*this, target.left, target.top + yy, ib, 16);
|
||||
yy += ccy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImageBuffer ib(sz);
|
||||
Fill(~ib, IsPrinter() ? White() : SColorPaper(), ib.GetLength());
|
||||
PaintImageBuffer(ib, pw, sz, Point(0, 0), IsPrinter());
|
||||
DrawImage(target.left, target.top, ib);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawPainting(int x, int y, int cx, int cy, const Painting& ig)
|
||||
{
|
||||
DrawPainting(RectC(x, y, cx, cy), ig);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
void NilDraw::BeginOp() {}
|
||||
bool NilDraw::ClipOp(const Rect& r) { return false; }
|
||||
bool NilDraw::ClipoffOp(const Rect& r) { return false; }
|
||||
void NilDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) {}
|
||||
void NilDraw::DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id) {}
|
||||
void NilDraw::DrawDrawingOp(const Rect& target, const Drawing& w) {}
|
||||
void NilDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) {}
|
||||
void NilDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) {}
|
||||
void NilDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) {}
|
||||
void NilDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor) {}
|
||||
void NilDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor) {}
|
||||
void NilDraw::DrawRectOp(int x, int y, int cx, int cy, Color color) {}
|
||||
void NilDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) {}
|
||||
void NilDraw::EndOp() {}
|
||||
void NilDraw::EndPage() {}
|
||||
bool NilDraw::ExcludeClipOp(const Rect& r) { return false; }
|
||||
Rect NilDraw::GetClipOp() const { return Null; }
|
||||
bool NilDraw::IntersectClipOp(const Rect& r) { return false; }
|
||||
bool NilDraw::IsPaintingOp(const Rect& r) const { return false; }
|
||||
void NilDraw::OffsetOp(Point p) {}
|
||||
void NilDraw::StartPage() {}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
Draw& ScreenInfo();
|
||||
|
||||
void BackDraw::Create(int cx, int cy)
|
||||
{
|
||||
DrawLock __;
|
||||
Create(ScreenInfo(), cx, cy);
|
||||
}
|
||||
|
||||
bool BackDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
Rect rr = r + GetOffset();
|
||||
if(!rr.Intersects(size))
|
||||
return false;
|
||||
return painting ? painting->IsPainting(rr + painting_offset) : true;
|
||||
}
|
||||
|
||||
BackDraw::BackDraw()
|
||||
{
|
||||
painting = NULL;
|
||||
painting_offset = Point(0, 0);
|
||||
}
|
||||
|
||||
BackDraw::~BackDraw()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
Draw& ScreenInfo();
|
||||
|
||||
bool ScreenInPaletteMode()
|
||||
{
|
||||
return ScreenInfo().PaletteMode();
|
||||
}
|
||||
|
||||
Size GetScreenSize()
|
||||
{
|
||||
return ScreenInfo().GetPagePixels();
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
1247
archive/olddraw/Draw/Draw.h
Normal file
1247
archive/olddraw/Draw/Draw.h
Normal file
File diff suppressed because it is too large
Load diff
88
archive/olddraw/Draw/Draw.upp
Normal file
88
archive/olddraw/Draw/Draw.upp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
description "Fundamental graphics operations, including raster image processing\377B128,0,255";
|
||||
|
||||
acceptflags
|
||||
NOGTK;
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
library((LINUX | BSD) & !NOGTK) "gtk-x11-2.0 gdk-x11-2.0 atk-1.0 gdk_pixbuf-2.0 m pangocairo-1.0 fontconfig Xext Xrender Xinerama Xi Xrandr Xcursor Xfixes pango-1.0 cairo X11 gobject-2.0 gmodule-2.0 glib-2.0";
|
||||
|
||||
library(WIN32 !MSC8ARM) "user32 gdi32";
|
||||
|
||||
library(LINUX) X11;
|
||||
|
||||
library(LINUX) dl;
|
||||
|
||||
library(LINUX !XLFD) Xft;
|
||||
|
||||
library(BSD) "X11 Xau Xdmcp";
|
||||
|
||||
library(BSD !XLFD) "Xft fontconfig Xrender freetype expat";
|
||||
|
||||
library(LINUX !XLFD !SHARED) "fontconfig Xrender freetype expat";
|
||||
|
||||
library(OSX11) "X11 Xft fontconfig Xrender freetype expat";
|
||||
|
||||
library(FREEBSD) xcb;
|
||||
|
||||
file
|
||||
Draw.h,
|
||||
DrawWin32.h,
|
||||
Mt.cpp,
|
||||
DrawWin32.cpp,
|
||||
DrawX11.cpp,
|
||||
ComposeText.cpp,
|
||||
DrawText.cpp,
|
||||
DrawTextWin32.cpp,
|
||||
DrawTextXft.cpp,
|
||||
Draw.cpp,
|
||||
DrawOpWin32.cpp,
|
||||
DrawOpX11.cpp,
|
||||
DrawData.cpp,
|
||||
Drawing.cpp,
|
||||
MetaFile.cpp,
|
||||
DrawUtil.cpp,
|
||||
DrawTextUtil.cpp,
|
||||
Display.h,
|
||||
Display.cpp,
|
||||
Debug.h,
|
||||
Debug.cpp,
|
||||
Image readonly separator,
|
||||
Image.h,
|
||||
ImageDraw.h,
|
||||
Image.cpp,
|
||||
ImageBlit.cpp,
|
||||
ImageWin32.cpp,
|
||||
ImageX11.cpp,
|
||||
Raster.h,
|
||||
RasterFormat.cpp,
|
||||
RasterWrite.cpp,
|
||||
Palette.cpp,
|
||||
Raster.cpp,
|
||||
RasterEncoder.cpp,
|
||||
ImageOp.h,
|
||||
ImageOp.cpp,
|
||||
ImageChOp.cpp,
|
||||
ImageScale.cpp,
|
||||
MakeCache.cpp,
|
||||
DrawRasterData.cpp,
|
||||
iml.h,
|
||||
iml_header.h,
|
||||
iml_source.h,
|
||||
DrawImg.iml,
|
||||
Chameleon readonly separator,
|
||||
Cham.h,
|
||||
Cham.cpp,
|
||||
SSettings.cpp,
|
||||
GTK-dli readonly separator,
|
||||
gobj.dli,
|
||||
gdk.dli,
|
||||
gpixbuf.dli,
|
||||
gtk.dli,
|
||||
gnome.dli,
|
||||
Info readonly separator,
|
||||
src.tpp,
|
||||
srcdoc.tpp,
|
||||
Copying;
|
||||
|
||||
127
archive/olddraw/Draw/DrawData.cpp
Normal file
127
archive/olddraw/Draw/DrawData.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x)
|
||||
// #define BENCHMARK_RLE
|
||||
|
||||
VectorMap<String, void *>& DataDrawer::Map()
|
||||
{
|
||||
static VectorMap<String, void *> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
static StaticCriticalSection sDataDrawer;
|
||||
|
||||
void DataDrawer::AddFormat(const char *id, Factory factory)
|
||||
{
|
||||
INTERLOCKED_(sDataDrawer)
|
||||
Map().Add(id, (void *)factory);
|
||||
}
|
||||
|
||||
One<DataDrawer> DataDrawer::Create(const String& id)
|
||||
{
|
||||
INTERLOCKED_(sDataDrawer) {
|
||||
Factory q = (Factory) Map().Get(id, NULL);
|
||||
if(q)
|
||||
return (*q)();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool IsWhiteColumn(const Image& m, int x)
|
||||
{
|
||||
LTIMING("IsEqColumn");
|
||||
Size sz = m.GetSize();
|
||||
const RGBA *s = ~m + x;
|
||||
while(sz.cy > 1) {
|
||||
s += sz.cx;
|
||||
if((s->a & s->r & s->g & s->b) != 255)
|
||||
return false;
|
||||
sz.cy--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef BENCHMARK_RLE
|
||||
static int sTotal;
|
||||
static int sRle;
|
||||
|
||||
EXITBLOCK
|
||||
{
|
||||
DUMP(sTotal);
|
||||
DUMP(sRle);
|
||||
}
|
||||
#endif
|
||||
|
||||
void DrawImageBandRLE(Draw& w, int x, int y, const Image& m, int minp)
|
||||
{
|
||||
int xi = 0;
|
||||
int cx = m.GetWidth();
|
||||
int ccy = m.GetHeight();
|
||||
Buffer<bool> todo(cx, true);
|
||||
#ifdef BENCHMARK_RLE
|
||||
sTotal += cx;
|
||||
#endif
|
||||
while(xi < cx) {
|
||||
int xi0 = xi;
|
||||
while(w.Dots() && IsWhiteColumn(m, xi) && xi < cx)
|
||||
xi++;
|
||||
if(xi - xi0 >= 16) {
|
||||
#ifdef BENCHMARK_RLE
|
||||
sRle += xi - xi0;
|
||||
#endif
|
||||
w.DrawRect(x + xi0, y, xi - xi0, ccy, White);
|
||||
Fill(~todo + xi0, ~todo + xi, false);
|
||||
}
|
||||
xi++;
|
||||
}
|
||||
|
||||
xi = 0;
|
||||
while(xi < cx)
|
||||
if(todo[xi]) {
|
||||
int xi0 = xi;
|
||||
while(xi < cx && todo[xi] && xi - xi0 < 2000)
|
||||
xi++;
|
||||
m.PaintImage(w, x + xi0, y, RectC(xi0, 0, xi - xi0, ccy), Null);
|
||||
}
|
||||
else
|
||||
xi++;
|
||||
}
|
||||
|
||||
void Draw::DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id)
|
||||
{
|
||||
DrawLock __;
|
||||
bool tonative = !IsNative();
|
||||
if(tonative) {
|
||||
BeginNative();
|
||||
Native(x, y);
|
||||
Native(cx, cy);
|
||||
}
|
||||
One<DataDrawer> dd = DataDrawer::Create(id);
|
||||
if(dd) {
|
||||
dd->Open(data, cx, cy);
|
||||
if(cx > 2048 || cy > 2048) {
|
||||
int yy = 0;
|
||||
while(yy < cy) {
|
||||
int ccy = min(cy - yy, 32);
|
||||
ImageBuffer ib(cx, ccy);
|
||||
dd->Render(ib);
|
||||
DrawImageBandRLE(*this, x, y + yy, ib, 16);
|
||||
yy += ccy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImageBuffer m(cx, cy);
|
||||
dd->Render(m);
|
||||
DrawImage(x, y, m);
|
||||
}
|
||||
}
|
||||
if(tonative)
|
||||
EndNative();
|
||||
}
|
||||
|
||||
DataDrawer::~DataDrawer() {}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
7
archive/olddraw/Draw/DrawImg.iml
Normal file
7
archive/olddraw/Draw/DrawImg.iml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
PREMULTIPLIED
|
||||
IMAGE_ID(threedots)
|
||||
|
||||
IMAGE_BEGIN_DATA
|
||||
IMAGE_DATA(120,156,99,96,99,96,103,192,1,54,3,177,40,22,241,255,64,188,10,136,37,176,136,195,228,176,137,167,99,17,71,23)
|
||||
IMAGE_DATA(3,129,80,92,14,130,1,0,129,113,9,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
IMAGE_END_DATA(64, 1)
|
||||
290
archive/olddraw/Draw/DrawOpWin32.cpp
Normal file
290
archive/olddraw/Draw/DrawOpWin32.cpp
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
void Draw::BeginOp()
|
||||
{
|
||||
LTIMING("Begin");
|
||||
DrawLock __;
|
||||
Cloff& w = cloff.Add();
|
||||
w.org = actual_offset;
|
||||
w.hrgn = CreateRectRgn(0, 0, 0, 0);
|
||||
ASSERT(w.hrgn);
|
||||
int q = ::GetClipRgn(handle, w.hrgn);
|
||||
ASSERT(q >= 0);
|
||||
if(q == 0) {
|
||||
DeleteObject(w.hrgn);
|
||||
w.hrgn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::OffsetOp(Point p)
|
||||
{
|
||||
DrawLock __;
|
||||
Begin();
|
||||
actual_offset += p;
|
||||
LTIMING("Offset");
|
||||
SetOrg();
|
||||
}
|
||||
|
||||
bool Draw::ClipOp(const Rect& r)
|
||||
{
|
||||
DrawLock __;
|
||||
Begin();
|
||||
LTIMING("Clip");
|
||||
return IntersectClip(r);
|
||||
}
|
||||
|
||||
bool Draw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
DrawLock __;
|
||||
Begin();
|
||||
LTIMING("Clipoff");
|
||||
LLOG("ClipoffOp " << r << ", GetClip() = " << GetClip() << ", actual_offset = " << actual_offset);
|
||||
actual_offset += r.TopLeft();
|
||||
bool q = IntersectClip(r);
|
||||
SetOrg();
|
||||
LLOG("//ClipoffOp, GetClip() = " << GetClip() << ", actual_offset = " << actual_offset);
|
||||
return q;
|
||||
}
|
||||
|
||||
void Draw::EndOp()
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("End");
|
||||
ASSERT(cloff.GetCount());
|
||||
Cloff& w = cloff.Top();
|
||||
actual_offset = w.org;
|
||||
::SelectClipRgn(handle, w.hrgn);
|
||||
SetOrg();
|
||||
if(w.hrgn)
|
||||
::DeleteObject(w.hrgn);
|
||||
cloff.Drop();
|
||||
}
|
||||
|
||||
bool Draw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
DrawLock __;
|
||||
#ifdef PLATFORM_WINCE
|
||||
int q = ExcludeClipRect(handle, r.left, r.top, r.right, r.bottom);
|
||||
#else
|
||||
LTIMING("ExcludeClip");
|
||||
Rect rr = LPtoDP(r);
|
||||
HRGN hrgn = ::CreateRectRgnIndirect(rr);
|
||||
int q = ::ExtSelectClipRgn(handle, hrgn, RGN_DIFF);
|
||||
ASSERT(q != ERROR);
|
||||
::DeleteObject(hrgn);
|
||||
#endif
|
||||
return q == SIMPLEREGION || q == COMPLEXREGION;
|
||||
}
|
||||
|
||||
bool Draw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
DrawLock __;
|
||||
#ifdef PLATFORM_WINCE
|
||||
int q = IntersectClipRect(handle, r.left, r.top, r.right, r.bottom);
|
||||
#else
|
||||
LTIMING("Intersect");
|
||||
Rect rr = LPtoDP(r);
|
||||
HRGN hrgn = ::CreateRectRgnIndirect(rr);
|
||||
int q = ::ExtSelectClipRgn(handle, hrgn, RGN_AND);
|
||||
ASSERT(q != ERROR);
|
||||
::DeleteObject(hrgn);
|
||||
#endif
|
||||
return q == SIMPLEREGION || q == COMPLEXREGION;
|
||||
}
|
||||
|
||||
Rect Draw::GetClipOp() const
|
||||
{
|
||||
DrawLock __;
|
||||
Rect r;
|
||||
::GetClipBox(handle, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Draw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("IsPainting");
|
||||
LLOG("Draw::IsPaintingOp r: " << r);
|
||||
return ::RectVisible(handle, r);
|
||||
}
|
||||
|
||||
void Draw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("DrawRect");
|
||||
LLOG("DrawRect " << RectC(x, y, cx, cy) << ": " << color);
|
||||
if(IsNull(color)) return;
|
||||
if(cx <= 0 || cy <= 0) return;
|
||||
if(color == InvertColor)
|
||||
::PatBlt(handle, x, y, cx, cy, DSTINVERT);
|
||||
else {
|
||||
SetColor(color);
|
||||
::PatBlt(handle, x, y, cx, cy, PATCOPY);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsNull(width) || IsNull(color)) return;
|
||||
SetDrawPen(width, color);
|
||||
::MoveToEx(handle, x1, y1, NULL);
|
||||
::LineTo(handle, x2, y2);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
|
||||
void Draw::DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
DrawLock __;
|
||||
ASSERT(count_count > 0 && vertex_count > 0);
|
||||
if(vertex_count < 2 || IsNull(color))
|
||||
return;
|
||||
bool is_xor = !IsNull(doxor);
|
||||
if(is_xor)
|
||||
color = Color(color.GetR() ^ doxor.GetR(), color.GetG() ^ doxor.GetG(), color.GetB() ^ doxor.GetB());
|
||||
if(is_xor)
|
||||
SetROP2(GetHandle(), R2_XORPEN);
|
||||
SetDrawPen(width, color);
|
||||
if(count_count == 1)
|
||||
::Polyline(GetHandle(), (const POINT *)vertices, vertex_count);
|
||||
else
|
||||
::PolyPolyline(GetHandle(), (const POINT *)vertices,
|
||||
(const dword *)counts, count_count);
|
||||
if(is_xor)
|
||||
SetROP2(GetHandle(), R2_COPYPEN);
|
||||
}
|
||||
|
||||
static void DrawPolyPolyPolygonRaw(
|
||||
Draw& draw, const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count,
|
||||
const int *disjunct_polygon_counts, int disjunct_polygon_count_count)
|
||||
{
|
||||
DrawLock __;
|
||||
for(int i = 0; i < disjunct_polygon_count_count; i++, disjunct_polygon_counts++)
|
||||
{
|
||||
int poly = *disjunct_polygon_counts;
|
||||
int sub = 1;
|
||||
if(*subpolygon_counts < poly)
|
||||
if(disjunct_polygon_count_count > 1)
|
||||
{
|
||||
const int *se = subpolygon_counts;
|
||||
int total = 0;
|
||||
while(total < poly)
|
||||
total += *se++;
|
||||
sub = (int)(se - subpolygon_counts);
|
||||
}
|
||||
else
|
||||
sub = subpolygon_count_count;
|
||||
ASSERT(sizeof(POINT) == sizeof(Point)); // modify algorithm when not
|
||||
if(sub == 1)
|
||||
Polygon(draw, (const POINT *)vertices, poly);
|
||||
else
|
||||
PolyPolygon(draw, (const POINT *)vertices, subpolygon_counts, sub);
|
||||
vertices += poly;
|
||||
subpolygon_counts += sub;
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count,
|
||||
const int *disjunct_polygon_counts, int disjunct_polygon_count_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawLock __;
|
||||
if(vertex_count == 0)
|
||||
return;
|
||||
bool is_xor = !IsNull(doxor);
|
||||
HDC hdc = GetHandle();
|
||||
if(pattern) {
|
||||
int old_rop = GetROP2(hdc);
|
||||
HGDIOBJ old_brush = GetCurrentObject(hdc, OBJ_BRUSH);
|
||||
word wpat[8] = {
|
||||
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
|
||||
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
|
||||
};
|
||||
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
|
||||
HBRUSH brush = ::CreatePatternBrush(bitmap);
|
||||
COLORREF old_bk = GetBkColor(hdc);
|
||||
COLORREF old_fg = GetTextColor(hdc);
|
||||
if(!is_xor) {
|
||||
SetROP2(hdc, R2_MASKPEN);
|
||||
SelectObject(hdc, brush);
|
||||
SetTextColor(hdc, Black());
|
||||
SetBkColor(hdc, White());
|
||||
SetDrawPen(PEN_NULL, Black);
|
||||
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
SetROP2(hdc, R2_MERGEPEN);
|
||||
SetTextColor(hdc, color);
|
||||
SetBkColor(hdc, Black());
|
||||
}
|
||||
else {
|
||||
SetROP2(hdc, R2_XORPEN);
|
||||
SetTextColor(hdc, COLORREF(color) ^ COLORREF(doxor));
|
||||
SelectObject(hdc, brush);
|
||||
}
|
||||
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
SelectObject(hdc, old_brush);
|
||||
SetTextColor(hdc, old_fg);
|
||||
SetBkColor(hdc, old_bk);
|
||||
SetROP2(hdc, old_rop);
|
||||
DeleteObject(brush);
|
||||
DeleteObject(bitmap);
|
||||
if(!IsNull(outline)) {
|
||||
SetColor(Null);
|
||||
SetDrawPen(width, outline);
|
||||
ASSERT(sizeof(POINT) == sizeof(Point));
|
||||
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
}
|
||||
}
|
||||
else { // simple fill
|
||||
SetDrawPen(IsNull(outline) ? PEN_NULL : width, Nvl(outline, Black));
|
||||
int old_rop2;
|
||||
if(is_xor) {
|
||||
color = Color(color.GetR() ^ doxor.GetR(), color.GetG() ^ doxor.GetG(), color.GetB() ^ doxor.GetB());
|
||||
old_rop2 = SetROP2(hdc, R2_XORPEN);
|
||||
}
|
||||
SetColor(color);
|
||||
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
if(is_xor)
|
||||
SetROP2(hdc, old_rop2);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
SetDrawPen(width, color);
|
||||
::Arc(GetHandle(), rc.left, rc.top, rc.right, rc.bottom, start.x, start.y, end.x, end.y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Draw::DrawEllipseOp(const Rect& r, Color color, int width, Color pencolor)
|
||||
{
|
||||
DrawLock __;
|
||||
SetColor(color);
|
||||
SetDrawPen(width, pencolor);
|
||||
::Ellipse(GetHandle(), r.left, r.top, r.right, r.bottom);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
320
archive/olddraw/Draw/DrawOpX11.cpp
Normal file
320
archive/olddraw/Draw/DrawOpX11.cpp
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // TIMING(x)
|
||||
|
||||
void Draw::BeginOp()
|
||||
{
|
||||
Cloff f = cloff.Top();
|
||||
Vector<Rect> newclip;
|
||||
newclip <<= clip.Top();
|
||||
f.clipi = clip.GetCount();
|
||||
clip.Add() = newclip;
|
||||
cloff.Add(f);
|
||||
}
|
||||
|
||||
void Draw::OffsetOp(Point p)
|
||||
{
|
||||
Cloff f = cloff.Top();
|
||||
f.offseti = offset.GetCount();
|
||||
actual_offset += p;
|
||||
offset.Add(actual_offset);
|
||||
cloff.Add(f);
|
||||
}
|
||||
|
||||
bool Draw::ClipOp(const Rect& r)
|
||||
{
|
||||
LLOG("Draw::ClipOp(" << r << ")");
|
||||
Cloff f = cloff.Top();
|
||||
bool ch = false;
|
||||
Vector<Rect> newclip = Intersect(clip.Top(), r + actual_offset, ch);
|
||||
if(ch) {
|
||||
f.clipi = clip.GetCount();
|
||||
clip.Add() = newclip;
|
||||
}
|
||||
cloff.Add(f);
|
||||
if(ch)
|
||||
SetClip();
|
||||
return clip.Top().GetCount();
|
||||
}
|
||||
|
||||
bool Draw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
LLOG("Draw::ClipOffOp(" << r << ")");
|
||||
Cloff f = cloff.Top();
|
||||
bool ch = false;
|
||||
Vector<Rect> newclip = Intersect(clip.Top(), r + actual_offset, ch);
|
||||
if(ch) {
|
||||
f.clipi = clip.GetCount();
|
||||
clip.Add() = newclip;
|
||||
}
|
||||
f.offseti = offset.GetCount();
|
||||
actual_offset += r.TopLeft();
|
||||
offset.Add(actual_offset);
|
||||
cloff.Add(f);
|
||||
if(ch)
|
||||
SetClip();
|
||||
return clip.Top().GetCount();
|
||||
}
|
||||
|
||||
void Draw::EndOp()
|
||||
{
|
||||
ASSERT(cloff.GetCount());
|
||||
cloff.Drop();
|
||||
actual_offset = offset[cloff.Top().offseti];
|
||||
clip.SetCount(cloff.Top().clipi + 1);
|
||||
SetClip();
|
||||
}
|
||||
|
||||
bool Draw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
LLOG("Draw::ExcludeClipOp(" << r << ")");
|
||||
CloneClip();
|
||||
Vector<Rect>& cl = clip.Top();
|
||||
bool ch = false;
|
||||
Vector<Rect> ncl = Subtract(cl, r + actual_offset, ch);
|
||||
if(ch) {
|
||||
cl = ncl;
|
||||
SetClip();
|
||||
}
|
||||
return clip.Top().GetCount();
|
||||
}
|
||||
|
||||
bool Draw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
CloneClip();
|
||||
Vector<Rect>& cl = clip.Top();
|
||||
bool ch = false;
|
||||
Vector<Rect> ncl = Intersect(cl, r + actual_offset, ch);
|
||||
if(ch) {
|
||||
cl = ncl;
|
||||
SetClip();
|
||||
}
|
||||
return clip.Top().GetCount();
|
||||
}
|
||||
|
||||
Rect Draw::GetClipOp() const
|
||||
{
|
||||
LLOG("Draw::GetClipOp; #clip = " << clip.GetCount() << ", #cloff = " << cloff.GetCount()
|
||||
<< ", clipi = " << cloff.Top().clipi);
|
||||
const Vector<Rect>& cl = clip[cloff.Top().clipi];
|
||||
Rect box(0, 0, 0, 0);
|
||||
if(!cl.GetCount()) return box;
|
||||
box = cl[0];
|
||||
LLOG("cl[0] = " << box);
|
||||
for(int i = 1; i < cl.GetCount(); i++) {
|
||||
LLOG("cl[" << i << "] = " << cl[i]);
|
||||
box |= cl[i];
|
||||
}
|
||||
LLOG("out box = " << box << ", actual offset = " << actual_offset);
|
||||
return box - actual_offset;
|
||||
}
|
||||
|
||||
bool Draw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
LTIMING("IsPaintingOp");
|
||||
Rect rr = r + actual_offset;
|
||||
const Vector<Rect>& cl = clip[cloff.Top().clipi];
|
||||
for(int i = 0; i < cl.GetCount(); i++)
|
||||
if(cl[i].Intersects(rr))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Draw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
LTIMING("DrawRect");
|
||||
DrawLock __;
|
||||
LLOG("DrawRect " << RectC(x, y, cx, cy) << ": " << color);
|
||||
if(IsNull(color)) return;
|
||||
if(cx <= 0 || cy <= 0) return;
|
||||
if(color == InvertColor) {
|
||||
XSetFunction(Xdisplay, gc, GXinvert);
|
||||
XFillRectangle(Xdisplay, dw, gc, x + actual_offset.x, y + actual_offset.y, cx, cy);
|
||||
XSetFunction(Xdisplay, gc, GXcopy);
|
||||
}
|
||||
else {
|
||||
SetForeground(color);
|
||||
XFillRectangle(Xdisplay, dw, gc, x + actual_offset.x, y + actual_offset.y, cx, cy);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsNull(width) || IsNull(color)) return;
|
||||
SetLineStyle(width);
|
||||
SetForeground(color);
|
||||
XDrawLine(Xdisplay, dw, gc,
|
||||
x1 + actual_offset.x, y1 + actual_offset.y,
|
||||
x2 + actual_offset.x, y2 + actual_offset.y);
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
DrawLock __;
|
||||
ASSERT(count_count > 0 && vertex_count > 0);
|
||||
if(vertex_count < 2 || IsNull(color))
|
||||
return;
|
||||
XGCValues gcv_old, gcv_new;
|
||||
XGetGCValues(Xdisplay, GetGC(), GCForeground | GCLineWidth | GCFunction, &gcv_old);
|
||||
gcv_new.function = IsNull(doxor) ? X11_ROP2_COPY : X11_ROP2_XOR;
|
||||
gcv_new.foreground = GetXPixel(color) ^ (IsNull(doxor) ? 0 : GetXPixel(doxor));
|
||||
gcv_new.line_width = width;
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground | GCLineWidth | GCFunction, &gcv_new);
|
||||
enum { REQUEST_LENGTH = 256 }; // X server XDrawLines request length (heuristic)
|
||||
Point offset = GetOffset();
|
||||
if(vertex_count == 2)
|
||||
XDrawLine(Xdisplay, GetDrawable(), GetGC(),
|
||||
vertices[0].x + offset.x, vertices[0].y + offset.y,
|
||||
vertices[1].x + offset.x, vertices[1].y + offset.y);
|
||||
else if(count_count == 1 || vertex_count > count_count * (REQUEST_LENGTH + 2)) {
|
||||
for(; --count_count >= 0; counts++)
|
||||
{
|
||||
Buffer<XPoint> part(*counts);
|
||||
for(XPoint *vo = part, *ve = vo + *counts; vo < ve; vo++, vertices++)
|
||||
{
|
||||
vo -> x = (short)(vertices -> x + offset.x);
|
||||
vo -> y = (short)(vertices -> y + offset.y);
|
||||
}
|
||||
XDrawLines(Xdisplay, GetDrawable(), GetGC(), part, *counts, CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int segment_count = vertex_count - count_count;
|
||||
Buffer<XSegment> segments(segment_count);
|
||||
XSegment *so = segments;
|
||||
while(--count_count >= 0)
|
||||
{
|
||||
const Point *end = vertices + *counts++;
|
||||
so -> x1 = (short)(vertices -> x + offset.x);
|
||||
so -> y1 = (short)(vertices -> y + offset.y);
|
||||
vertices++;
|
||||
so -> x2 = (short)(vertices -> x + offset.x);
|
||||
so -> y2 = (short)(vertices -> y + offset.y);
|
||||
so++;
|
||||
while(++vertices < end) {
|
||||
so -> x1 = so[-1].x2;
|
||||
so -> y1 = so[-1].y2;
|
||||
so -> x2 = (short)(vertices -> x + offset.x);
|
||||
so -> y2 = (short)(vertices -> y + offset.y);
|
||||
so++;
|
||||
}
|
||||
}
|
||||
ASSERT(so == segments + segment_count);
|
||||
XDrawSegments(Xdisplay, GetDrawable(), GetGC(), segments, segment_count);
|
||||
}
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground | GCLineWidth | GCFunction, &gcv_old);
|
||||
}
|
||||
|
||||
static void DrawPolyPolyPolygonRaw(Draw& draw, const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count, const int *, int)
|
||||
{
|
||||
DrawLock __;
|
||||
Point offset = draw.GetOffset();
|
||||
const Point *in = vertices;
|
||||
for(int i = 0; i < subpolygon_count_count; i++) {
|
||||
int n = subpolygon_counts[i];
|
||||
Buffer<XPoint> out_points(n);
|
||||
XPoint *t = out_points;
|
||||
XPoint *e = t + n;
|
||||
while(t < e) {
|
||||
t->x = (short)(in->x + offset.x);
|
||||
t->y = (short)(in->y + offset.y);
|
||||
t++;
|
||||
in++;
|
||||
}
|
||||
XFillPolygon(Xdisplay, draw.GetDrawable(), draw.GetGC(), out_points, n, Nonconvex, CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count,
|
||||
const int *disjunct_polygon_counts, int disjunct_polygon_count_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
DrawLock __;
|
||||
if(vertex_count == 0)
|
||||
return;
|
||||
|
||||
bool is_xor = !IsNull(doxor);
|
||||
XGCValues gcv_old, gcv_new;
|
||||
XGetGCValues(Xdisplay, GetGC(), GCForeground | GCFunction | GCLineWidth, &gcv_old);
|
||||
unsigned xor_pixel = (is_xor ? GetXPixel(doxor) : 0);
|
||||
if(!IsNull(color))
|
||||
{
|
||||
gcv_new.foreground = GetXPixel(color) ^ xor_pixel;
|
||||
gcv_new.function = is_xor ? X11_ROP2_XOR : X11_ROP2_COPY;
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground | GCFunction, &gcv_new);
|
||||
DrawPolyPolyPolygonRaw(*this, vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
}
|
||||
if(!IsNull(outline))
|
||||
{
|
||||
gcv_new.foreground = GetXPixel(outline) ^ xor_pixel;
|
||||
gcv_new.line_width = width;
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground | GCLineWidth, &gcv_new);
|
||||
Point offset = GetOffset();
|
||||
for(const int *sp = subpolygon_counts, *se = sp + subpolygon_count_count; sp < se; sp++)
|
||||
{
|
||||
Buffer<XPoint> segment(*sp + 1);
|
||||
XPoint *out = segment;
|
||||
for(const Point *end = vertices + *sp; vertices < end; vertices++, out++)
|
||||
{
|
||||
out -> x = (short)(vertices -> x + offset.x);
|
||||
out -> y = (short)(vertices -> y + offset.y);
|
||||
}
|
||||
*out = segment[0];
|
||||
XDrawLines(Xdisplay, GetDrawable(), GetGC(), segment, *sp + 1, CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground | GCFunction | GCLineWidth, &gcv_old);
|
||||
}
|
||||
|
||||
void Draw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
DrawLock __;
|
||||
SetLineStyle(pen);
|
||||
if(!IsNull(color)) {
|
||||
SetForeground(color);
|
||||
XFillArc(Xdisplay, dw, gc, r.left + actual_offset.x, r.top + actual_offset.y,
|
||||
r.Width() - 1, r.Height() - 1, 0, 360 * 64);
|
||||
}
|
||||
if(!IsNull(pencolor) && !IsNull(pen)) {
|
||||
SetForeground(pencolor);
|
||||
XDrawArc(Xdisplay, dw, gc, r.left + actual_offset.x, r.top + actual_offset.y,
|
||||
r.Width() - 1, r.Height() - 1, 0, 360 * 64);
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
XGCValues gcv, gcv_old;
|
||||
XGetGCValues(Xdisplay, GetGC(), GCForeground, &gcv_old);
|
||||
Point offset = GetOffset();
|
||||
gcv.foreground = GetXPixel(color);
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground, &gcv);
|
||||
Point centre = rc.CenterPoint();
|
||||
int angle1 = fround(360 * 64 / (2 * M_PI) *
|
||||
atan2(centre.y - start.y, start.x - centre.x));
|
||||
int angle2 = fround(360 * 64 / (2 * M_PI) *
|
||||
atan2(centre.y - end.y, end.x - centre.x));
|
||||
if(angle2 <= angle1)
|
||||
angle2 += 360 * 64;
|
||||
angle2 -= angle1;
|
||||
XDrawArc(Xdisplay, GetDrawable(), GetGC(), rc.left + offset.x, rc.top + offset.y,
|
||||
rc.Width(), rc.Height(), angle1, angle2);
|
||||
XChangeGC(Xdisplay, GetGC(), GCForeground, &gcv_old);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
40
archive/olddraw/Draw/DrawRasterData.cpp
Normal file
40
archive/olddraw/Draw/DrawRasterData.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
struct cDrawRasterData : DataDrawer {
|
||||
int cx;
|
||||
StringStream ss;
|
||||
One<StreamRaster> raster;
|
||||
RescaleImage si;
|
||||
|
||||
virtual void Open(const String& data, int cx, int cy);
|
||||
virtual void Render(ImageBuffer& ib);
|
||||
};
|
||||
|
||||
void cDrawRasterData::Open(const String& data, int _cx, int cy)
|
||||
{
|
||||
cx = _cx;
|
||||
ss.Open(data);
|
||||
raster = StreamRaster::OpenAny(ss);
|
||||
if(raster)
|
||||
si.Create(Size(cx, cy), *raster, raster->GetSize());
|
||||
}
|
||||
|
||||
void cDrawRasterData::Render(ImageBuffer& ib)
|
||||
{
|
||||
for(int y = 0; y < ib.GetHeight(); y++)
|
||||
si.Get(ib[y]);
|
||||
}
|
||||
|
||||
INITBLOCK
|
||||
{
|
||||
DataDrawer::Register<cDrawRasterData>("image_data");
|
||||
};
|
||||
|
||||
void DrawRasterData(Draw& w, int x, int y, int cx, int cy, const String& data)
|
||||
{
|
||||
w.DrawData(x, y, cx, cy, data, "image_data");
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
483
archive/olddraw/Draw/DrawText.cpp
Normal file
483
archive/olddraw/Draw/DrawText.cpp
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
|
||||
#if defined(PLATFORM_WIN32) || defined(PLATFORM_X11)
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // TIMING(x)
|
||||
|
||||
bool Draw::sFini;
|
||||
|
||||
void Draw::SinCos(int angle, double& sina, double& cosa)
|
||||
{
|
||||
angle = angle % 3600;
|
||||
switch(angle) {
|
||||
case 0: sina = 0; cosa = 1; break;
|
||||
case 900: sina = 1; cosa = 0; break;
|
||||
case 1800: sina = 0; cosa = -1; break;
|
||||
case 2700: sina = -1; cosa = 0; break;
|
||||
default:
|
||||
double a = angle * M_PI / 1800.0;
|
||||
sina = sin(a);
|
||||
cosa = cos(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Draw::StdFontSizeSet;
|
||||
Size Draw::StdFontSize;
|
||||
Font Draw::AStdFont;
|
||||
|
||||
INITBLOCK {
|
||||
RichValue<Font>::Register();
|
||||
}
|
||||
|
||||
void Draw::InitFonts()
|
||||
{
|
||||
DrawLock __;
|
||||
if(sFini) return;
|
||||
sFini = true;
|
||||
GetFontHash(0);
|
||||
GetFontLru();
|
||||
InitPlatformFonts();
|
||||
}
|
||||
|
||||
int FontFilter(int c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z' || c >= '0' && c <= '9' ? c : c >= 'A' && c <= 'Z' ? ToLower(c) : 0;
|
||||
}
|
||||
|
||||
int Font::FindFaceNameIndex(const char *name) {
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(GetFaceName(i) == name)
|
||||
return i;
|
||||
String n = Filter(name, FontFilter);
|
||||
for(int i = 1; i < GetFaceCount(); i++)
|
||||
if(Filter(GetFaceName(i), FontFilter) == n)
|
||||
return i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Draw& ScreenInfo();
|
||||
|
||||
FontInfo Font::Info() const
|
||||
{
|
||||
DrawLock __;
|
||||
return ScreenInfo().GetFontInfoW(*this);
|
||||
}
|
||||
|
||||
void Draw::SetStdFont(Font font)
|
||||
{
|
||||
InitFonts();
|
||||
AStdFont = font;
|
||||
StdFontSizeSet = false;
|
||||
}
|
||||
|
||||
Size Draw::GetStdFontSize()
|
||||
{
|
||||
DrawLock __;
|
||||
if(!StdFontSizeSet) {
|
||||
StdFontSizeSet = true;
|
||||
FontInfo fi = AStdFont.Info();
|
||||
FontInfo bfi = AStdFont().Bold().Info();
|
||||
StdFontSize = Size(fi.GetAveWidth(), bfi.GetHeight());
|
||||
}
|
||||
return StdFontSize;
|
||||
}
|
||||
|
||||
Font StdFont()
|
||||
{
|
||||
return Font(0, Draw::AStdFont.GetHeight());
|
||||
}
|
||||
|
||||
String Font::GetFaceName() const {
|
||||
if(IsNull()) return String();
|
||||
if(GetFace() == 0)
|
||||
return "STDFONT";
|
||||
return GetFaceName(GetFace());
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo() const {
|
||||
if(IsNull()) return 0;
|
||||
return GetFaceInfo(GetFace());
|
||||
}
|
||||
|
||||
Font& Font::FaceName(const String& name) {
|
||||
int n = FindFaceNameIndex(name);
|
||||
Face(n < 0 ? 0xffff : n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Font::Serialize(Stream& s) {
|
||||
int version = 1;
|
||||
s / version;
|
||||
if(version >= 1) {
|
||||
int f = GetFace();
|
||||
if(f > COURIER)
|
||||
f = -1;
|
||||
s / f;
|
||||
String name;
|
||||
if(f < 0) {
|
||||
name = GetFaceName();
|
||||
s % name;
|
||||
}
|
||||
if(s.IsLoading())
|
||||
if(f >= 0)
|
||||
Face(f);
|
||||
else
|
||||
FaceName(name);
|
||||
}
|
||||
else {
|
||||
String name = GetFaceName();
|
||||
s % name;
|
||||
if(s.IsLoading()) {
|
||||
FaceName(name);
|
||||
if(IsNull())
|
||||
Face(COURIER);
|
||||
}
|
||||
}
|
||||
s % flags % height % width;
|
||||
}
|
||||
|
||||
template<>
|
||||
String AsString(const Font& f) {
|
||||
if(IsNull(f)) return "<null>";
|
||||
String s = "<" + f.GetFaceName() + Format(":%d", f.GetHeight());
|
||||
if(f.IsBold())
|
||||
s += " Bold";
|
||||
if(f.IsItalic())
|
||||
s += " Italic";
|
||||
if(f.IsUnderline())
|
||||
s += " Underline";
|
||||
if(f.IsStrikeout())
|
||||
s += " Strikeout";
|
||||
return s + '>';
|
||||
}
|
||||
|
||||
int Draw::FontCacheMax = 32;
|
||||
int Draw::FontCached;
|
||||
|
||||
void Draw::FreeFonts() {
|
||||
FontCacheMax = FontCached = 0;
|
||||
sFini = false;
|
||||
for(int i = 0; i < FONTHASH; i++)
|
||||
GetFontHash(i)->DeleteList(HASH);
|
||||
}
|
||||
|
||||
FontInfo::FontInfo(const FontInfo& f)
|
||||
{
|
||||
Retain(f);
|
||||
}
|
||||
|
||||
FontInfo& FontInfo::operator=(const FontInfo& f)
|
||||
{
|
||||
Release();
|
||||
Retain(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//# Pretty ugly code....
|
||||
FontInfo::Data *Draw::GetFontHash(int i) {
|
||||
static byte buff[FONTHASH * sizeof(FontLink)];
|
||||
static FontLink *fonthash;
|
||||
if(!fonthash) {
|
||||
fonthash = (FontLink *)buff;
|
||||
for(int i = 0; i < FONTHASH; i++)
|
||||
fonthash[i].LinkSelfAll();
|
||||
}
|
||||
ASSERT(i >= 0 && i < FONTHASH);
|
||||
return (FontInfo::Data *)&fonthash[i];
|
||||
}
|
||||
|
||||
//# Pretty ugly code....
|
||||
FontInfo::Data *Draw::GetFontLru() {
|
||||
static byte buff[sizeof(FontLink)];
|
||||
static FontLink *fontlru;
|
||||
if(!fontlru)
|
||||
fontlru = new(buff) FontLink;
|
||||
return (FontInfo::Data *)fontlru;
|
||||
}
|
||||
|
||||
bool FontInfo::IsEqual(byte _charset, Font f, int angle, int device) const
|
||||
{
|
||||
return ptr && ptr->font == f && ptr->angle == angle && ptr->device == device &&
|
||||
charset == _charset;
|
||||
}
|
||||
|
||||
FontInfo::CharMetrics FontInfo::GetCM(int c) const
|
||||
{
|
||||
// CharMetrics mm;
|
||||
// ptr->GetMetrics(&mm, c, 1);
|
||||
// return mm;
|
||||
|
||||
if(c < 0) c = (byte)c;
|
||||
if(charset != CHARSET_UNICODE)
|
||||
c = ToUnicode(c, charset);
|
||||
ASSERT(c < 65536);
|
||||
if(c >= 65536) {
|
||||
CharMetrics h;
|
||||
h.width = h.lspc = h.rspc = 0;
|
||||
return h;
|
||||
}
|
||||
if(c < 2048)
|
||||
return GetPage(c >> 5)[c & 31];
|
||||
Mutex::Lock __(ptr->xmutex);
|
||||
Kinfo& ki = ptr->kinfo.At((c >> 10) - 2);
|
||||
if(!ki.flags) {
|
||||
ki.flags = new byte[128];
|
||||
memset(ki.flags, 0, 128);
|
||||
ptr->GetMetrics(&ki.std, c, 1);
|
||||
}
|
||||
int fi = (c >> 3) & 127;
|
||||
int fm = 1 << (c & 7);
|
||||
if(ki.flags[fi] & fm)
|
||||
return ki.std;
|
||||
int q = ptr->xx.Find(c);
|
||||
if(q >= 0)
|
||||
return ptr->xx[q];
|
||||
CharMetrics m;
|
||||
ptr->GetMetrics(&m, c, 1);
|
||||
if(m == ki.std)
|
||||
ki.flags[fi] |= fm;
|
||||
else
|
||||
ptr->xx.Add(c, m);
|
||||
return m;
|
||||
}
|
||||
|
||||
int FontInfo::GetWidth(int c) const {
|
||||
return GetCM(c).width;
|
||||
}
|
||||
|
||||
int FontInfo::GetLeftSpace(int c) const {
|
||||
return GetCM(c).lspc;
|
||||
}
|
||||
|
||||
int FontInfo::GetRightSpace(int c) const {
|
||||
return GetCM(c).rspc;
|
||||
}
|
||||
|
||||
void Draw::Release(FontInfo::Data *font) {
|
||||
DrawLock __;
|
||||
ASSERT(font->refcount > 0);
|
||||
LLOG("Release " << font->font << " count:" << font->count);
|
||||
if(--font->refcount == 0) {
|
||||
if(FontCacheMax == 0) {
|
||||
delete font;
|
||||
return;
|
||||
}
|
||||
FontInfo::Data *lru = GetFontLru();
|
||||
font->LinkAfter(lru, LRU);
|
||||
FontCached++;
|
||||
LLOG("Placed to cache " << font->font << " cached:" << FontCached);
|
||||
while(FontCached > FontCacheMax) {
|
||||
ASSERT(lru->GetPrev(LRU) != lru);
|
||||
FontCached--;
|
||||
LLOG("Deleting from cache " << lru->GetPrev(LRU)->font <<
|
||||
" cached: " << FontCached);
|
||||
delete lru->GetPrev(LRU);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FontInfo::Release()
|
||||
{
|
||||
if(ptr) Draw::Release(ptr);
|
||||
}
|
||||
|
||||
void FontInfo::Retain(const FontInfo& f)
|
||||
{
|
||||
DrawLock __;
|
||||
ptr = f.ptr;
|
||||
ptr->refcount++;
|
||||
charset = f.charset;
|
||||
}
|
||||
|
||||
|
||||
FontInfo Draw::GetFontInfoW(Font font) {
|
||||
DrawLock __;
|
||||
LTIMING("GetFontInfo");
|
||||
byte charset = CHARSET_UNICODE;
|
||||
if(lastFont.IsEqual(charset, font, 0, device))
|
||||
return lastFont;
|
||||
#ifdef PLATFORM_WIN32
|
||||
HDC hdc = GetHandle();
|
||||
FontInfo fi = Acquire(font, hdc ? hdc : ScreenHDC(), 0, device);
|
||||
#endif
|
||||
#ifdef PLATFORM_X11
|
||||
FontInfo fi = Acquire(font, 0, device);
|
||||
#endif
|
||||
fi.charset = charset;
|
||||
return fi;
|
||||
}
|
||||
|
||||
void Draw::SetFont(Font font, int angle) {
|
||||
DrawLock __;
|
||||
LLOG("Set font: " << font << " face: " << font.GetFaceName());
|
||||
if(lastFont && lastFont.IsEqual(CHARSET_UNICODE, font, angle, device))
|
||||
return;
|
||||
#ifdef PLATFORM_WIN32
|
||||
lastFont = Acquire(font, GetHandle(), angle, device);
|
||||
HFONT h = (HFONT) SelectObject(handle, lastFont.ptr->hfont);
|
||||
if(!orgFont) orgFont = h;
|
||||
#endif
|
||||
#ifdef PLATFORM_X11
|
||||
lastFont = Acquire(font, angle, device);
|
||||
#endif
|
||||
}
|
||||
|
||||
WString TextUnicode(const char *s, int n, byte cs, Font font)
|
||||
{
|
||||
if(n < 0)
|
||||
n = (int)strlen(s);
|
||||
if(font.GetFace() == Font::SYMBOL) {
|
||||
WStringBuffer b(n);
|
||||
wchar *t = b;
|
||||
while(n > 0) {
|
||||
*t++ = *s++;
|
||||
n--;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
else
|
||||
return ToUnicode(s, n, cs);
|
||||
}
|
||||
|
||||
FontInfo::CharMetrics *FontInfo::CreateMetricsPage(int page) const
|
||||
{
|
||||
DrawLock __;
|
||||
CharMetrics *cm;
|
||||
cm = new CharMetrics[32];
|
||||
ptr->GetMetrics(cm, page << 5, 32);
|
||||
if(page >= 8 && page < 12)
|
||||
ComposeMetrics(ptr->font, cm, page);
|
||||
return cm;
|
||||
}
|
||||
|
||||
FontInfo::CharMetrics *FontInfo::GetPage(int page) const
|
||||
{
|
||||
ASSERT(page >= 0 && page < 64);
|
||||
ONCELOCK_PTR(ptr->base[page], CreateMetricsPage(page));
|
||||
return ptr->base[page];
|
||||
}
|
||||
|
||||
void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
if(IsNull(ink)) return;
|
||||
if(n < 0)
|
||||
n = wstrlen(text);
|
||||
ComposeText(x, y, angle, text, font, ink, n, dx);
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
|
||||
void Draw::DrawText(int x, int y, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
DrawText(x, y, 0, text, font, ink, n, dx);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
void Draw::DrawText(int x, int y, int angle, const WString& text, Font font,
|
||||
Color ink, const int *dx)
|
||||
{
|
||||
DrawText(x, y, angle, ~text, font, ink, text.GetLength(), dx);
|
||||
}
|
||||
|
||||
void Draw::DrawText(int x, int y, const WString& text, Font font, Color ink, const int *dx)
|
||||
{
|
||||
DrawText(x, y, 0, text, font, ink, dx);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
void Draw::DrawText(int x, int y, int angle, const char *text, byte charset, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
DrawText(x, y, angle, TextUnicode(text, n, charset, font), font, ink, dx);
|
||||
}
|
||||
|
||||
void Draw::DrawText(int x, int y, const char *text, byte charset, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
DrawText(x, y, 0, text, charset, font, ink, n, dx);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
void Draw::DrawText(int x, int y, int angle, const char *text,
|
||||
Font font, Color ink, int n, const int *dx)
|
||||
{
|
||||
DrawText(x, y, angle, text, CHARSET_DEFAULT, font, ink, n, dx);
|
||||
}
|
||||
|
||||
void Draw::DrawText(int x, int y, const char *text, Font font,
|
||||
Color ink, int n, const int *dx)
|
||||
{
|
||||
DrawText(x, y, text, CHARSET_DEFAULT, font, ink, n, dx);
|
||||
}
|
||||
|
||||
// ---------------------------
|
||||
|
||||
void Draw::DrawText(int x, int y, int angle, const String& text, Font font,
|
||||
Color ink, const int *dx)
|
||||
{
|
||||
DrawText(x, y, angle, text, font, ink, text.GetLength(), dx);
|
||||
}
|
||||
|
||||
void Draw::DrawText(int x, int y, const String& text, Font font, Color ink, const int *dx)
|
||||
{
|
||||
WString h = TextUnicode(text, text.GetLength(), CHARSET_DEFAULT, font);
|
||||
DrawText(x, y, h, font, ink, h.GetLength(), dx);
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
|
||||
Size GetTextSize(const wchar *text, Font font, int n)
|
||||
{
|
||||
FontInfo fi = font.Info();
|
||||
if(n < 0)
|
||||
n = wstrlen(text);
|
||||
Size sz;
|
||||
sz.cx = 0;
|
||||
const wchar *wtext = (const wchar *)text;
|
||||
while(n > 0) {
|
||||
sz.cx += fi[*wtext++];
|
||||
n--;
|
||||
}
|
||||
sz.cy = fi.GetHeight();
|
||||
return sz;
|
||||
}
|
||||
|
||||
Size GetTextSize(const WString& text, Font font)
|
||||
{
|
||||
return GetTextSize(text, font, text.GetLength());
|
||||
}
|
||||
|
||||
Size GetTextSize(const char *text, byte charset, Font font, int n)
|
||||
{
|
||||
return GetTextSize(TextUnicode(text, n, charset, font), font);
|
||||
}
|
||||
|
||||
Size GetTextSize(const char *text, Font font, int n)
|
||||
{
|
||||
return GetTextSize(text, CHARSET_DEFAULT, font, n);
|
||||
}
|
||||
|
||||
Size GetTextSize(const String& text, Font font)
|
||||
{
|
||||
return GetTextSize(text, font, text.GetLength());
|
||||
}
|
||||
|
||||
Font Draw::GetStdFont()
|
||||
{
|
||||
return AStdFont;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
128
archive/olddraw/Draw/DrawTextUtil.cpp
Normal file
128
archive/olddraw/Draw/DrawTextUtil.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const char *ellipsis,
|
||||
Font font, Color ink, int n)
|
||||
{
|
||||
if(n < 0) n = wstrlen(text);
|
||||
FontInfo f = font.Info();
|
||||
const char *s;
|
||||
int dtl = 0;
|
||||
int el = 0;
|
||||
for(s = ellipsis; *s; s++) {
|
||||
dtl += f[(byte)*s];
|
||||
el++;
|
||||
}
|
||||
int l = 0;
|
||||
int i;
|
||||
for(i = 0; i < n; i++) {
|
||||
l += f[(byte) text[i]];
|
||||
if(l > cx) {
|
||||
while(l + dtl > cx && i > 0) {
|
||||
l -= f[(byte) text[i]];
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
w.DrawText(x, y, text, font, ink, i);
|
||||
if(i < n)
|
||||
w.DrawText(x + l, y, ellipsis, font, ink, el);
|
||||
}
|
||||
|
||||
void DrawTextEllipsis(Draw& w, int x, int y, int cx, const char *text, const char *ellipsis,
|
||||
Font font, Color ink, int n)
|
||||
{
|
||||
return DrawTextEllipsis(w, x, y, cx, WString(text), ellipsis, font, ink, n);
|
||||
}
|
||||
|
||||
Size GetTLTextSize(const wchar *text, Font font)
|
||||
{
|
||||
Size sz(0, 0);
|
||||
int cy = font.Info().GetHeight();
|
||||
const wchar *s = text;
|
||||
const wchar *t = s;
|
||||
for(;;) {
|
||||
if(*s == '\n' || *s == '\0') {
|
||||
int a = 0;
|
||||
const wchar *q = t;
|
||||
while(q < s) {
|
||||
while(q < s && *q < ' ') {
|
||||
if(*q == '\t')
|
||||
a = (a + 2 * cy) / (2 * cy) * (2 * cy);
|
||||
q++;
|
||||
}
|
||||
t = q;
|
||||
while(q < s && *q >= ' ')
|
||||
q++;
|
||||
a += GetTextSize(t, font, (int) (q - t)).cx;
|
||||
}
|
||||
t = s + 1;
|
||||
sz.cy += cy;
|
||||
sz.cx = max(sz.cx, a);
|
||||
}
|
||||
if(*s++ == '\0') break;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
int GetTLTextHeight(const wchar *s, Font font)
|
||||
{
|
||||
int cy = font.Info().GetHeight();
|
||||
int h = cy;
|
||||
while(*s) {
|
||||
if(*s == '\n')
|
||||
h += cy;
|
||||
s++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void DrawTLText(Draw& draw, int x, int y, int cx, const wchar *text,
|
||||
Font font, Color ink, int accesskey) {
|
||||
int cy = font.Info().GetHeight();
|
||||
const wchar *s = text;
|
||||
const wchar *t = s;
|
||||
int apos = HIWORD(accesskey);
|
||||
int akey = LOWORD(accesskey);
|
||||
for(;;) {
|
||||
if(*s == '\n' || *s == '\0') {
|
||||
int a = x;
|
||||
const wchar *q = t;
|
||||
const wchar *start = NULL;
|
||||
while(q < s) {
|
||||
while(q < s && *q < ' ') {
|
||||
if(*q == '\t')
|
||||
a = (a - x + 2 * cy) / (2 * cy) * (2 * cy) + x;
|
||||
q++;
|
||||
}
|
||||
t = q;
|
||||
bool ak = false;
|
||||
start = q;
|
||||
while(q < s && *q >= ' ') {
|
||||
if(akey && ToUpper(ToAscii(*q)) == akey && (apos == 0 || q - start + 1 == apos)) {
|
||||
ak = true;
|
||||
akey = 0;
|
||||
break;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
start = NULL;
|
||||
draw.DrawText(a, y, t, font, ink, (int)(q - t));
|
||||
a += GetTextSize(t, font, (int)(q - t)).cx;
|
||||
if(ak) {
|
||||
draw.DrawText(a, y, q, font().Underline(), ink, 1);
|
||||
a += GetTextSize(q, font().Underline(), 1).cx;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
t = s + 1;
|
||||
y += cy;
|
||||
}
|
||||
if(*s++ == '\0') break;
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
433
archive/olddraw/Draw/DrawTextWin32.cpp
Normal file
433
archive/olddraw/Draw/DrawTextWin32.cpp
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x)
|
||||
|
||||
struct FontFaceInfo : Moveable<FontFaceInfo> {
|
||||
String name;
|
||||
dword info;
|
||||
|
||||
FontFaceInfo() { info = 0; }
|
||||
};
|
||||
|
||||
static VectorMap<String, FontFaceInfo>& sFontFace()
|
||||
{
|
||||
static VectorMap<String, FontFaceInfo> s;
|
||||
return s;
|
||||
}
|
||||
|
||||
int Font::GetFaceCount()
|
||||
{
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
return sFontFace().GetCount();
|
||||
}
|
||||
|
||||
String Font::GetFaceName(int index) {
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
return index >= 0 && index < sFontFace().GetCount() ? sFontFace()[index].name
|
||||
: Null;
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo(int index) {
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
return index >= 0 && index < sFontFace().GetCount() ? sFontFace()[index].info
|
||||
: 0;
|
||||
}
|
||||
|
||||
void Win32_GetGlyphIndices(HDC hdc, LPCWSTR s, int n, LPWORD r, DWORD flag)
|
||||
{
|
||||
typedef DWORD (WINAPI *GGIW)(HDC, LPCWSTR, int, LPWORD, DWORD);
|
||||
static GGIW fn;
|
||||
ONCELOCK
|
||||
if(HMODULE hDLL = LoadLibrary("gdi32"))
|
||||
fn = (GGIW) GetProcAddress(hDLL, "GetGlyphIndicesW");
|
||||
if(fn)
|
||||
fn(hdc, s, n, r, flag);
|
||||
else
|
||||
memset(r, 0, n * sizeof(WORD));
|
||||
}
|
||||
|
||||
int CALLBACK Draw::AddFace(const LOGFONT *logfont, const TEXTMETRIC *, dword type, LPARAM param)
|
||||
{
|
||||
#ifdef PLATFORM_WINCE
|
||||
const wchar *facename = (const wchar *)param;
|
||||
if(facename && _wcsicmp(logfont->lfFaceName, facename))
|
||||
return 1;
|
||||
#else
|
||||
const char *facename = (const char *)param;
|
||||
if(facename && stricmp(logfont->lfFaceName, facename))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
dword typ = 0;
|
||||
if((logfont->lfPitchAndFamily & 3) == FIXED_PITCH)
|
||||
typ |= Font::FIXEDPITCH;
|
||||
if(type & TRUETYPE_FONTTYPE)
|
||||
typ |= Font::SCALEABLE;
|
||||
if(logfont->lfCharSet == SYMBOL_CHARSET)
|
||||
typ |= Font::SYMBOLTYPE;
|
||||
else
|
||||
if(logfont->lfCharSet != 0)
|
||||
typ |= Font::LOCAL;
|
||||
#ifndef PLATFORM_WINCE
|
||||
{
|
||||
HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
|
||||
HFONT hfnt = (HFONT) CreateFontIndirect(logfont);
|
||||
HFONT o = (HFONT) SelectObject(hdc, hfnt);
|
||||
wchar wch[128];
|
||||
WORD pos[128];
|
||||
for(int i = 0; i < 128; i++)
|
||||
wch[i] = i + 256;
|
||||
Win32_GetGlyphIndices(hdc, (LPCWSTR) wch, 128, pos, 1);
|
||||
SelectObject(hdc, o);
|
||||
DeleteObject(hfnt);
|
||||
DeleteDC(hdc);
|
||||
int n = 0;
|
||||
for(int i = 0; i < 128; i++)
|
||||
if(pos[i] == 0xffff)
|
||||
n++;
|
||||
if(n > 10)
|
||||
typ |= Font::COMPOSED;
|
||||
}
|
||||
#endif
|
||||
#ifdef PLATFORM_WINCE
|
||||
if(facename) {
|
||||
FontFaceInfo& f = sFontFace().Add(WString(logfont->lfFaceName).ToString());
|
||||
f.name = WString(facename).ToString();
|
||||
return 0;
|
||||
}
|
||||
FontFaceInfo& f = sFontFace().Add(WString(logfont->lfFaceName).ToString());
|
||||
f.name = FromSystemCharset(logfont->lfFaceName);
|
||||
#else
|
||||
if(facename) {
|
||||
FontFaceInfo& f = sFontFace().Add(logfont->lfFaceName);
|
||||
f.name = facename;
|
||||
f.info = typ;
|
||||
return 0;
|
||||
}
|
||||
FontFaceInfo& f = sFontFace().Add(logfont->lfFaceName);
|
||||
f.name = FromSystemCharset(logfont->lfFaceName);
|
||||
#endif
|
||||
f.info |= typ;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Draw::EnumFace(HDC hdc, const char *face)
|
||||
{
|
||||
#ifdef PLATFORM_WINCE
|
||||
return EnumFontFamilies(hdc, ToSystemCharset(face), AddFace, (LPARAM)~ToSystemCharset(face));
|
||||
#else
|
||||
return EnumFontFamilies(hdc, face, AddFace, (LPARAM)face);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Draw::ForceFace(HDC hdc, const char *face, const char *aface)
|
||||
{
|
||||
if(!aface)
|
||||
aface = "Arial";
|
||||
if(EnumFace(hdc, face) && (aface == NULL || EnumFace(hdc, aface)))
|
||||
Panic("Missing font " + String(face));
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINCE
|
||||
const char *Draw::FontScreenSans = "Tahoma"; //TODO!
|
||||
const char *Draw::FontScreenSerif = "Tahoma";
|
||||
const char *Draw::FontScreenFixed = "Courier New";
|
||||
const char *Draw::FontRoman = "Tahoma" ;
|
||||
const char *Draw::FontArial = "Tahoma";
|
||||
const char *Draw::FontCourier = "Tahoma";
|
||||
const char *Draw::FontSymbol = "Tahoma";
|
||||
const char *Draw::FontWingdings = "Tahoma";
|
||||
const char *Draw::FontTahoma = "Tahoma";
|
||||
#else
|
||||
const char *Draw::FontScreenSans = "Arial";
|
||||
const char *Draw::FontScreenSerif = "Times New Roman";
|
||||
const char *Draw::FontScreenFixed = "Courier New";
|
||||
const char *Draw::FontRoman = "Times New Roman" ;
|
||||
const char *Draw::FontArial = "Arial";
|
||||
const char *Draw::FontCourier = "Courier New";
|
||||
const char *Draw::FontSymbol = "Symbol";
|
||||
const char *Draw::FontWingdings = "WingDings";
|
||||
const char *Draw::FontTahoma = "Tahoma";
|
||||
#endif
|
||||
|
||||
void Draw::InitPlatformFonts() {
|
||||
#ifdef PLATFORM_WINCE
|
||||
HDC hdc = CreateDC(NULL, NULL, NULL, NULL);
|
||||
#else
|
||||
HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
|
||||
#endif
|
||||
ForceFace(hdc, FontScreenSans, NULL);
|
||||
ForceFace(hdc, FontScreenSerif, FontScreenSans);
|
||||
ForceFace(hdc, FontScreenSans, FontScreenSans);
|
||||
ForceFace(hdc, FontScreenFixed, FontScreenSans);
|
||||
ForceFace(hdc, FontRoman, FontScreenSans);
|
||||
ForceFace(hdc, FontArial, FontScreenSans);
|
||||
ForceFace(hdc, FontCourier, FontScreenSans);
|
||||
ForceFace(hdc, FontSymbol, FontScreenSans);
|
||||
ForceFace(hdc, FontWingdings, FontArial);
|
||||
ForceFace(hdc, FontTahoma, FontArial);
|
||||
EnumFace(hdc, NULL);
|
||||
DeleteDC(hdc);
|
||||
#ifdef PLATFORM_WINCE
|
||||
SetStdFont(Arial(10));
|
||||
#else
|
||||
NONCLIENTMETRICS ncm;
|
||||
ncm.cbSize = sizeof(ncm);
|
||||
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
|
||||
SetStdFont(Font(Font::FindFaceNameIndex(ncm.lfMenuFont.lfFaceName),
|
||||
abs((int)ncm.lfMenuFont.lfHeight)));
|
||||
#endif
|
||||
}
|
||||
|
||||
FontInfo::Data::Data()
|
||||
{
|
||||
refcount = 1;
|
||||
hfont = NULL;
|
||||
for(int i = 0; i < 64; i++)
|
||||
base[i] = NULL;
|
||||
}
|
||||
|
||||
FontInfo::Data::~Data()
|
||||
{
|
||||
DrawLock __;
|
||||
if(hfont)
|
||||
DeleteObject(hfont);
|
||||
for(int i = 0; i < 64; i++)
|
||||
if(base[i]) delete[] base[i];
|
||||
}
|
||||
|
||||
bool FontInfo::Data::HasChar(int ch) const
|
||||
{
|
||||
HDC hdc = ScreenHDC();
|
||||
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
|
||||
WCHAR c = ch;
|
||||
WORD pos;
|
||||
Win32_GetGlyphIndices(hdc, &c, 1, &pos, 1);
|
||||
::SelectObject(hdc, ohfont);
|
||||
return pos != 0xffff;
|
||||
}
|
||||
|
||||
int sGetCW(HDC hdc, wchar *h, int n)
|
||||
{
|
||||
SIZE sz;
|
||||
return GetTextExtentPoint32W(hdc, h, n, &sz) ? sz.cx : 0;
|
||||
}
|
||||
|
||||
void FontInfo::Data::GetMetrics(CharMetrics *t, int from, int count)
|
||||
{
|
||||
DrawLock __;
|
||||
HDC hdc = ScreenHDC();
|
||||
HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont);
|
||||
if(from >= 8192) {
|
||||
wchar h[3];
|
||||
h[0] = 'x';
|
||||
h[1] = 'x';
|
||||
h[2] = 'x';
|
||||
int w0 = sGetCW(hdc, h, 2);
|
||||
for(int i = 0; i < count; i++) {
|
||||
h[1] = from + i;
|
||||
t[i].width = sGetCW(hdc, h, 3) - w0;
|
||||
t[i].lspc = t[i].rspc = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool abca = false, abcw = false;
|
||||
Buffer<ABC> abc(count);
|
||||
#ifdef PLATFORM_WINCE
|
||||
if(scaleable)
|
||||
abcw = ::GetCharABCWidths(hdc, from, from + count - 1, abc);
|
||||
#else
|
||||
if(scaleable && !(abcw = ::GetCharABCWidthsW(hdc, from, from + count - 1, abc)))
|
||||
abca = ::GetCharABCWidthsA(hdc, from, from + count - 1, abc);
|
||||
#endif
|
||||
if(abcw)
|
||||
{
|
||||
for(ABC *s = abc, *lim = abc + count; s < lim; s++, t++)
|
||||
{
|
||||
t->width = s->abcA + s->abcB + s->abcC;
|
||||
t->lspc = s->abcA;
|
||||
t->rspc = s->abcC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer<int> wb(count);
|
||||
#ifdef PLATFORM_WINCE
|
||||
::GetCharWidth32(hdc, from, from + count - 1, wb);
|
||||
#else
|
||||
::GetCharWidthW(hdc, from, from + count - 1, wb);
|
||||
#endif
|
||||
for(int *s = wb, *lim = wb + count; s < lim; s++, t++)
|
||||
{
|
||||
t->width = *s - overhang;
|
||||
if(abca)
|
||||
{
|
||||
ABC aa = abc[(byte)ToAscii(from++)];
|
||||
t->lspc = aa.abcA;
|
||||
t->rspc = aa.abcC;
|
||||
}
|
||||
else
|
||||
t->lspc = t->rspc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
::SelectObject(hdc, ohfont);
|
||||
}
|
||||
|
||||
FontInfo Draw::Acquire(Font font, HDC hdc, int angle, int device)
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsNull(font))
|
||||
font = StdFont();
|
||||
if(font.GetFace() == 0)
|
||||
font.Face(AStdFont.GetFace());
|
||||
if(font.GetHeight() == 0)
|
||||
font.Height(AStdFont.GetHeight());
|
||||
// if(font.GetFace() >= sFontFace().GetCount())
|
||||
// font.SetFace(Font::ARIAL);
|
||||
FontInfo::Data *f, *fh;
|
||||
f = fh = GetFontHash((font.GetHashValue() ^ angle ^ (device << 9)) % FONTHASH);
|
||||
LLOG("Acquire " << font);
|
||||
for(;;) {
|
||||
f = f->GetNext(HASH);
|
||||
if(f == fh) break;
|
||||
if(f->font == font && f->angle == angle && f->device == device)
|
||||
{
|
||||
LLOG("Reusing " << f->font << " count:" << f->count);
|
||||
if(f->InList(LRU)) {
|
||||
f->Unlink(LRU);
|
||||
FontCached--;
|
||||
LLOG("Removing from cache " << f->font << " count:" << f->count <<
|
||||
" cached:" << FontCached);
|
||||
}
|
||||
f->refcount++;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
LLOG("New " << font);
|
||||
LTIMING("Acquire New");
|
||||
f = fh->InsertNext(HASH);
|
||||
f->font = font;
|
||||
f->angle = angle;
|
||||
f->device = device;
|
||||
|
||||
byte chrset;
|
||||
if((sFontFace()[font.GetFace()].info & Font::SCALEABLE) == 0)
|
||||
chrset = DEFAULT_CHARSET;
|
||||
else
|
||||
if(sFontFace()[font.GetFace()].info & Font::SYMBOLTYPE)
|
||||
chrset = SYMBOL_CHARSET;
|
||||
else
|
||||
chrset = DEFAULT_CHARSET;
|
||||
#ifdef PLATFORM_WINCE
|
||||
LOGFONT lfnt;
|
||||
Zero(lfnt);
|
||||
lfnt.lfHeight = font.GetHeight() ? -abs(font.GetHeight()) : -12;
|
||||
lfnt.lfWeight = font.IsBold() ? FW_BOLD : FW_NORMAL;
|
||||
lfnt.lfItalic = font.IsItalic();
|
||||
lfnt.lfUnderline = font.IsUnderline();
|
||||
lfnt.lfStrikeOut = font.IsStrikeout();
|
||||
wcscpy(lfnt.lfFaceName, ToSystemCharset(font.GetFaceName()));
|
||||
f->hfont = CreateFontIndirect(&lfnt);
|
||||
#else
|
||||
f->hfont = CreateFont(font.GetHeight() ? -abs(font.GetHeight()) : -12,
|
||||
font.GetWidth(), angle, angle, font.IsBold() ? FW_BOLD : FW_NORMAL,
|
||||
font.IsItalic(), font.IsUnderline(), font.IsStrikeout(),
|
||||
chrset,
|
||||
font.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS,
|
||||
font.IsNonAntiAliased() ? NONANTIALIASED_QUALITY
|
||||
: DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH|FF_DONTCARE,
|
||||
sFontFace().GetKey(font.GetFace()));
|
||||
#endif
|
||||
ASSERT(f->hfont);
|
||||
TEXTMETRIC tm;
|
||||
HFONT hfont = (HFONT) ::SelectObject(hdc, f->hfont);
|
||||
::GetTextMetrics(hdc, &tm);
|
||||
f->ascent = tm.tmAscent;
|
||||
f->descent = tm.tmDescent;
|
||||
f->external = tm.tmExternalLeading;
|
||||
f->internal = tm.tmInternalLeading;
|
||||
f->height = f->ascent + f->descent;
|
||||
f->lineheight = f->height + f->external;
|
||||
f->overhang = tm.tmOverhang;
|
||||
f->avewidth = tm.tmAveCharWidth;
|
||||
f->maxwidth = tm.tmMaxCharWidth;
|
||||
f->firstchar = tm.tmFirstChar;
|
||||
f->charcount = tm.tmLastChar - tm.tmFirstChar + 1;
|
||||
f->default_char = tm.tmDefaultChar;
|
||||
f->fixedpitch = (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0;
|
||||
f->scaleable = tm.tmPitchAndFamily & TMPF_TRUETYPE;
|
||||
f->kerning.Clear();
|
||||
if(f->scaleable) {
|
||||
ABC abc;
|
||||
GetCharABCWidths(hdc, 'o', 'o', &abc);
|
||||
f->spacebefore = abc.abcA;
|
||||
f->spaceafter = abc.abcC;
|
||||
}
|
||||
else
|
||||
f->spacebefore = f->spaceafter = 0;
|
||||
#ifndef PLATFORM_WINCE
|
||||
int n = ::GetKerningPairs(hdc, 0, NULL);
|
||||
if(n) {
|
||||
Buffer<KERNINGPAIR> kp(n);
|
||||
::GetKerningPairs(hdc, n, kp);
|
||||
const KERNINGPAIR *p = kp;
|
||||
while(n--) {
|
||||
f->kerning.Add(MAKELONG(p->wFirst, p->wSecond), p->iKernAmount);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
::SelectObject(hdc, hfont);
|
||||
f->offset = Size(0, f->ascent);
|
||||
if(angle) {
|
||||
FontInfo font0 = Acquire(font, hdc, 0, device);
|
||||
double sina, cosa;
|
||||
SinCos(angle, sina, cosa);
|
||||
f->offset.cx = fround(font0.GetAscent() * sina);
|
||||
f->offset.cy = fround(font0.GetAscent() * cosa);
|
||||
}
|
||||
return FontInfo(f);
|
||||
}
|
||||
|
||||
void Draw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink,
|
||||
int n, const int *dx) {
|
||||
while(n > 30000) {
|
||||
DrawTextOp(x, y, angle, text, font, ink, 30000, dx);
|
||||
if(dx) {
|
||||
for(int i = 0; i < 30000; i++)
|
||||
x += *dx++;
|
||||
}
|
||||
else
|
||||
x += GetTextSize(text, font, 30000).cx;
|
||||
n -= 30000;
|
||||
text += 30000;
|
||||
}
|
||||
DrawLock __;
|
||||
COLORREF cr = GetColor(ink);
|
||||
if(cr != lastTextColor) {
|
||||
LLOG("Setting text color: " << ink);
|
||||
::SetTextColor(handle, lastTextColor = cr);
|
||||
}
|
||||
if(angle) {
|
||||
SetFont(font, angle);
|
||||
::ExtTextOutW(handle, x + lastFont.ptr->offset.cx, y + lastFont.ptr->offset.cy,
|
||||
0, NULL, (const WCHAR *)text, n, dx);
|
||||
}
|
||||
else {
|
||||
SetFont(font);
|
||||
::ExtTextOutW(handle, x, y + lastFont.GetAscent(), 0, NULL, (const WCHAR *)text,
|
||||
n, dx);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
376
archive/olddraw/Draw/DrawTextXft.cpp
Normal file
376
archive/olddraw/Draw/DrawTextXft.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_XFT
|
||||
|
||||
#define LLOG(x) //LOG(x)
|
||||
#define LTIMING(x) //RTIMING(x)
|
||||
|
||||
struct XFTFontFaceInfo {
|
||||
String name;
|
||||
bool fixed:1;
|
||||
bool scaleable:1;
|
||||
bool compose:1;
|
||||
|
||||
XFTFontFaceInfo()
|
||||
{
|
||||
fixed = scaleable = false;
|
||||
}
|
||||
};
|
||||
|
||||
ArrayMap<String, XFTFontFaceInfo>& XFTFontFace()
|
||||
{
|
||||
static ArrayMap<String, XFTFontFaceInfo> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
FontInfo::Data::Data()
|
||||
{
|
||||
refcount = 1;
|
||||
for(int i = 0; i < 64; i++)
|
||||
base[i] = NULL;
|
||||
xftfont = NULL;
|
||||
}
|
||||
|
||||
FontInfo::Data::~Data()
|
||||
{
|
||||
DrawLock __;
|
||||
if(xftfont0 && xftfont0 != xftfont)
|
||||
XftFontClose(Xdisplay, xftfont0);
|
||||
if(xftfont)
|
||||
XftFontClose(Xdisplay, xftfont);
|
||||
for(int i = 0; i < 64; i++)
|
||||
if(base[i]) delete[] base[i];
|
||||
}
|
||||
|
||||
void FontInfo::Data::GetMetrics(CharMetrics *t, int from, int count)
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("GetMetrics");
|
||||
LLOG("GetMetrics " << font << " " << from << ", " << count);
|
||||
if(xftfont) {
|
||||
for(int i = 0; i < count; i++) {
|
||||
LTIMING("XftTextExtents16");
|
||||
wchar h = from + i;
|
||||
XGlyphInfo info;
|
||||
XftTextExtents16(Xdisplay, xftfont0, &h, 1, &info);
|
||||
t[i].width = info.xOff;
|
||||
t[i].lspc = -info.x;
|
||||
t[i].rspc = info.xOff - info.width + info.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *basic_fonts[] = {
|
||||
"sans-serif",
|
||||
"serif",
|
||||
"sans-serif",
|
||||
"monospace",
|
||||
"serif",
|
||||
"sans-serif",
|
||||
"monospace",
|
||||
};
|
||||
|
||||
static int sCheckComposed(const char *face)
|
||||
{
|
||||
XftFont *xftfont = XftFontOpen(Xdisplay, Xscreenno,
|
||||
XFT_FAMILY, XftTypeString, (char *)face,
|
||||
XFT_PIXEL_SIZE, XftTypeInteger, 20,
|
||||
(void *)0);
|
||||
if(xftfont == NULL )
|
||||
return -1;
|
||||
int n = 0;
|
||||
for(int c = 0; c < 128; c++)
|
||||
if(!XftCharExists(Xdisplay, xftfont, c + 256))
|
||||
n++;
|
||||
XftFontClose(Xdisplay, xftfont);
|
||||
return n > 10;
|
||||
}
|
||||
|
||||
bool FontInfo::Data::HasChar(int ch) const
|
||||
{
|
||||
return XftCharExists(Xdisplay, xftfont, ch);
|
||||
}
|
||||
|
||||
void Draw::InitPlatformFonts()
|
||||
{
|
||||
for(int i = 0; i < __countof(basic_fonts); i++) {
|
||||
XFTFontFaceInfo& f = XFTFontFace().Add(basic_fonts[i]);
|
||||
f.name = basic_fonts[i];
|
||||
f.scaleable = true;
|
||||
f.fixed = i == 3 || i == 6;
|
||||
f.compose = sCheckComposed(basic_fonts[i]);
|
||||
}
|
||||
FcFontSet *fs = XftListFonts(Xdisplay, Xscreenno, (void *)0, XFT_FAMILY, XFT_SPACING,
|
||||
XFT_SCALABLE, (void *)0);
|
||||
for(int i = 0; i < fs->nfont; i++) {
|
||||
FcChar8 *family = NULL;
|
||||
if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == 0 && family) {
|
||||
int comp = sCheckComposed((char *)family);
|
||||
if(comp >= 0) {
|
||||
XFTFontFaceInfo& f = XFTFontFace().GetAdd((char *)family);
|
||||
int spacing;
|
||||
if(FcPatternGetInteger(fs->fonts[i], FC_SPACING, 0, &spacing) == 0 && spacing == XFT_MONO)
|
||||
f.fixed = true;
|
||||
FcBool scaleable;
|
||||
if(FcPatternGetBool(fs->fonts[i], FC_SCALABLE, 0, &scaleable) == 0 && scaleable)
|
||||
f.scaleable = true;
|
||||
f.compose = comp;
|
||||
}
|
||||
}
|
||||
}
|
||||
FcFontSetDestroy(fs);
|
||||
}
|
||||
|
||||
int Font::GetFaceCount()
|
||||
{
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
return XFTFontFace().GetCount();
|
||||
}
|
||||
|
||||
String Font::GetFaceName(int index)
|
||||
{
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
return index >= 0 && index < XFTFontFace().GetCount() ? XFTFontFace().GetKey(index)
|
||||
: Null;
|
||||
}
|
||||
|
||||
dword Font::GetFaceInfo(int index) {
|
||||
if(!Draw::sFini) Draw::InitFonts();
|
||||
dword w = 0;
|
||||
if(index >= 0 && index < XFTFontFace().GetCount()) {
|
||||
XFTFontFaceInfo& fi = XFTFontFace()[index];
|
||||
if(fi.fixed)
|
||||
w |= FIXEDPITCH;
|
||||
if(fi.scaleable)
|
||||
w |= SCALEABLE;
|
||||
if(fi.compose)
|
||||
w |= COMPOSED;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
int gtk_antialias = -1;
|
||||
int gtk_hinting = -1;
|
||||
String gtk_hintstyle;
|
||||
String gtk_rgba;
|
||||
|
||||
XftFont *Draw::CreateXftFont(Font font, int angle)
|
||||
{
|
||||
LTIMING("CreateXftFont");
|
||||
XftFont *xftfont;
|
||||
double sina, cosa;
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = 10;
|
||||
int i = font.GetFace();
|
||||
if(i < 0 || i >= XFTFontFace().GetCount())
|
||||
i = 0;
|
||||
const char *face = i < 7 ? basic_fonts[i] : ~XFTFontFace().GetKey(i);
|
||||
FcPattern *p = FcPatternCreate();
|
||||
FcPatternAddString(p, FC_FAMILY, (FcChar8*)face);
|
||||
FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? 110 : 0);
|
||||
FcPatternAddInteger(p, FC_PIXEL_SIZE, hg);
|
||||
FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? 200 : 100);
|
||||
FcPatternAddBool(p, FC_MINSPACE, 1);
|
||||
if(angle) {
|
||||
FcMatrix mx;
|
||||
SinCos(angle, sina, cosa);
|
||||
mx.xx = cosa;
|
||||
mx.xy = -sina;
|
||||
mx.yx = sina;
|
||||
mx.yy = cosa;
|
||||
FcPatternAddMatrix(p, FC_MATRIX, &mx);
|
||||
}
|
||||
FcResult result;
|
||||
FcPattern *m = XftFontMatch(Xdisplay, Xscreenno, p, &result);
|
||||
if(font.IsNonAntiAliased() || gtk_antialias >= 0) {
|
||||
FcPatternDel(m, FC_ANTIALIAS);
|
||||
FcPatternAddBool(m, FC_ANTIALIAS,
|
||||
font.IsNonAntiAliased() ? FcFalse : gtk_antialias ? FcTrue : FcFalse);
|
||||
}
|
||||
if(gtk_hinting >= 0) {
|
||||
FcPatternDel(m, FC_HINTING);
|
||||
FcPatternAddBool(m, FC_HINTING, gtk_hinting);
|
||||
}
|
||||
const char *hs[] = { "hintnone", "hintslight", "hintmedium", "hintfull" };
|
||||
for(int i = 0; i < 4; i++)
|
||||
if(gtk_hintstyle == hs[i]) {
|
||||
FcPatternDel(m, FC_HINT_STYLE);
|
||||
FcPatternAddInteger(m, FC_HINT_STYLE, i);
|
||||
}
|
||||
const char *rgba[] = { "_", "rgb", "bgr", "vrgb", "vbgr" };
|
||||
for(int i = 0; i < __countof(rgba); i++)
|
||||
if(gtk_rgba == rgba[i]) {
|
||||
FcPatternDel(m, FC_RGBA);
|
||||
FcPatternAddInteger(m, FC_RGBA, i);
|
||||
}
|
||||
xftfont = XftFontOpenPattern(Xdisplay, m);
|
||||
FcPatternDestroy(p);
|
||||
return xftfont;
|
||||
}
|
||||
|
||||
FontInfo Draw::Acquire(Font font, int angle, int device)
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("Acquire");
|
||||
if(IsNull(font))
|
||||
font = StdFont();
|
||||
if(font.GetFace() == 0)
|
||||
font.Face(AStdFont.GetFace());
|
||||
if(font.GetHeight() == 0)
|
||||
font.Height(AStdFont.GetHeight());
|
||||
FontInfo::Data *f, *fh;
|
||||
f = fh = GetFontHash((font.GetHashValue() ^ angle ^ (device << 9)) % (int)FONTHASH);
|
||||
LLOG("Acquire " << font << " device: " << device);
|
||||
for(;;) {
|
||||
f = f->GetNext(HASH);
|
||||
if(f == fh) break;
|
||||
if(f->font == font && f->angle == angle && f->device == device)
|
||||
{
|
||||
LLOG("Reusing " << f->font);
|
||||
if(f->InList(LRU)) {
|
||||
f->Unlink(LRU);
|
||||
FontCached--;
|
||||
LLOG("Removing from cache " << f->font << " cached:" << FontCached);
|
||||
}
|
||||
f->refcount++;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
LLOG("New " << font);
|
||||
LTIMING("Acquire New");
|
||||
f = fh->InsertNext(HASH);
|
||||
f->font = font;
|
||||
f->angle = angle;
|
||||
f->device = device;
|
||||
int hg = abs(font.GetHeight());
|
||||
if(hg == 0) hg = 10;
|
||||
f->xftfont0 = f->xftfont = CreateXftFont(font, angle);
|
||||
if(angle)
|
||||
f->xftfont0 = CreateXftFont(font, 0);
|
||||
f->filename = NULL;
|
||||
f->ascent = (int16)f->xftfont0->ascent;
|
||||
f->descent = (int16)f->xftfont0->descent;
|
||||
f->height = f->ascent + f->descent;
|
||||
f->lineheight = (int16)f->xftfont0->height;
|
||||
f->external = 0;
|
||||
f->internal = 0;
|
||||
f->overhang = 0;
|
||||
f->maxwidth = (int16)f->xftfont0->max_advance_width;
|
||||
f->avewidth = f->maxwidth;
|
||||
f->default_char = '?';
|
||||
f->fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH;
|
||||
f->underline_thickness = max(hg / 20, 1);
|
||||
f->underline_position = max(hg / 15, int(f->descent > 0));
|
||||
if(angle) {
|
||||
SinCos(angle, f->sina, f->cosa);
|
||||
f->offset.cx = fround(f->ascent * f->sina);
|
||||
f->offset.cy = fround(f->ascent * f->cosa);
|
||||
}
|
||||
FontInfo fi = FontInfo(f);
|
||||
fi.GetPage(0);
|
||||
return fi;
|
||||
}
|
||||
|
||||
String FontInfo::GetFileName() const
|
||||
{
|
||||
if(IsNull(ptr->filename)) {
|
||||
char *fn = NULL;
|
||||
XftPatternGetString(ptr->xftfont->pattern, XFT_FILE, 0, &fn);
|
||||
if(fn)
|
||||
ptr->filename = fn;
|
||||
}
|
||||
return ptr->filename;
|
||||
}
|
||||
|
||||
void Draw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font,
|
||||
Color ink, int n, const int *dx) {
|
||||
LTIMING("DrawText");
|
||||
LLOG("DrawText " << ToUtf8(WString(text, n)) << " color:" << ink << " font:" << font);
|
||||
//TODO - X11 seems to crash when displaying too long strings (?)
|
||||
int ox = x + actual_offset.x;
|
||||
int oy = y + actual_offset.y;
|
||||
SetForeground(ink);
|
||||
SetFont(font, angle);
|
||||
const FontInfo::Data *fd = lastFont.ptr;
|
||||
XftColor c;
|
||||
c.color.red = ink.GetR() << 8;
|
||||
c.color.green = ink.GetG() << 8;
|
||||
c.color.blue = ink.GetB() << 8;
|
||||
c.color.alpha = 0xffff;
|
||||
c.pixel = GetXPixel(ink.GetR(), ink.GetG(), ink.GetB());
|
||||
if(angle) {
|
||||
int xpos = 0;
|
||||
for(int i = 0; i < n; i++) {
|
||||
wchar h = text[i];
|
||||
XftDrawString16(xftdraw, &c, fd->xftfont,
|
||||
int(ox + xpos * fd->cosa + fd->offset.cx),
|
||||
int(oy - xpos * fd->sina + fd->offset.cy),
|
||||
(FcChar16 *)&h, 1);
|
||||
xpos += dx ? dx[i] : lastFont[text[i]];
|
||||
}
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
x += fd->offset.cx;
|
||||
y += fd->offset.cy;
|
||||
if(font.IsUnderline())
|
||||
DrawLine(
|
||||
int(x + fd->underline_position * fd->sina),
|
||||
int(y + fd->underline_position * fd->cosa),
|
||||
int(x + xpos * fd->cosa + fd->underline_position * fd->sina),
|
||||
int(y - xpos * fd->sina + fd->underline_position * fd->cosa),
|
||||
fd->underline_thickness,
|
||||
ink
|
||||
);
|
||||
if(font.IsStrikeout()) {
|
||||
int p = 2 * fd->ascent / 3;
|
||||
DrawLine(
|
||||
int(x + p * fd->sina),
|
||||
int(y + p * fd->cosa),
|
||||
int(x + xpos * fd->cosa + p * fd->sina),
|
||||
int(y - xpos * fd->sina + p * fd->cosa),
|
||||
fd->underline_thickness,
|
||||
ink
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(dx) {
|
||||
int xpos = ox;
|
||||
Buffer<XftCharSpec> ch(n);
|
||||
for(int i = 0; i < n; i++) {
|
||||
ch[i].ucs4 = text[i];
|
||||
ch[i].x = xpos;
|
||||
ch[i].y = oy + fd->ascent;
|
||||
xpos += dx[i];
|
||||
}
|
||||
XftDrawCharSpec(xftdraw, &c, fd->xftfont, ch, n);
|
||||
}
|
||||
else
|
||||
XftDrawString16(xftdraw, &c, fd->xftfont, ox, oy + fd->ascent,
|
||||
(FcChar16 *)text, n);
|
||||
LLOG("XftColor: r=" << c.color.red << ", g=" << c.color.green << ", b=" << c.color.blue
|
||||
<< ", alpha=" << c.color.alpha << ", pixel=" << FormatIntHex(c.pixel));
|
||||
if(font.IsUnderline() || font.IsStrikeout()) {
|
||||
int cx;
|
||||
if(dx && n > 0) {
|
||||
cx = 0;
|
||||
Sum(cx, dx, dx + n - 1);
|
||||
cx += lastFont[text[n - 1]];
|
||||
}
|
||||
else
|
||||
cx = GetTextSize(text, font, n).cx;
|
||||
if(font.IsUnderline())
|
||||
DrawRect(x, y + lastFont.GetAscent() + lastFont.ptr->underline_position,
|
||||
cx, lastFont.ptr->underline_thickness, ink);
|
||||
if(font.IsStrikeout())
|
||||
DrawRect(x, y + 2 * lastFont.GetAscent() / 3,
|
||||
cx, lastFont.ptr->underline_thickness, ink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
636
archive/olddraw/Draw/DrawUtil.cpp
Normal file
636
archive/olddraw/Draw/DrawUtil.cpp
Normal file
|
|
@ -0,0 +1,636 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // TIMING(x)
|
||||
|
||||
void AddNotEmpty(Vector<Rect>& result, int left, int right, int top, int bottom)
|
||||
{
|
||||
if(left < right && top < bottom)
|
||||
result.Add(Rect(left, top, right, bottom));
|
||||
}
|
||||
|
||||
bool Subtract(const Rect& r, const Rect& sub, Vector<Rect>& result)
|
||||
{
|
||||
LTIMING("SubtractRect0");
|
||||
Rect is = r & sub;
|
||||
if(!is.IsEmpty()) {
|
||||
AddNotEmpty(result, r.left, is.left, r.top, is.top);
|
||||
AddNotEmpty(result, is.left, is.right, r.top, is.top);
|
||||
AddNotEmpty(result, is.right, r.right, r.top, is.top);
|
||||
AddNotEmpty(result, r.left, is.left, is.top, is.bottom);
|
||||
AddNotEmpty(result, is.right, r.right, is.top, is.bottom);
|
||||
AddNotEmpty(result, r.left, is.left, is.bottom, r.bottom);
|
||||
AddNotEmpty(result, is.left, is.right, is.bottom, r.bottom);
|
||||
AddNotEmpty(result, is.right, r.right, is.bottom, r.bottom);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
result.Add(r);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Subtract(const Vector<Rect>& rr, const Rect& sub, Vector<Rect>& result)
|
||||
{
|
||||
LTIMING("SubtractRect");
|
||||
bool changed = false;
|
||||
for(int i = 0; i < rr.GetCount(); i++) {
|
||||
const Rect& r = rr[i];
|
||||
if(Subtract(r, sub, result))
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
Vector<Rect> Subtract(const Vector<Rect>& rr, const Rect& sub, bool& changed)
|
||||
{
|
||||
Vector<Rect> result;
|
||||
if(Subtract(rr, sub, result))
|
||||
changed = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Subtract(Vector<Rect>& rr, const Rect& sub)
|
||||
{
|
||||
LTIMING("Subtract");
|
||||
if(sub.IsEmpty())
|
||||
return;
|
||||
bool dummy;
|
||||
rr = Subtract(rr, sub, dummy);
|
||||
}
|
||||
|
||||
void Union(Vector<Rect>& rr, const Rect& add)
|
||||
{
|
||||
LTIMING("Union");
|
||||
if(add.IsEmpty())
|
||||
return;
|
||||
Vector<Rect> r;
|
||||
r.Add(add);
|
||||
for(int i = 0; i < rr.GetCount() && r.GetCount(); i++)
|
||||
Subtract(r, rr[i]);
|
||||
for(int i = 0; i < r.GetCount(); i++)
|
||||
rr.Add(r[i]);
|
||||
}
|
||||
|
||||
Vector<Rect> Intersect(const Vector<Rect>& b, const Rect& a, bool& changed)
|
||||
{
|
||||
Vector<Rect> result;
|
||||
for(int i = 0; i < b.GetCount(); i++) {
|
||||
Rect r = b[i] & a;
|
||||
if(r.IsEmpty())
|
||||
changed = true;
|
||||
else {
|
||||
if(r != b[i]) changed = true;
|
||||
result.Add(r);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawFatFrame(Draw& w, int x, int y, int cx, int cy, Color color, int n) {
|
||||
if(n < 0) {
|
||||
x += n;
|
||||
y += n;
|
||||
n = -n;
|
||||
cx += 2 * n;
|
||||
cy += 2 * n;
|
||||
}
|
||||
w.DrawRect(x, y, cx, n, color);
|
||||
w.DrawRect(x, y + n, n, cy - n, color);
|
||||
w.DrawRect(x + cx - n, y + n, n, cy - n, color);
|
||||
w.DrawRect(x + n, y + cy - n, cx - 2 * n, n, color);
|
||||
}
|
||||
|
||||
void DrawFatFrame(Draw& w, const Rect& r, Color color, int n) {
|
||||
DrawFatFrame(w, r.left, r.top, r.Width(), r.Height(), color, n);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, int x, int y, int cx, int cy,
|
||||
Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor)
|
||||
{
|
||||
w.DrawRect(x, y, cx - 1, 1, topcolor);
|
||||
w.DrawRect(x, y, 1, cy - 1, leftcolor);
|
||||
w.DrawRect(x + cx - 1, y, 1, cy, rightcolor);
|
||||
w.DrawRect(x, y + cy - 1, cx, 1, bottomcolor);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, const Rect& r,
|
||||
Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor)
|
||||
{
|
||||
DrawFrame(w, r.left, r.top, r.Width(), r.Height(),
|
||||
leftcolor, topcolor, rightcolor, bottomcolor);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, int x, int y, int cx, int cy,
|
||||
Color topleftcolor, Color bottomrightcolor)
|
||||
{
|
||||
DrawFrame(w, x, y, cx, cy, topleftcolor, topleftcolor, bottomrightcolor, bottomrightcolor);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, const Rect& r,
|
||||
Color topleftcolor, Color bottomrightcolor) {
|
||||
DrawFrame(w, r, topleftcolor, topleftcolor, bottomrightcolor, bottomrightcolor);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, int x, int y, int cx, int cy, Color color) {
|
||||
DrawFrame(w, x, y, cx, cy, color, color);
|
||||
}
|
||||
|
||||
void DrawFrame(Draw& w, const Rect& r, Color color) {
|
||||
DrawFrame(w, r, color, color);
|
||||
}
|
||||
|
||||
void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *c) {
|
||||
if(!c) return;
|
||||
int n = (int)(uintptr_t)*c;
|
||||
c++;
|
||||
while(n--) {
|
||||
if(cx <= 0 || cy <= 0)
|
||||
break;
|
||||
DrawFrame(w, x, y, cx, cy, c[0], c[1], c[2], c[3]);
|
||||
x += 1;
|
||||
y += 1;
|
||||
cx -= 2;
|
||||
cy -= 2;
|
||||
c += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBorder(Draw& w, const Rect& r, const ColorF *c) {
|
||||
DrawBorder(w, r.left, r.top, r.Width(), r.Height(), c);
|
||||
}
|
||||
|
||||
const ColorF *BlackBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)1,
|
||||
&SColorText, &SColorText, &SColorText, &SColorText,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *DefButtonBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)3,
|
||||
&SColorText, &SColorText, &SColorText, &SColorText,
|
||||
&SColorLight, &SColorLight, &SColorText, &SColorText,
|
||||
&SColorLtFace, &SColorLtFace, &SColorShadow, &SColorShadow,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *ButtonBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)2,
|
||||
&SColorLight, &SColorLight, &SColorText, &SColorText,
|
||||
&SColorLtFace, &SColorLtFace, &SColorShadow, &SColorShadow,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *EdgeButtonBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)2,
|
||||
&SColorLtFace, &SColorLtFace, &SColorText, &SColorText,
|
||||
&SColorLight, &SColorLight, &SColorShadow, &SColorShadow,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *ButtonPushBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)2,
|
||||
&SColorText, &SColorText, &SColorText, &SColorText,
|
||||
&SColorShadow, &SColorShadow, &SColorText, &SColorText
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *InsetBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)2,
|
||||
&SColorShadow, &SColorShadow, &SColorLight, &SColorLight,
|
||||
&SColorText, &SColorText, &SColorFace, &SColorFace
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *OutsetBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)2,
|
||||
&SColorFace, &SColorFace, &SColorText, &SColorText,
|
||||
&SColorLight, &SColorLight, &SColorShadow, &SColorShadow,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *ThinOutsetBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)1,
|
||||
&SColorLight, &SColorLight, &SColorShadow, &SColorShadow,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
const ColorF *ThinInsetBorder()
|
||||
{
|
||||
static ColorF data[] = {
|
||||
(ColorF)1,
|
||||
&SColorShadow, &SColorShadow, &SColorLight, &SColorLight,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *(*colors_ltrd)())
|
||||
{
|
||||
DrawBorder(w, x, y, cx, cy, (*colors_ltrd)());
|
||||
}
|
||||
|
||||
void DrawBorder(Draw& w, const Rect& r, const ColorF *(*colors_ltrd)())
|
||||
{
|
||||
DrawBorder(w, r, (*colors_ltrd)());
|
||||
}
|
||||
|
||||
void DrawRectMinusRect(Draw& w, const Rect& rect, const Rect& inner, Color color) {
|
||||
Rect r = rect;
|
||||
r.bottom = inner.top;
|
||||
w.DrawRect(r, color);
|
||||
r = inner;
|
||||
r.right = r.left;
|
||||
r.left = rect.left;
|
||||
w.DrawRect(r, color);
|
||||
r.left = inner.right;
|
||||
r.right = rect.right;
|
||||
w.DrawRect(r, color);
|
||||
r = rect;
|
||||
r.top = inner.bottom;
|
||||
w.DrawRect(r, color);
|
||||
}
|
||||
|
||||
void DrawRect(Draw& w, int x, int y, int cx, int cy, const Image& img, bool ra) {
|
||||
w.Clip(x, y, cx, cy);
|
||||
Size sz = img.GetSize();
|
||||
for(int a = ra ? x : x / sz.cx * sz.cx; a < x + cx; a += sz.cx)
|
||||
for(int b = ra ? y : y / sz.cy * sz.cy ; b < y + cy; b += sz.cy)
|
||||
w.DrawImage(a, b, img);
|
||||
w.End();
|
||||
}
|
||||
|
||||
void DrawRect(Draw& w, const Rect& rect, const Image& img, bool ralgn)
|
||||
{
|
||||
DrawRect(w, rect.left, rect.top, rect.Width(), rect.Height(), img, ralgn);
|
||||
}
|
||||
|
||||
void DrawTiles(Draw& w, int x, int y, int cx, int cy, const Image& img) {
|
||||
w.Clip(x, y, cx, cy);
|
||||
Size sz = img.GetSize();
|
||||
for(int a = x; a < x + cx; a += sz.cx)
|
||||
for(int b = y; b < y + cy; b += sz.cy)
|
||||
w.DrawImage(a, b, img);
|
||||
w.End();
|
||||
}
|
||||
|
||||
void DrawTiles(Draw& w, const Rect& rect, const Image& img)
|
||||
{
|
||||
DrawTiles(w, rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), img);
|
||||
}
|
||||
|
||||
void DrawHighlightImage(Draw& w, int x, int y, const Image& img, bool highlight,
|
||||
bool enabled, Color maskcolor)
|
||||
{
|
||||
if(highlight) {
|
||||
w.DrawImage(x + 1, y, img, maskcolor);
|
||||
w.DrawImage(x - 1, y, img, maskcolor);
|
||||
w.DrawImage(x, y + 1, img, maskcolor);
|
||||
w.DrawImage(x, y - 1, img, maskcolor);
|
||||
}
|
||||
w.DrawImage(x, y, enabled ? img : MakeImage(img, Etched));
|
||||
}
|
||||
|
||||
Color GradientColor(Color fc, Color tc, int i, int n)
|
||||
{
|
||||
return Color(
|
||||
fc.GetR() + i * (tc.GetR() - fc.GetR()) / n,
|
||||
fc.GetG() + i * (tc.GetG() - fc.GetG()) / n,
|
||||
fc.GetB() + i * (tc.GetB() - fc.GetB()) / n
|
||||
);
|
||||
}
|
||||
|
||||
void PaintButtonRect(Draw& w, Rect& r,
|
||||
Color left, Color top, Color right, Color bottom,
|
||||
Color& topleft, Color& topright, Color& bottomleft, Color& bottomright)
|
||||
{
|
||||
w.DrawRect(r.left, r.top, 1, 1, topleft);
|
||||
w.DrawRect(r.right - 1, r.top, 1, 1, topright);
|
||||
w.DrawRect(r.left, r.bottom - 1, 1, 1, bottomleft);
|
||||
w.DrawRect(r.right - 1, r.bottom - 1, 1, 1, bottomright);
|
||||
|
||||
Color b1, b2;
|
||||
w.DrawRect(r.left + 1, r.top, 1, 1, b1 = Blend(topleft, top, 160));
|
||||
w.DrawRect(r.left, r.top + 1, 1, 1, b2 = Blend(topleft, left, 160));
|
||||
w.DrawRect(r.left + 2, r.top, 1, 1, Blend(b1, top));
|
||||
w.DrawRect(r.left, r.top + 2, 1, 1, Blend(b2, left));
|
||||
topleft = Blend(b1, b2);
|
||||
|
||||
w.DrawRect(r.right - 2, r.top, 1, 1, b1 = Blend(topright, top, 160));
|
||||
w.DrawRect(r.right - 1, r.top + 1, 1, 1, b2 = Blend(topright, right, 160));
|
||||
w.DrawRect(r.right - 3, r.top, 1, 1, Blend(b1, top));
|
||||
w.DrawRect(r.right - 1, r.top + 2, 1, 1, Blend(b2, right));
|
||||
topright = Blend(b1, b2);
|
||||
|
||||
w.DrawRect(r.left + 1, r.bottom - 1, 1, 1, b1 = Blend(bottomleft, bottom, 160));
|
||||
w.DrawRect(r.left, r.bottom - 2, 1, 1, b2 = Blend(bottomleft, left, 160));
|
||||
w.DrawRect(r.left + 2, r.bottom - 1, 1, 1, Blend(b1, bottom));
|
||||
w.DrawRect(r.left, r.bottom - 3, 1, 1, Blend(b2, left));
|
||||
bottomleft = Blend(b1, b2);
|
||||
|
||||
w.DrawRect(r.right - 2, r.bottom - 1, 1, 1, b1 = Blend(bottomright, bottom, 160));
|
||||
w.DrawRect(r.right - 1, r.bottom - 2, 1, 1, b2 = Blend(bottomright, right, 160));
|
||||
w.DrawRect(r.right - 3, r.bottom - 1, 1, 1, Blend(b1, bottom));
|
||||
w.DrawRect(r.right - 1, r.bottom - 3, 1, 1, Blend(b2, right));
|
||||
bottomright = Blend(b1, b2);
|
||||
|
||||
w.DrawRect(r.left + 3, r.top, r.Width() - 6, 1, top);
|
||||
w.DrawRect(r.left, r.top + 3, 1, r.Height() - 6, left);
|
||||
w.DrawRect(r.right - 1, r.top + 3, 1, r.Height() - 6, right);
|
||||
w.DrawRect(r.left + 3, r.bottom - 1, r.Width() - 6, 1, bottom);
|
||||
|
||||
r.Deflate(1, 1);
|
||||
}
|
||||
|
||||
void DrawXPButton(Draw& w, Rect r, int type)
|
||||
{
|
||||
Color outlight = SColorLight;
|
||||
Color outshade = Blend(SColorShadow, SColorFace);
|
||||
Color light = SColorLight;
|
||||
Color shade = SColorShadow;
|
||||
Color frame = Blend(SColorHighlight, SColorText);
|
||||
Color mark = Null;
|
||||
Color topleft = SColorFace;
|
||||
int markblend = 0;
|
||||
|
||||
if(type & BUTTON_EDGE)
|
||||
frame = Blend(SColorHighlight, SColorLight);
|
||||
|
||||
if(type & BUTTON_TOOL) {
|
||||
frame = SColorDisabled;
|
||||
light = Blend(SColorFace, light);
|
||||
}
|
||||
|
||||
if(type & BUTTON_SCROLL) {
|
||||
outlight = SColorFace;
|
||||
shade = outshade = SColorFace;
|
||||
frame = Blend(SColorHighlight, SColorShadow);
|
||||
}
|
||||
|
||||
switch(type & 15) {
|
||||
case BUTTON_OK:
|
||||
mark = Blend(Blue, SColorLight);
|
||||
markblend = 130;
|
||||
break;
|
||||
case BUTTON_HIGHLIGHT:
|
||||
if(!(type & BUTTON_SCROLL)) {
|
||||
mark = Blend(Yellow, LtRed, 100);
|
||||
markblend = 130;
|
||||
}
|
||||
break;
|
||||
case BUTTON_PUSH:
|
||||
light = shade = Blend(SColorHighlight, SColorFace, 235);
|
||||
break;
|
||||
case BUTTON_DISABLED:
|
||||
frame = SColorDisabled;
|
||||
outlight = outshade = light = shade = SColorFace;
|
||||
break;
|
||||
case BUTTON_CHECKED:
|
||||
if(type & BUTTON_TOOL)
|
||||
light = shade = SColorLight;
|
||||
else
|
||||
light = shade = Blend(SColorHighlight, SColorFace);
|
||||
break;
|
||||
}
|
||||
|
||||
Color topright = topleft;
|
||||
Color bottomleft = topleft;
|
||||
Color bottomright = topleft;
|
||||
|
||||
if(type & BUTTON_EDGE) {
|
||||
DrawFrame(w, r, frame);
|
||||
light = Blend(frame, SColorLight);
|
||||
shade = Blend(frame, SColorShadow);
|
||||
w.DrawRect(r.left, r.top, 1, 1, light);
|
||||
w.DrawRect(r.right - 1, r.top, 1, 1, light);
|
||||
w.DrawRect(r.left, r.bottom - 1, 1, 1, light);
|
||||
w.DrawRect(r.right - 1, r.bottom - 1, 1, 1, light);
|
||||
r.Deflate(1, 1);
|
||||
switch(type & 15) {
|
||||
case BUTTON_HIGHLIGHT:
|
||||
light = Blend(light, SColorLight);
|
||||
shade = Blend(shade, SColorLight);
|
||||
break;
|
||||
case BUTTON_PUSH:
|
||||
light = shade = Blend(SColorHighlight, SColorFace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!(type & BUTTON_TOOL))
|
||||
PaintButtonRect(w, r, outshade, outshade, outlight, outlight, topleft, topright, bottomleft, bottomright);
|
||||
PaintButtonRect(w, r, frame, frame, frame, frame, topleft, topright, bottomleft, bottomright);
|
||||
Color hc = Blend(light, mark, markblend);
|
||||
Color sc = Blend(shade, mark, markblend);
|
||||
PaintButtonRect(w, r, hc, hc, sc, sc, topleft, topright, bottomleft, bottomright);
|
||||
if(markblend) {
|
||||
DrawFrame(w, r, Blend(hc, mark, markblend), Blend(sc, mark, markblend));
|
||||
r.Deflate(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(type & BUTTON_SCROLL)
|
||||
switch(type & 15) {
|
||||
case BUTTON_PUSH:
|
||||
light = shade = Blend(SColorFace, SColorHighlight);
|
||||
break;
|
||||
case BUTTON_HIGHLIGHT:
|
||||
light = shade = Blend(SColorLight, SColorHighlight, 40);
|
||||
break;
|
||||
default:
|
||||
light = Blend(SColorLight, SColorHighlight, 80);
|
||||
shade = Blend(SColorFace, SColorHighlight, 80);
|
||||
}
|
||||
|
||||
Color b1 = Blend(light, shade, 80);
|
||||
Color bs = Blend(shade, SColorFace);
|
||||
if(type & BUTTON_VERTICAL) {
|
||||
int wd = r.Width();
|
||||
int w1 = 4 * wd / 5;
|
||||
for(int i = 0; i < wd; i++)
|
||||
w.DrawRect(r.left + i, r.top, 1, r.Height(), i < w1 ? Blend(light, b1, 255 * i / w1)
|
||||
: Blend(b1, bs, 255 * (i - w1) / (wd - w1)));
|
||||
}
|
||||
else {
|
||||
int h = r.Height();
|
||||
int h1 = 4 * h / 5;
|
||||
for(int i = 0; i < h; i++)
|
||||
w.DrawRect(r.left, r.top + i, r.Width(), 1, i < h1 ? Blend(light, b1, 255 * i / h1)
|
||||
: Blend(b1, bs, 255 * (i - h1) / (h - h1)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
HRGN GetFrameRgn(const Rect& rect, int n) {
|
||||
HRGN rgn = CreateRectRgnIndirect(rect);
|
||||
Rect r = rect;
|
||||
r.Deflate(n);
|
||||
if(r.Width() > 0 && r.Height() > 0) {
|
||||
HRGN rgnin = CreateRectRgnIndirect(r);
|
||||
CombineRgn(rgn, rgn, rgnin, RGN_XOR);
|
||||
DeleteObject(rgnin);
|
||||
}
|
||||
return rgn;
|
||||
}
|
||||
|
||||
void DrawDragRect(Draw& w, const Rect& _rect1, const Rect& _rect2, const Rect& _clip, int n, Color color, uint64 pattern)
|
||||
{
|
||||
Point o = w.GetOffset();
|
||||
Rect rect1 = _rect1 + o;
|
||||
Rect rect2 = _rect2 + o;
|
||||
Rect clip = _clip + o;
|
||||
HDC hdc = w.BeginGdi();
|
||||
word wpat[8] = {
|
||||
(byte)(pattern >> 56), (byte)(pattern >> 48), (byte)(pattern >> 40), (byte)(pattern >> 32),
|
||||
(byte)(pattern >> 24), (byte)(pattern >> 16), (byte)(pattern >> 8), (byte)(pattern >> 0),
|
||||
};
|
||||
HBITMAP bitmap = CreateBitmap(8, 8, 1, 1, wpat);
|
||||
HBRUSH brush = ::CreatePatternBrush(bitmap);
|
||||
DeleteObject(bitmap);
|
||||
SetTextColor(hdc, color);
|
||||
SetBkColor(hdc, SColorText());
|
||||
Point offset;
|
||||
#ifdef PLATFORM_WINCE
|
||||
offset = Point(0, 0);
|
||||
#else
|
||||
::GetViewportOrgEx(hdc, offset);
|
||||
#endif
|
||||
HRGN rgn = GetFrameRgn(rect1 + offset, n);
|
||||
HRGN rgn2 = GetFrameRgn(rect2 + offset, n);
|
||||
HRGN cliprgn = CreateRectRgnIndirect(clip + offset);
|
||||
CombineRgn(rgn, rgn, rgn2, RGN_XOR);
|
||||
CombineRgn(rgn, rgn, cliprgn, RGN_AND);
|
||||
SelectClipRgn(hdc, rgn);
|
||||
Rect r;
|
||||
GetClipBox(hdc, r);
|
||||
HBRUSH obrush = (HBRUSH) SelectObject(hdc, brush);
|
||||
PatBlt(hdc, r.left, r.top, r.Width(), r.Height(), PATINVERT);
|
||||
SelectObject(hdc, obrush);
|
||||
SelectClipRgn(hdc, NULL);
|
||||
DeleteObject(rgn);
|
||||
DeleteObject(rgn2);
|
||||
DeleteObject(cliprgn);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteObject(brush);
|
||||
w.EndGdi();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
Vector<Rect> RectRgn(const Rect& r)
|
||||
{
|
||||
Vector<Rect> q;
|
||||
q.Add(r);
|
||||
return q;
|
||||
}
|
||||
|
||||
Vector<Rect> Intersect(const Vector<Rect>& r1, const Vector<Rect>& r2)
|
||||
{
|
||||
Vector<Rect> q;
|
||||
for(int i = 0; i < r1.GetCount(); i++)
|
||||
for(int j = 0; j < r2.GetCount(); j++) {
|
||||
Rect r = r1[i] & r2[j];
|
||||
if(!r.IsEmpty())
|
||||
q.Add(r);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
Vector<Rect> Subtract(const Vector<Rect>& r1, const Vector<Rect>& r2)
|
||||
{
|
||||
Vector<Rect> q;
|
||||
bool dummy;
|
||||
q <<= r1;
|
||||
for(int i = 0; i < r2.GetCount(); i++)
|
||||
q = Subtract(q, r2[i], dummy);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
Vector<Rect> Xor(const Vector<Rect>& r1, const Vector<Rect>& r2)
|
||||
{
|
||||
Vector<Rect> is = Intersect(r1, r2);
|
||||
Vector<Rect> q = Subtract(r1, is);
|
||||
q.Append(Subtract(r2, is));
|
||||
return q;
|
||||
}
|
||||
|
||||
Vector<Rect> GetFrameRgn(const Rect& rect, int n) {
|
||||
Vector<Rect> q = RectRgn(rect);
|
||||
q.Add(rect);
|
||||
Rect r = rect;
|
||||
r.Deflate(n);
|
||||
if(r.Width() > 0 && r.Height() > 0)
|
||||
q = Xor(q, RectRgn(r));
|
||||
return q;
|
||||
}
|
||||
|
||||
void DrawDragRect(Draw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n,
|
||||
Color color, uint64 pattern)
|
||||
{
|
||||
char bd[8];
|
||||
for(int i = 0; i < 8; i++)
|
||||
bd[i] = ~(byte)(pattern >> (8 * (7 - i)));
|
||||
Pixmap stipple = XCreateBitmapFromData(Xdisplay, w.GetDrawable(), bd, 8, 8);
|
||||
Point offset = w.GetOffset();
|
||||
GC gc = XCreateGC(Xdisplay, w.GetDrawable(), 0, 0);
|
||||
#ifdef PLATFORM_XFT
|
||||
SetClip(gc, w.GetXftDraw(),
|
||||
Intersect(Xor(GetFrameRgn(rect1 + offset, n), GetFrameRgn(rect2 + offset, n)),
|
||||
RectRgn(clip + offset)));
|
||||
#else
|
||||
SetClip(gc, Intersect(Xor(GetFrameRgn(rect1 + offset, n), GetFrameRgn(rect2 + offset, n)),
|
||||
RectRgn(clip + offset)));
|
||||
#endif
|
||||
XGCValues gcv;
|
||||
gcv.function = X11_ROP2_XOR;
|
||||
gcv.foreground = GetXPixel(color);
|
||||
gcv.fill_style = FillStippled;
|
||||
gcv.stipple = stipple;
|
||||
XChangeGC(Xdisplay, gc, GCForeground|GCFunction|GCStipple|GCFillStyle, &gcv);
|
||||
XFillRectangle(Xdisplay, w.GetDrawable(), gc, 0, 0, Xwidth, Xheight);
|
||||
XFreePixmap(Xdisplay, stipple);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static DrawingToPdfFnType sPdf;
|
||||
|
||||
void SetDrawingToPdfFn(DrawingToPdfFnType Pdf)
|
||||
{
|
||||
sPdf = Pdf;
|
||||
}
|
||||
|
||||
DrawingToPdfFnType GetDrawingToPdfFn()
|
||||
{
|
||||
return sPdf;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
471
archive/olddraw/Draw/DrawWin32.cpp
Normal file
471
archive/olddraw/Draw/DrawWin32.cpp
Normal file
|
|
@ -0,0 +1,471 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
static COLORREF sLightGray;
|
||||
|
||||
void StaticExitDraw_()
|
||||
{
|
||||
Draw::FreeFonts();
|
||||
}
|
||||
|
||||
EXITBLOCK
|
||||
{
|
||||
StaticExitDraw_();
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
void Add(LOGPALETTE *pal, int r, int g, int b)
|
||||
{
|
||||
pal->palPalEntry[pal->palNumEntries].peRed = min(r, 255);
|
||||
pal->palPalEntry[pal->palNumEntries].peGreen = min(g, 255);
|
||||
pal->palPalEntry[pal->palNumEntries].peBlue = min(b, 255);
|
||||
pal->palPalEntry[pal->palNumEntries++].peFlags = PC_NOCOLLAPSE;
|
||||
}
|
||||
|
||||
HPALETTE GetQlibPalette()
|
||||
{
|
||||
static HPALETTE hQlibPalette;
|
||||
if(hQlibPalette) return hQlibPalette;
|
||||
Draw::InitColors();
|
||||
LOGPALETTE *pal = (LOGPALETTE *) new byte[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
|
||||
pal->palNumEntries = 0;
|
||||
pal->palVersion = 0x300;
|
||||
for(int r = 0; r < 6; r++)
|
||||
for(int g = 0; g < 6; g++)
|
||||
for(int b = 0; b < 6; b++)
|
||||
Add(pal, 255 * r / 5, 255 * g / 5, 255 * b / 5);
|
||||
for(int q = 0; q <= 16; q++)
|
||||
Add(pal, 16 * q, 16 * q, 16 * q);
|
||||
Add(pal, GetRValue(sLightGray), GetGValue(sLightGray), GetBValue(sLightGray));
|
||||
hQlibPalette = CreatePalette(pal);
|
||||
delete[] pal;
|
||||
return hQlibPalette;
|
||||
}
|
||||
#endif
|
||||
|
||||
Draw& GLOBAL_VP(ScreenDraw, ScreenInfo, (true))
|
||||
|
||||
HDC ScreenHDC()
|
||||
{
|
||||
return ScreenInfo();
|
||||
}
|
||||
|
||||
static bool _AutoPalette = true;
|
||||
bool Draw::AutoPalette() { return _AutoPalette; }
|
||||
void Draw::SetAutoPalette(bool ap) { _AutoPalette = ap; }
|
||||
|
||||
COLORREF Draw::GetColor(Color c) const {
|
||||
COLORREF color = c;
|
||||
#ifdef PLATFORM_WINCE
|
||||
return color;
|
||||
#else
|
||||
if(!palette)
|
||||
return color;
|
||||
static Index<dword> *SColor;
|
||||
ONCELOCK {
|
||||
static Index<dword> StaticColor;
|
||||
StaticColor << RGB(0x00, 0x00, 0x00) << RGB(0x80, 0x00, 0x00) << RGB(0x00, 0x80, 0x00)
|
||||
<< RGB(0x80, 0x80, 0x00) << RGB(0x00, 0x00, 0x80) << RGB(0x80, 0x00, 0x80)
|
||||
<< RGB(0x00, 0x80, 0x80) << RGB(0xC0, 0xC0, 0xC0) << RGB(0xC0, 0xDC, 0xC0)
|
||||
<< RGB(0xA6, 0xCA, 0xF0) << RGB(0xFF, 0xFB, 0xF0) << RGB(0xA0, 0xA0, 0xA4)
|
||||
<< RGB(0x80, 0x80, 0x80) << RGB(0xFF, 0x00, 0x00) << RGB(0x00, 0xFF, 0x00)
|
||||
<< RGB(0xFF, 0xFF, 0x00) << RGB(0x00, 0x00, 0xFF) << RGB(0xFF, 0x00, 0xFF)
|
||||
<< RGB(0x00, 0xFF, 0xFF) << RGB(0xFF, 0xFF, 0xFF);
|
||||
SColor = &StaticColor;
|
||||
}
|
||||
if(color16 || !AutoPalette())
|
||||
return GetNearestColor(handle, color);
|
||||
if(SColor->Find(color) >= 0)
|
||||
return color;
|
||||
if(color == sLightGray)
|
||||
return PALETTEINDEX(216 + 17);
|
||||
int r = GetRValue(color);
|
||||
int g = GetGValue(color);
|
||||
int b = GetBValue(color);
|
||||
return PALETTEINDEX(r == g && g == b ? (r + 8) / 16 + 216
|
||||
: (r + 25) / 51 * 36 +
|
||||
(g + 25) / 51 * 6 +
|
||||
(b + 25) / 51);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Draw::InitColors()
|
||||
{
|
||||
}
|
||||
|
||||
void Draw::SetColor(Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
LLOG("SetColor " << color);
|
||||
if(color != lastColor) {
|
||||
LLOG("Setting, lastColor:" << FormatIntHex(lastColor.GetRaw())
|
||||
<< " color:" << FormatIntHex(color.GetRaw()) <<
|
||||
" GetColor:" << FormatIntHex(GetColor(color)) << " palette:" << palette);
|
||||
HBRUSH oldBrush = actBrush;
|
||||
HBRUSH h;
|
||||
if(!IsNull(color))
|
||||
h = (HBRUSH) SelectObject(handle, actBrush = CreateSolidBrush(GetColor(color)));
|
||||
else {
|
||||
HGDIOBJ empty = GetStockObject(HOLLOW_BRUSH);
|
||||
h = (HBRUSH) SelectObject(handle, empty);
|
||||
actBrush = NULL;
|
||||
}
|
||||
ASSERT(h);
|
||||
if(!orgBrush) orgBrush = h;
|
||||
if(oldBrush) DeleteObject(oldBrush);
|
||||
lastColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::SetDrawPen(int width, Color color) {
|
||||
DrawLock __;
|
||||
if(IsNull(width))
|
||||
width = PEN_NULL;
|
||||
if(width != lastPen || color != lastPenColor) {
|
||||
static int penstyle[] = {
|
||||
PS_NULL, PS_SOLID, PS_DASH,
|
||||
#ifndef PLATFORM_WINCE
|
||||
PS_DOT, PS_DASHDOT, PS_DASHDOTDOT
|
||||
#endif
|
||||
};
|
||||
HPEN oldPen = actPen;
|
||||
actPen = CreatePen(width < 0 ? penstyle[-width - 1] : PS_SOLID,
|
||||
width < 0 ? 0 : width, GetColor(color));
|
||||
HPEN h = (HPEN) SelectObject(handle, actPen);
|
||||
if(!orgPen) orgPen = h;
|
||||
if(oldPen) DeleteObject(oldPen);
|
||||
lastPen = width;
|
||||
lastPenColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Draw::SetOrg() {
|
||||
DrawLock __;
|
||||
#ifdef PLATFORM_WINCE
|
||||
::SetViewportOrgEx(handle, actual_offset.x, actual_offset.y, 0);
|
||||
#else
|
||||
LLOG("Draw::SetOrg: clip = " << GetClip() << ", offset = " << actual_offset);
|
||||
::SetWindowOrgEx(handle, -actual_offset.x, -actual_offset.y, 0);
|
||||
LLOG("//Draw::SetOrg: clip = " << GetClip());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
Point Draw::LPtoDP(Point p) const {
|
||||
DrawLock __;
|
||||
::LPtoDP(handle, p, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
Point Draw::DPtoLP(Point p) const {
|
||||
DrawLock __;
|
||||
::DPtoLP(handle, p, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
Rect Draw::LPtoDP(const Rect& r) const {
|
||||
DrawLock __;
|
||||
Rect w = r;
|
||||
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
|
||||
return w;
|
||||
}
|
||||
|
||||
Rect Draw::DPtoLP(const Rect& r) const {
|
||||
DrawLock __;
|
||||
Rect w = r;
|
||||
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
|
||||
return w;
|
||||
}
|
||||
#endif
|
||||
|
||||
Size Draw::GetSizeCaps(int i, int j) const {
|
||||
DrawLock __;
|
||||
return Size(GetDeviceCaps(handle, i), GetDeviceCaps(handle, j));
|
||||
}
|
||||
|
||||
void Draw::DotsMode()
|
||||
{
|
||||
::SetMapMode(handle, MM_ANISOTROPIC);
|
||||
::SetViewportExtEx(handle, nativeDpi.cx, nativeDpi.cy, NULL);
|
||||
::SetViewportOrgEx(handle, 0, 0, NULL);
|
||||
::SetWindowExtEx(handle, 600, 600, NULL);
|
||||
::SetWindowOrgEx(handle, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void Draw::BeginNative()
|
||||
{
|
||||
if(inchPixels != nativeDpi && ++native == 1) {
|
||||
::SetMapMode(handle, MM_TEXT);
|
||||
actual_offset_bak = actual_offset;
|
||||
Native(actual_offset);
|
||||
SetOrg();
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::EndNative()
|
||||
{
|
||||
if(inchPixels != nativeDpi && --native == 0) {
|
||||
DotsMode();
|
||||
actual_offset = actual_offset_bak;
|
||||
SetOrg();
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::LoadCaps() {
|
||||
DrawLock __;
|
||||
color16 = false;
|
||||
palette = (GetDeviceCaps(handle, RASTERCAPS) & RC_PALETTE);
|
||||
if(palette)
|
||||
color16 = GetDeviceCaps(handle, SIZEPALETTE) != 256;
|
||||
pageDots = pagePixels = GetSizeCaps(HORZRES, VERTRES);
|
||||
pageMMs = GetSizeCaps(HORZSIZE, VERTSIZE);
|
||||
nativeDpi = inchPixels = GetSizeCaps(LOGPIXELSX, LOGPIXELSY);
|
||||
sheetPixels = GetSizeCaps(PHYSICALWIDTH, PHYSICALHEIGHT);
|
||||
pageOffset = GetSizeCaps(PHYSICALOFFSETX, PHYSICALOFFSETY);
|
||||
is_mono = GetDeviceCaps(handle, BITSPIXEL) == 1 && GetDeviceCaps(handle, PLANES) == 1;
|
||||
}
|
||||
|
||||
void Draw::SetDevice(const char *s) {
|
||||
DrawLock __;
|
||||
static Index<String> map;
|
||||
device = map.FindAdd(s) + 1;
|
||||
LoadCaps();
|
||||
}
|
||||
|
||||
void Draw::Cinit() {
|
||||
DrawLock __;
|
||||
lastColor = Color::FromCR(COLORREF(-5));
|
||||
lastPenColor = Color::FromCR(COLORREF(-5));
|
||||
lastTextColor = COLORREF(-1);
|
||||
lastPen = Null;
|
||||
actBrush = orgBrush = NULL;
|
||||
actPen = orgPen = NULL;
|
||||
orgFont = NULL;
|
||||
lastFont.Clear();
|
||||
}
|
||||
|
||||
void Draw::Init() {
|
||||
DrawLock __;
|
||||
Cinit();
|
||||
SetBkMode(handle, TRANSPARENT);
|
||||
::SetTextAlign(handle, TA_BASELINE);
|
||||
#ifdef PLATFORM_WINCE
|
||||
actual_offset = Point(0, 0);
|
||||
#else
|
||||
::GetViewportOrgEx(handle, actual_offset);
|
||||
#endif
|
||||
LoadCaps();
|
||||
}
|
||||
|
||||
void Draw::Reset() {
|
||||
DrawLock __;
|
||||
device = 0;
|
||||
pixels = true;
|
||||
printer = aborted = backdraw = is_mono = false;
|
||||
}
|
||||
|
||||
Draw::Draw() {
|
||||
DrawLock __;
|
||||
native = 0;
|
||||
InitColors();
|
||||
InitFonts();
|
||||
actual_offset = Point(0, 0);
|
||||
Reset();
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
Draw::Draw(HDC hdc) {
|
||||
DrawLock __;
|
||||
native = 0;
|
||||
InitColors();
|
||||
InitFonts();
|
||||
Reset();
|
||||
Attach(hdc);
|
||||
}
|
||||
|
||||
void Draw::Unselect0() {
|
||||
DrawLock __;
|
||||
if(orgPen) SelectObject(handle, orgPen);
|
||||
if(orgBrush) SelectObject(handle, orgBrush);
|
||||
if(orgFont) SelectObject(handle, orgFont);
|
||||
if(actPen) DeleteObject(actPen);
|
||||
if(actBrush) DeleteObject(actBrush);
|
||||
Cinit();
|
||||
}
|
||||
|
||||
void Draw::Unselect() {
|
||||
DrawLock __;
|
||||
while(cloff.GetCount())
|
||||
End();
|
||||
Unselect0();
|
||||
}
|
||||
|
||||
Draw::~Draw() {
|
||||
DrawLock __;
|
||||
if(handle)
|
||||
Unselect();
|
||||
}
|
||||
|
||||
HDC Draw::BeginGdi() {
|
||||
DrawLock __;
|
||||
Begin();
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Draw::EndGdi() {
|
||||
DrawLock __;
|
||||
Unselect0();
|
||||
End();
|
||||
}
|
||||
|
||||
NilDraw::NilDraw() {
|
||||
DrawLock __;
|
||||
Attach(ScreenInfo().GetHandle());
|
||||
pixels = false;
|
||||
cloff.Clear();
|
||||
}
|
||||
|
||||
NilDraw::~NilDraw() {
|
||||
DrawLock __;
|
||||
Detach();
|
||||
}
|
||||
|
||||
void BackDraw::Create(Draw& w, int cx, int cy) {
|
||||
ASSERT(w.GetHandle());
|
||||
DrawLock __;
|
||||
Destroy();
|
||||
size.cx = cx;
|
||||
size.cy = cy;
|
||||
hbmp = ::CreateCompatibleBitmap(w.GetHandle(), cx, cy);
|
||||
handle = ::CreateCompatibleDC(w.GetHandle());
|
||||
ASSERT(hbmp);
|
||||
ASSERT(handle);
|
||||
#ifndef PLATFORM_WINCE
|
||||
if(w.PaletteMode() && AutoPalette()) {
|
||||
::SelectPalette(handle, GetQlibPalette(), FALSE);
|
||||
::RealizePalette(handle);
|
||||
}
|
||||
#endif
|
||||
hbmpold = (HBITMAP) ::SelectObject(handle, hbmp);
|
||||
Init();
|
||||
backdraw = true;
|
||||
}
|
||||
|
||||
void BackDraw::Put(Draw& w, int x, int y) {
|
||||
DrawLock __;
|
||||
ASSERT(handle);
|
||||
LTIMING("BackDraw::Put");
|
||||
#ifdef PLATFORM_WINCE
|
||||
::SetViewportOrgEx(handle, 0, 0, 0);
|
||||
#else
|
||||
::SetWindowOrgEx(handle, 0, 0, NULL);
|
||||
#endif
|
||||
::BitBlt(w, x, y, size.cx, size.cy, *this, 0, 0, SRCCOPY);
|
||||
}
|
||||
|
||||
void BackDraw::Destroy() {
|
||||
DrawLock __;
|
||||
if(handle) {
|
||||
Unselect();
|
||||
::SelectObject(handle, hbmpold);
|
||||
::DeleteDC(handle);
|
||||
::DeleteObject(hbmp);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ScreenDraw::ScreenDraw(bool ic) {
|
||||
DrawLock __;
|
||||
#ifdef PLATFORM_WINCE
|
||||
Attach(CreateDC(NULL, NULL, NULL, NULL));
|
||||
#else
|
||||
Attach((ic ? CreateIC : CreateDC)("DISPLAY", NULL, NULL, NULL));
|
||||
if(PaletteMode() && AutoPalette()) {
|
||||
SelectPalette(handle, GetQlibPalette(), TRUE);
|
||||
RealizePalette(handle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ScreenDraw::~ScreenDraw() {
|
||||
DrawLock __;
|
||||
Unselect();
|
||||
DeleteDC(handle);
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
|
||||
void PrintDraw::InitPrinter()
|
||||
{
|
||||
DrawLock __;
|
||||
Init();
|
||||
printer = true;
|
||||
pixels = false;
|
||||
nativeDpi = inchPixels;
|
||||
DotsMode();
|
||||
native = 0;
|
||||
actual_offset = Point(0, 0);
|
||||
pageDots.cx = 600 * pagePixels.cx / inchPixels.cx;
|
||||
pageDots.cy = 600 * pagePixels.cy / inchPixels.cy;
|
||||
inchPixels.cx = 600;
|
||||
inchPixels.cy = 600;
|
||||
}
|
||||
|
||||
void PrintDraw::StartPage()
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsAborted()) return;
|
||||
Unselect();
|
||||
if(::StartPage(handle) <= 0)
|
||||
Abort();
|
||||
else
|
||||
InitPrinter();
|
||||
}
|
||||
|
||||
void PrintDraw::EndPage()
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsAborted()) return;
|
||||
Unselect();
|
||||
ASSERT(printer);
|
||||
if(::EndPage(handle) <= 0)
|
||||
Abort();
|
||||
}
|
||||
|
||||
PrintDraw::PrintDraw(HDC hdc, const char *docname)
|
||||
: Draw(hdc)
|
||||
{
|
||||
DrawLock __;
|
||||
DOCINFO di;
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.cbSize = sizeof(di);
|
||||
String sys_docname = ToSystemCharset(docname);
|
||||
di.lpszDocName = ~sys_docname;
|
||||
if(::StartDoc(hdc, &di) <= 0) {
|
||||
Abort();
|
||||
return;
|
||||
}
|
||||
InitPrinter();
|
||||
}
|
||||
|
||||
PrintDraw::~PrintDraw() {
|
||||
DrawLock __;
|
||||
if(IsAborted())
|
||||
::AbortDoc(handle);
|
||||
else
|
||||
::EndDoc(handle);
|
||||
DeleteDC(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
105
archive/olddraw/Draw/DrawWin32.h
Normal file
105
archive/olddraw/Draw/DrawWin32.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef PLATFORM_WINCE
|
||||
class WinMetaFile {
|
||||
Size size;
|
||||
mutable HENHMETAFILE hemf;
|
||||
|
||||
void ChkP() const { ASSERT(!IsPicked()); }
|
||||
void Init();
|
||||
void Pick(pick_ WinMetaFile& src);
|
||||
void Copy(const WinMetaFile& src);
|
||||
|
||||
public:
|
||||
void Attach(HENHMETAFILE emf);
|
||||
HENHMETAFILE *Detach();
|
||||
|
||||
bool IsPicked() const { return (uintptr_t) hemf == 0xffffffff; }
|
||||
|
||||
operator bool() const { ChkP(); return hemf; }
|
||||
Size GetSize() const { ChkP(); return hemf ? size : Size(0, 0); }
|
||||
|
||||
void Clear();
|
||||
|
||||
void Paint(Draw& w, const Rect& r) const;
|
||||
void Paint(Draw& w, int x, int y, int cx, int cy) const;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
|
||||
void ReadClipboard();
|
||||
void WriteClipboard() const;
|
||||
bool Load(const char *file);
|
||||
|
||||
WinMetaFile() { Init(); }
|
||||
WinMetaFile(HENHMETAFILE hemf);
|
||||
WinMetaFile(HENHMETAFILE hemf, Size sz);
|
||||
WinMetaFile(const char *file);
|
||||
|
||||
WinMetaFile(pick_ WinMetaFile& src) { Pick(src); }
|
||||
WinMetaFile(const WinMetaFile& src, int) { Copy(src); }
|
||||
void operator=(pick_ WinMetaFile& src) { Clear(); Pick(src); }
|
||||
void operator<<=(const WinMetaFile& src) { Clear(); Copy(src); }
|
||||
|
||||
~WinMetaFile() { Clear(); }
|
||||
|
||||
HENHMETAFILE GetHEMF() const { ChkP(); return hemf; }
|
||||
};
|
||||
|
||||
class WinMetaFileDraw : public Draw {
|
||||
Size size;
|
||||
|
||||
public:
|
||||
bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
WinMetaFile Close();
|
||||
|
||||
WinMetaFileDraw() {}
|
||||
WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL);
|
||||
~WinMetaFileDraw();
|
||||
};
|
||||
#endif
|
||||
|
||||
class ScreenDraw : public Draw {
|
||||
public:
|
||||
ScreenDraw(bool ic = false);
|
||||
~ScreenDraw();
|
||||
};
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
class PrintDraw : public Draw {
|
||||
public:
|
||||
virtual void StartPage();
|
||||
virtual void EndPage();
|
||||
|
||||
private:
|
||||
void InitPrinter();
|
||||
public:
|
||||
void Abort() { aborted = true; }
|
||||
|
||||
PrintDraw(HDC hdc, const char *jobname);
|
||||
~PrintDraw();
|
||||
};
|
||||
#endif
|
||||
|
||||
inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY)
|
||||
{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); }
|
||||
|
||||
inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY)
|
||||
{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); }
|
||||
|
||||
inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY)
|
||||
{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); }
|
||||
|
||||
inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); }
|
||||
inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); }
|
||||
|
||||
inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); }
|
||||
inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); }
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); }
|
||||
#endif
|
||||
inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); }
|
||||
inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); }
|
||||
inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); }
|
||||
|
||||
inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); }
|
||||
465
archive/olddraw/Draw/DrawX11.cpp
Normal file
465
archive/olddraw/Draw/DrawX11.cpp
Normal file
|
|
@ -0,0 +1,465 @@
|
|||
#include "Draw.h"
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
#define Time XTime
|
||||
#define Font XFont
|
||||
#define Display XDisplay
|
||||
#define Picture XPicture
|
||||
|
||||
#ifndef flagNOGTK
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdkprivate.h>
|
||||
#endif
|
||||
|
||||
#undef Picture
|
||||
#undef Time
|
||||
#undef Font
|
||||
#undef Display
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) //LOG(x)
|
||||
#define LTIMING(x) //TIMING(x)
|
||||
|
||||
XDisplay *Xdisplay;
|
||||
int Xscreenno;
|
||||
Visual *Xvisual;
|
||||
Window Xroot;
|
||||
Screen *Xscreen;
|
||||
Colormap Xcolormap;
|
||||
int Xheight;
|
||||
int Xwidth;
|
||||
int XheightMM;
|
||||
int XwidthMM;
|
||||
int Xdepth;
|
||||
dword Xblack;
|
||||
dword Xwhite;
|
||||
int Xconnection;
|
||||
byte *Xmapcolor;
|
||||
byte *Xunmapcolor;
|
||||
|
||||
dword (*Xgetpixel)(int r, int g, int b);
|
||||
|
||||
void StaticExitDraw_()
|
||||
{
|
||||
Draw::FreeFonts();
|
||||
}
|
||||
|
||||
EXITBLOCK
|
||||
{
|
||||
if(Xdisplay) {
|
||||
StaticExitDraw_();
|
||||
// No CloseDisplay for now...
|
||||
XCloseDisplay(Xdisplay);
|
||||
LLOG("Xdisplay closed");
|
||||
Xdisplay = NULL;
|
||||
}
|
||||
if(Xmapcolor)
|
||||
delete[] Xmapcolor;
|
||||
if(Xunmapcolor)
|
||||
delete[] Xunmapcolor;
|
||||
}
|
||||
|
||||
void XError()
|
||||
{
|
||||
Panic("X11 error !");
|
||||
}
|
||||
|
||||
void XError(const char *s)
|
||||
{
|
||||
Panic(String("X11 error:") + s + " !");
|
||||
}
|
||||
|
||||
static int sAcs;
|
||||
|
||||
bool sAllocColor(int xr, int xg, int xb)
|
||||
{
|
||||
XColor ce;
|
||||
ce.red = xr;
|
||||
ce.green = xg;
|
||||
ce.blue = xb;
|
||||
ce.flags = DoRed | DoGreen | DoBlue;
|
||||
if(!XAllocColor(Xdisplay, Xcolormap, &ce)) return false;
|
||||
sAcs++;
|
||||
return sAcs < 257;
|
||||
}
|
||||
|
||||
void sAllocColors()
|
||||
{
|
||||
int r, g, b;
|
||||
for(r = 0; r < 2; r++)
|
||||
for(g = 0; g < 2; g++)
|
||||
for(b = 0; b < 2; b++)
|
||||
if(!sAllocColor(65535 * r, 65535 * g, 65535 * b)) return;
|
||||
for(r = 0; r < 3; r++)
|
||||
for(g = 0; g < 3; g++)
|
||||
for(b = 0; b < 3; b++)
|
||||
if((r == 1 || g == 1 || b == 1) &&
|
||||
!sAllocColor((65535 * r) / 2, (65535 * g) / 2, (65535 * b) / 2)) return;
|
||||
for(r = 5; r >= 0; r--)
|
||||
for(g = 5; g >= 0; g--)
|
||||
for(b = 5; b >= 0; b--)
|
||||
if((r != 0 && r != 5 || g != 0 && g != 5 || b != 0 && b != 5) &&
|
||||
!sAllocColor((65535 * r) / 5, (65535 * g) / 5, (65535 * b) / 5)) return;
|
||||
for(r = 1; r <= 11; r += 2)
|
||||
if(!sAllocColor((65535 * r) / 11, (65535 * r) / 11, (65535 * r) / 11)) return;
|
||||
for(int r = 255; r >= 0; r--)
|
||||
if(!sAllocColor(r << 8, r << 8, r << 8)) return;
|
||||
}
|
||||
|
||||
dword GetPseudoColorPixel(int r, int g, int b)
|
||||
{
|
||||
return Xmapcolor[r * 11 / 255 * (24 * 12) + g * 23 / 255 * 12 + b * 11 / 255];
|
||||
}
|
||||
|
||||
static
|
||||
struct Xshift {
|
||||
dword mask;
|
||||
int bits;
|
||||
int shift;
|
||||
dword Do(int c) { return (c >> bits << shift) & mask; }
|
||||
}
|
||||
Xred, Xgreen, Xblue;
|
||||
|
||||
Xshift CalcXShift(dword mask)
|
||||
{
|
||||
Xshift f;
|
||||
f.mask = mask;
|
||||
f.shift = 0;
|
||||
f.bits = 0;
|
||||
while((mask & 1) == 0) {
|
||||
mask >>= 1;
|
||||
f.shift++;
|
||||
}
|
||||
while((mask & 1) == 1) {
|
||||
mask >>= 1;
|
||||
f.bits++;
|
||||
}
|
||||
f.bits = 8 - f.bits;
|
||||
if(f.bits < 0) {
|
||||
f.shift += f.bits;
|
||||
f.bits = 0;
|
||||
}
|
||||
LLOG("xshift(" << FormatIntHex(mask) << "): mask = "
|
||||
<< FormatIntHex(f.mask) << ", bits = " << f.bits << ", shift = " << f.shift);
|
||||
return f;
|
||||
}
|
||||
|
||||
dword GetTrueColorPixel(int r, int g, int b)
|
||||
{
|
||||
return Xred.Do(r) | Xgreen.Do(g) | Xblue.Do(b);
|
||||
}
|
||||
|
||||
inline int ssq(int x) { return x * x; }
|
||||
|
||||
void InitX11Draw(XDisplay *display)
|
||||
{
|
||||
Xdisplay = display;
|
||||
if(!Xdisplay) {
|
||||
puts(NFormat("No X11 display, errno = %d, %s", errno, strerror(errno)));
|
||||
fflush(stdout);
|
||||
XError();
|
||||
}
|
||||
Xscreenno = DefaultScreen(Xdisplay);
|
||||
Xroot = RootWindow(Xdisplay, Xscreenno);
|
||||
Xscreen = ScreenOfDisplay(Xdisplay, Xscreenno);
|
||||
Xcolormap = DefaultColormap(Xdisplay, Xscreenno);
|
||||
// Xcolormap = (Colormap)GDK().gdk_x11_colormap_get_xcolormap(GDK().gdk_rgb_get_colormap());
|
||||
Xheight = DisplayHeight(Xdisplay, Xscreenno);
|
||||
Xwidth = DisplayWidth(Xdisplay, Xscreenno);
|
||||
XheightMM = DisplayHeightMM(Xdisplay, Xscreenno);
|
||||
XwidthMM = DisplayWidthMM(Xdisplay, Xscreenno);
|
||||
LLOG("Xwidth = " << Xwidth << ", XwidthMM = " << XwidthMM);
|
||||
LLOG("Xheight = " << Xheight << ", XheightMM = " << XheightMM);
|
||||
Xdepth = DefaultDepth(Xdisplay, Xscreenno);
|
||||
Xblack = BlackPixel(Xdisplay, 0);
|
||||
Xwhite = WhitePixel(Xdisplay, 0);
|
||||
Xconnection = XConnectionNumber(Xdisplay);
|
||||
Xvisual = DefaultVisual(Xdisplay, Xscreenno);
|
||||
Visual *v = Xvisual;
|
||||
if(v->c_class == TrueColor) {
|
||||
Xred = CalcXShift(v->red_mask);
|
||||
Xgreen = CalcXShift(v->green_mask);
|
||||
Xblue = CalcXShift(v->blue_mask);
|
||||
Xgetpixel = GetTrueColorPixel;
|
||||
}
|
||||
else {
|
||||
sAllocColors();
|
||||
int colorcount = max(1 << Xdepth, 256);
|
||||
Buffer<XColor> cs(colorcount);
|
||||
int i;
|
||||
for(i = 0; i < colorcount; i++)
|
||||
cs[i].pixel = i;
|
||||
XQueryColors(Xdisplay, Xcolormap, cs, colorcount);
|
||||
Xunmapcolor = new byte[3 * colorcount];
|
||||
for(i = 0; i < colorcount; i++)
|
||||
{
|
||||
Xunmapcolor[3 * i + 0] = cs[i].blue;
|
||||
Xunmapcolor[3 * i + 1] = cs[i].green;
|
||||
Xunmapcolor[3 * i + 2] = cs[i].red;
|
||||
}
|
||||
byte *cm = Xmapcolor = new byte[12 * 24 * 12];
|
||||
for(int r = 0; r < 12; r++)
|
||||
for(int g = 0; g < 24; g++)
|
||||
for(int b = 0; b < 12; b++) {
|
||||
int mind = INT_MAX;
|
||||
int mini;
|
||||
for(int i = 0; i < colorcount; i++) {
|
||||
int d = ssq(r * 255 / 11 - (cs[i].red >> 8)) +
|
||||
ssq(g * 255 / 23 - (cs[i].green >> 8)) +
|
||||
ssq(b * 255 / 11 - (cs[i].blue >> 8));
|
||||
if(d < mind) {
|
||||
mini = i;
|
||||
mind = d;
|
||||
}
|
||||
}
|
||||
*cm++ = mini;
|
||||
}
|
||||
Xgetpixel = GetPseudoColorPixel;
|
||||
}
|
||||
// XFree(v);
|
||||
|
||||
Draw::SetStdFont(ScreenSans(12));
|
||||
}
|
||||
|
||||
void InitX11Draw(const char *dispname)
|
||||
{
|
||||
#ifdef flagNOGTK
|
||||
if(!dispname || !*dispname) {
|
||||
int f = Environment().Find("DISPLAY");
|
||||
dispname = (f >= 0 ? ~Environment()[f] : ":0.0");
|
||||
}
|
||||
InitX11Draw(XOpenDisplay(dispname));
|
||||
#else
|
||||
MemoryIgnoreLeaksBlock __;
|
||||
const Vector<String>& cmd = CommandLine();
|
||||
char **argv = (char**) MemoryAllocPermanent(sizeof(char *) * cmd.GetCount());
|
||||
for(int i = 0; i < cmd.GetCount(); i++)
|
||||
argv[i] = PermanentCopy(cmd[i]);
|
||||
int argc = cmd.GetCount();
|
||||
gtk_init (&argc, &argv);
|
||||
GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
GdkDisplay *d = gtk_widget_get_display(w);
|
||||
gdk_x11_display_get_xdisplay(d);
|
||||
InitX11Draw(gdk_x11_display_get_xdisplay(d));
|
||||
gtk_widget_destroy(w);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_XFT
|
||||
void SetClip(GC gc, XftDraw *xftdraw, const Vector<Rect>& cl)
|
||||
#else
|
||||
void SetClip(GC gc, const Vector<Rect>& cl)
|
||||
#endif
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("SetClip");
|
||||
Buffer<XRectangle> xr(cl.GetCount());
|
||||
LLOG("SetClip");
|
||||
for(int i = 0; i < cl.GetCount(); i++) {
|
||||
XRectangle& r = xr[i];
|
||||
const Rect& cr = cl[i];
|
||||
LLOG("[" << i << "] = " << cr);
|
||||
r.x = cr.left;
|
||||
r.y = cr.top;
|
||||
r.width = cr.Width();
|
||||
r.height = cr.Height();
|
||||
}
|
||||
XSetClipRectangles(Xdisplay, gc, 0, 0, xr, cl.GetCount(), Unsorted);
|
||||
#ifdef PLATFORM_XFT
|
||||
LLOG("XftDrawSetClipRectangles, # = " << cl.GetCount() << ", xftdraw = " << FormatIntHex(xftdraw));
|
||||
XftDrawSetClipRectangles(xftdraw, 0, 0, xr, cl.GetCount());
|
||||
LLOG("//XftDrawSetClipRectangles");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Draw::CloneClip()
|
||||
{
|
||||
if(cloff.GetCount() > 1 && cloff.Top().clipi == cloff[cloff.GetCount() - 2].clipi) {
|
||||
cloff.Top().clipi = clip.GetCount();
|
||||
Vector<Rect>& c = clip.Add();
|
||||
c <<= clip[clip.GetCount() - 2];
|
||||
}
|
||||
}
|
||||
|
||||
void Draw::SetForeground(Color color)
|
||||
{
|
||||
DrawLock __;
|
||||
LTIMING("SetForeground");
|
||||
if(IsDrawing()) return;
|
||||
int p = GetXPixel(color.GetR(), color.GetG(), color.GetB());
|
||||
if(p == foreground) return;
|
||||
LTIMING("XSetForeground");
|
||||
LLOG("XSetForeground " << color);
|
||||
foreground = p;
|
||||
XSetForeground(Xdisplay, gc, foreground);
|
||||
}
|
||||
|
||||
void Draw::SetClip() {
|
||||
DrawLock __;
|
||||
if(IsDrawing() || dw == Xroot) return;
|
||||
LTIMING("SetClip");
|
||||
#ifdef PLATFORM_XFT
|
||||
UPP::SetClip(gc, xftdraw, clip.Top());
|
||||
#else
|
||||
UPP::SetClip(gc, clip.Top());
|
||||
#endif
|
||||
}
|
||||
|
||||
void Draw::SetLineStyle(int width)
|
||||
{
|
||||
DrawLock __;
|
||||
if(IsDrawing()) return;
|
||||
if(width == linewidth) return;
|
||||
linewidth = width;
|
||||
if(IsNull(width))
|
||||
width = 1;
|
||||
if(width < PEN_SOLID) {
|
||||
static const char dash[] = { 18, 6 };
|
||||
static const char dot[] = { 3, 3 };
|
||||
static const char dashdot[] = { 9, 6, 3, 6 };
|
||||
static const char dashdotdot[] = { 9, 3, 3, 3, 3, 3 };
|
||||
static struct {
|
||||
const char *dash;
|
||||
int len;
|
||||
} ds[] = {
|
||||
{ dash, __countof(dash) },
|
||||
{ dot, __countof(dot) },
|
||||
{ dashdot, __countof(dashdot) },
|
||||
{ dashdotdot, __countof(dashdotdot) }
|
||||
};
|
||||
int i = -(width - PEN_DASH);
|
||||
ASSERT(i >= 0 && i < 4);
|
||||
XSetDashes(Xdisplay, gc, 0, ds[i].dash, ds[i].len);
|
||||
}
|
||||
XSetLineAttributes(Xdisplay, gc, max(width, 1),
|
||||
width < PEN_SOLID ? LineOnOffDash : LineSolid, CapRound, JoinRound);
|
||||
}
|
||||
|
||||
void Draw::Init()
|
||||
{
|
||||
DrawLock __;
|
||||
pageDots = pagePixels = Size(Xwidth, Xheight);
|
||||
pageMMs = Size(XwidthMM, XheightMM);
|
||||
nativeDpi = inchPixels = 254 * pagePixels / pageMMs / 10;
|
||||
sheetPixels = pagePixels;
|
||||
pageOffset = Point(0, 0);
|
||||
InitFonts();
|
||||
cloff.Clear();
|
||||
clip.Clear();
|
||||
foreground = linewidth = Null;
|
||||
device = 0;
|
||||
device = 0;
|
||||
pixels = true;
|
||||
printer = aborted = backdraw = is_mono = false;
|
||||
native = 0;
|
||||
}
|
||||
|
||||
void Draw::Init(const Vector<Rect>& _clip, Point _offset)
|
||||
{
|
||||
DrawLock __;
|
||||
Init();
|
||||
clip.Add() <<= _clip;
|
||||
offset.Add(_offset);
|
||||
actual_offset = _offset;
|
||||
Cloff& f = cloff.Add();
|
||||
f.offseti = 0;
|
||||
f.clipi = 0;
|
||||
SetClip();
|
||||
}
|
||||
|
||||
Draw::Draw()
|
||||
{
|
||||
DrawLock __;
|
||||
dw = None;
|
||||
gc = None;
|
||||
actual_offset = Point(0, 0);
|
||||
Init();
|
||||
}
|
||||
|
||||
void Draw::BeginNative() {}
|
||||
|
||||
void Draw::EndNative() {}
|
||||
|
||||
|
||||
#ifdef PLATFORM_XFT
|
||||
Draw::Draw(Drawable _dw, GC _gc, XftDraw *_xftdraw, const Vector<Rect>& _clip)
|
||||
#else
|
||||
Draw::Draw(Drawable _dw, GC _gc, const Vector<Rect>& _clip)
|
||||
#endif
|
||||
{
|
||||
LLOG("Draw");
|
||||
dw = _dw;
|
||||
gc = _gc;
|
||||
#ifdef PLATFORM_XFT
|
||||
xftdraw = _xftdraw;
|
||||
#endif
|
||||
Init(_clip);
|
||||
}
|
||||
|
||||
Draw::~Draw()
|
||||
{
|
||||
}
|
||||
|
||||
void BackDraw::Create(Draw& w, int cx, int cy)
|
||||
{
|
||||
DrawLock __;
|
||||
LLOG("Creating BackDraw " << cx << "x" << cy);
|
||||
Destroy();
|
||||
size.cx = cx;
|
||||
size.cy = cy;
|
||||
dw = XCreatePixmap(Xdisplay, w.GetDrawable(), max(cx, 1), max(cy, 1), Xdepth);
|
||||
gc = XCreateGC(Xdisplay, dw, 0, 0);
|
||||
#ifdef PLATFORM_XFT
|
||||
xftdraw = XftDrawCreate(Xdisplay, (Drawable) dw,
|
||||
DefaultVisual(Xdisplay, Xscreenno), Xcolormap);
|
||||
#endif
|
||||
Vector<Rect> clip;
|
||||
clip.Add(RectC(0, 0, cx, cy));
|
||||
Init(clip, Point(0, 0));
|
||||
backdraw = true;
|
||||
}
|
||||
|
||||
void BackDraw::Put(Draw& w, int x, int y)
|
||||
{
|
||||
DrawLock __;
|
||||
LLOG("Putting BackDraw");
|
||||
ASSERT(dw != None);
|
||||
XCopyArea(Xdisplay, dw, w.GetDrawable(), w.GetGC(), 0, 0, size.cx, size.cy,
|
||||
x + w.GetOffset().x, y + w.GetOffset().y);
|
||||
}
|
||||
|
||||
void BackDraw::Destroy()
|
||||
{
|
||||
DrawLock __;
|
||||
if(dw != None) {
|
||||
#ifdef PLATFORM_XFT
|
||||
XftDrawDestroy(xftdraw);
|
||||
#endif
|
||||
XFreePixmap(Xdisplay, dw);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
}
|
||||
}
|
||||
|
||||
NilDraw::NilDraw()
|
||||
{
|
||||
DrawLock __;
|
||||
dw = Xroot;
|
||||
gc = XCreateGC(Xdisplay, Xroot, 0, 0);
|
||||
pixels = false;
|
||||
Init(Vector<Rect>());
|
||||
}
|
||||
|
||||
NilDraw::~NilDraw()
|
||||
{
|
||||
DrawLock __;
|
||||
XFreeGC(Xdisplay, gc);
|
||||
}
|
||||
|
||||
Draw& ScreenInfo() { return Single<NilDraw>(); }
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
||||
#endif
|
||||
743
archive/olddraw/Draw/Drawing.cpp
Normal file
743
archive/olddraw/Draw/Drawing.cpp
Normal file
|
|
@ -0,0 +1,743 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
#ifdef COMPILER_MSC
|
||||
#pragma warning(disable: 4700)
|
||||
#endif
|
||||
|
||||
static void StreamUnpackPoints(Stream& stream, Point *out, int count)
|
||||
{
|
||||
if(count == 0)
|
||||
return;
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
if(sizeof(Point) == 8) {
|
||||
stream.Get(out, 8 * count);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Point *end = out + count;
|
||||
byte *top = reinterpret_cast<byte *>(end) - count * 8;
|
||||
stream.Get(top, count * 8);
|
||||
for(; out < end; out++, top += 8) {
|
||||
out -> x = (short)Peek32le(top + 0);
|
||||
out -> y = (short)Peek32le(top + 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void StreamPackPoints(Stream& stream, const Point *in, int count)
|
||||
{
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
if(sizeof(Point) == 8) {
|
||||
stream.Put(in, 8 * count);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
enum { PART = 1024 };
|
||||
byte part[PART * 8];
|
||||
while(count > 0)
|
||||
{
|
||||
int part_count = min<int>(count, PART);
|
||||
for(byte *pp = part, *pe = pp + 8 * part_count; pp < pe; pp += 8, in++) {
|
||||
Poke32le(pp + 0, in -> x);
|
||||
Poke32le(pp + 4, in -> y);
|
||||
}
|
||||
stream.Put(part, part_count * 4);
|
||||
count -= part_count;
|
||||
}
|
||||
}
|
||||
|
||||
static void StreamUnpackInts(Stream& stream, int *out, int count)
|
||||
{
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
if(sizeof(int) == 4) {
|
||||
stream.Get(out, count * 4);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
while(count--)
|
||||
*out++ = stream.Get32le();
|
||||
}
|
||||
|
||||
static void StreamPackInts(Stream& stream, const int *in, int count)
|
||||
{
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
if(sizeof(int) == 4) {
|
||||
stream.Put(in, count * 4);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
while(count--)
|
||||
stream.Put32le(*in++);
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
|
||||
Stream& DrawingDraw::DrawingOp(int code)
|
||||
{
|
||||
ASSERT(IsDrawing());
|
||||
drawing / code;
|
||||
return drawing;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawingBegin()
|
||||
{
|
||||
Cloff& w = cloff.Add();
|
||||
w.org = actual_offset;
|
||||
w.drawingclip = drawingclip;
|
||||
}
|
||||
|
||||
void DrawingDraw::BeginOp()
|
||||
{
|
||||
DrawingOp(BEGIN);
|
||||
DrawingBegin();
|
||||
}
|
||||
|
||||
void DrawingDraw::OffsetOp(Point p)
|
||||
{
|
||||
DrawingOp(OFFSET) % p;
|
||||
DrawingBegin();
|
||||
actual_offset += p;
|
||||
}
|
||||
|
||||
bool DrawingDraw::ClipOp(const Rect& r)
|
||||
{
|
||||
DrawingOp(CLIP) % const_cast<Rect&>(r);
|
||||
DrawingBegin();
|
||||
drawingclip &= r + actual_offset;
|
||||
return !drawingclip.IsEmpty();
|
||||
}
|
||||
|
||||
bool DrawingDraw::ClipoffOp(const Rect& r)
|
||||
{
|
||||
DrawingOp(CLIPOFF) % const_cast<Rect&>(r);
|
||||
DrawingBegin();
|
||||
drawingclip &= r + actual_offset;
|
||||
actual_offset += r.TopLeft();
|
||||
return !drawingclip.IsEmpty();
|
||||
}
|
||||
|
||||
void DrawingDraw::EndOp()
|
||||
{
|
||||
DrawingOp(END);
|
||||
ASSERT(cloff.GetCount());
|
||||
Cloff& w = cloff.Top();
|
||||
actual_offset = w.org;
|
||||
drawingclip = w.drawingclip;
|
||||
cloff.Drop();
|
||||
}
|
||||
|
||||
bool DrawingDraw::ExcludeClipOp(const Rect& r)
|
||||
{
|
||||
DrawingOp(EXCLUDECLIP) % const_cast<Rect&>(r);
|
||||
return !drawingclip.IsEmpty();
|
||||
}
|
||||
|
||||
bool DrawingDraw::IntersectClipOp(const Rect& r)
|
||||
{
|
||||
DrawingOp(INTERSECTCLIP) % const_cast<Rect&>(r);
|
||||
drawingclip &= r;
|
||||
return !drawingclip.IsEmpty();
|
||||
}
|
||||
|
||||
Rect DrawingDraw::GetClipOp() const
|
||||
{
|
||||
return drawingclip - actual_offset;
|
||||
}
|
||||
|
||||
bool DrawingDraw::IsPaintingOp(const Rect& r) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
|
||||
{
|
||||
if(!IsNull(color))
|
||||
DrawingOp(DRAWRECT) % x % y % cx % cy % color;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color)
|
||||
{
|
||||
Rect s = src;
|
||||
DrawingOp(DRAWIMAGE) % x % y % cx % cy % s % color;
|
||||
val.Add(img);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id)
|
||||
{
|
||||
String h = id;
|
||||
DrawingOp(DRAWDATA) % x % y % cx % cy % h;
|
||||
val.Add(data);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawDrawingOp(const Rect& target, const Drawing& w)
|
||||
{
|
||||
DrawingOp(DRAWDRAWING) % const_cast<Rect&>(target);
|
||||
val.Add(w);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawPaintingOp(const Rect& target, const Painting& w)
|
||||
{
|
||||
DrawingOp(DRAWPAINTING) % const_cast<Rect&>(target);
|
||||
val.Add(w);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
|
||||
{
|
||||
DrawingOp(DRAWLINE) % x1 % y1 % x2 % y2 % width % color;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count,
|
||||
const int *counts, int count_count,
|
||||
int width, Color color, Color doxor)
|
||||
{
|
||||
ASSERT(count_count > 0 && vertex_count > 0);
|
||||
if(vertex_count < 2 || IsNull(color))
|
||||
return;
|
||||
DrawingOp(DRAWPOLYPOLYLINE);
|
||||
int version = 2;
|
||||
drawing / version;
|
||||
drawing % width % color % doxor;
|
||||
drawing % vertex_count % count_count;
|
||||
StreamPackPoints(drawing, vertices, vertex_count);
|
||||
StreamPackInts(drawing, counts, count_count);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count,
|
||||
const int *subpolygon_counts, int subpolygon_count_count,
|
||||
const int *disjunct_polygon_counts, int disjunct_polygon_count_count,
|
||||
Color color, int width, Color outline, uint64 pattern, Color doxor)
|
||||
{
|
||||
if(vertex_count == 0)
|
||||
return;
|
||||
DrawingOp(DRAWPOLYPOLYPOLYGON);
|
||||
int version = 2;
|
||||
drawing / version;
|
||||
drawing % color % width % outline % pattern % doxor;
|
||||
drawing % vertex_count % subpolygon_count_count % disjunct_polygon_count_count;
|
||||
StreamPackPoints(drawing, vertices, vertex_count);
|
||||
StreamPackInts(drawing, subpolygon_counts, subpolygon_count_count);
|
||||
StreamPackInts(drawing, disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
|
||||
{
|
||||
DrawingOp(DRAWELLIPSE) % const_cast<Rect&>(r) % color / pen % pencolor;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
|
||||
{
|
||||
DrawingOp(DRAWARC) % const_cast<Rect&>(rc) % start % end % color % width;
|
||||
}
|
||||
|
||||
void DrawingDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink,
|
||||
int n, const int *dx) {
|
||||
if(IsNull(ink)) return;
|
||||
if(n < 0)
|
||||
n = wstrlen((const wchar *)text);
|
||||
if(n == 0)
|
||||
return;
|
||||
Stream& s = DrawingOp(DRAWTEXT);
|
||||
byte cs = CHARSET_UNICODE;
|
||||
s % x % y % angle % font % ink / n % cs;
|
||||
s.PutW((wchar *)text, n);
|
||||
bool dxb = dx;
|
||||
s % dxb;
|
||||
if(dx) {
|
||||
int *w = const_cast<int *>(dx);
|
||||
while(n--)
|
||||
s / *w++;
|
||||
}
|
||||
}
|
||||
|
||||
Drawing DrawingDraw::GetResult()
|
||||
{
|
||||
Drawing out;
|
||||
out.size = size;
|
||||
LLOG("GetResult size: " << size);
|
||||
out.data = drawing.GetResult();
|
||||
out.val = val;
|
||||
return out;
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
|
||||
struct Draw::DrawingPos : StringStream {
|
||||
Size source;
|
||||
Size target;
|
||||
Point srcoff;
|
||||
Point trgoff;
|
||||
Point trgini;
|
||||
Vector<Point16> stack;
|
||||
|
||||
bool Identity() const { return source == target; }
|
||||
|
||||
int GetX(int x) const;
|
||||
int GetY(int y) const;
|
||||
int GetCx(int cx) const;
|
||||
int GetCy(int cy) const;
|
||||
int GetW(int w) const;
|
||||
Point Get(int x, int y) const;
|
||||
Point Get(Point p) const;
|
||||
Rect Get(const Rect& r) const;
|
||||
Rect Get(int x, int y, int cx, int cy) const;
|
||||
|
||||
Point operator()(int x, int y) const { return Get(x, y); }
|
||||
Point operator()(Point p) const { return Get(p); }
|
||||
Rect operator()(const Rect& r) const { return Get(r); }
|
||||
Rect operator()(int x, int y, int cx, int cy) const { return Get(x, y, cx, cy); }
|
||||
|
||||
void TransformX(int& x) const { x = GetX(x); }
|
||||
void TransformY(int& y) const { y = GetY(y); }
|
||||
void TransformW(int& w) const { w = GetW(w); }
|
||||
void Transform(int& x, int& y) const { TransformX(x); TransformY(y); }
|
||||
void Transform(Point& p) const { p = Get(p); }
|
||||
void Transform(Rect& r) const { r = Get(r); }
|
||||
|
||||
Rect GetRect();
|
||||
|
||||
DrawingPos(const String& src) : StringStream(src) {}
|
||||
};
|
||||
|
||||
Rect Draw::DrawingPos::GetRect()
|
||||
{
|
||||
Rect r;
|
||||
*this % r;
|
||||
return Get(r);
|
||||
}
|
||||
|
||||
int Draw::DrawingPos::GetX(int x) const {
|
||||
return iscale(x + srcoff.x, target.cx, source.cx) - trgoff.x;
|
||||
}
|
||||
|
||||
int Draw::DrawingPos::GetY(int y) const {
|
||||
return iscale(y + srcoff.y, target.cy, source.cy) - trgoff.y;
|
||||
}
|
||||
|
||||
int Draw::DrawingPos::GetCx(int cx) const {
|
||||
return iscale(cx, target.cx, source.cx);
|
||||
}
|
||||
|
||||
int Draw::DrawingPos::GetCy(int cy) const {
|
||||
return iscale(cy, target.cy, source.cy);
|
||||
}
|
||||
|
||||
int Draw::DrawingPos::GetW(int w) const {
|
||||
return iscale(w, target.cx + target.cy, source.cx + source.cy);
|
||||
}
|
||||
|
||||
Point Draw::DrawingPos::Get(int x, int y) const {
|
||||
return Point(GetX(x), GetY(y));
|
||||
}
|
||||
|
||||
Point Draw::DrawingPos::Get(Point p) const {
|
||||
return Get(p.x, p.y);
|
||||
}
|
||||
|
||||
Rect Draw::DrawingPos::Get(const Rect& r) const {
|
||||
return Rect(GetX(r.left), GetY(r.top), GetX(r.right), GetY(r.bottom));
|
||||
}
|
||||
|
||||
Rect Draw::DrawingPos::Get(int x, int y, int cx, int cy) const {
|
||||
return Get(RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
void Draw::DrawDrawingOp(const Rect& target, const Drawing& w) {
|
||||
#ifdef _DEBUG
|
||||
int cl = GetCloffLevel();
|
||||
#endif
|
||||
DrawingPos ps(w.data);
|
||||
ps.srcoff = ps.trgoff = Point(0, 0);
|
||||
ps.target = target.Size();
|
||||
ps.source = w.size;
|
||||
LLOG("DrawDrawingOp size: " << w.size);
|
||||
if(ps.target.cx == 0 || ps.target.cy == 0 || ps.source.cx == 0 || ps.source.cy == 0)
|
||||
return;
|
||||
Clipoff(target);
|
||||
ps.trgini = GetOffset();
|
||||
Rect r;
|
||||
int x, y, cx, cy, width, vertex_count, count_count;
|
||||
Color color, pencolor, doxor;
|
||||
Image img;
|
||||
Drawing dw;
|
||||
Painting sw;
|
||||
Point p, p1;
|
||||
int vi = 0;
|
||||
while(!ps.IsEof()) {
|
||||
int code;
|
||||
ps / code;
|
||||
switch(code) {
|
||||
case BEGIN:
|
||||
Begin();
|
||||
ps.stack.Add(ps.srcoff);
|
||||
break;
|
||||
case OFFSET:
|
||||
ps % p;
|
||||
Offset(ps(p));
|
||||
ps.stack.Add(ps.srcoff);
|
||||
ps.srcoff += p;
|
||||
ps.trgoff = GetOffset() - ps.trgini;
|
||||
break;
|
||||
case CLIP:
|
||||
Clip(ps.GetRect());
|
||||
ps.stack.Add(ps.srcoff);
|
||||
break;
|
||||
case CLIPOFF:
|
||||
ps % r;
|
||||
Clipoff(ps(r));
|
||||
ps.stack.Add(ps.srcoff);
|
||||
ps.srcoff += r.TopLeft();
|
||||
ps.trgoff = GetOffset() - ps.trgini;
|
||||
break;
|
||||
case EXCLUDECLIP:
|
||||
ExcludeClip(ps.GetRect());
|
||||
break;
|
||||
case INTERSECTCLIP:
|
||||
IntersectClip(ps.GetRect());
|
||||
break;
|
||||
case END:
|
||||
End();
|
||||
ps.srcoff = ps.stack.Pop();
|
||||
ps.trgoff = GetOffset() - ps.trgini;
|
||||
break;
|
||||
case DRAWRECT:
|
||||
ps % x % y % cx % cy % color;
|
||||
DrawRect(ps(x, y, cx, cy), color);
|
||||
break;
|
||||
case DRAWIMAGE:
|
||||
ps % x % y % cx % cy;
|
||||
if(w.val.GetCount())
|
||||
img = w.val[vi++];
|
||||
else
|
||||
ps % img;
|
||||
ps % r % color;
|
||||
DrawImageOp(ps.GetX(x), ps.GetY(y), ps.GetCx(cx), ps.GetCy(cy), img, r, color);
|
||||
break;
|
||||
case DRAWDATA:
|
||||
{
|
||||
String data, id;
|
||||
ps % x % y % cx % cy % id;
|
||||
if(w.val.GetCount())
|
||||
data = w.val[vi++];
|
||||
else
|
||||
ps % data;
|
||||
DrawData(ps(x, y, cx, cy), data, id);
|
||||
}
|
||||
break;
|
||||
case DRAWDRAWING:
|
||||
if(w.val.GetCount())
|
||||
dw = w.val[vi++];
|
||||
else
|
||||
ps % dw;
|
||||
DrawDrawing(ps.GetRect(), dw);
|
||||
break;
|
||||
case DRAWPAINTING:
|
||||
if(w.val.GetCount())
|
||||
sw = w.val[vi++];
|
||||
else
|
||||
ps % sw;
|
||||
DrawPainting(ps.GetRect(), sw);
|
||||
break;
|
||||
case DRAWLINE:
|
||||
ps % x % y % cx % cy % width % color;
|
||||
DrawLine(ps(x, y), ps(cx, cy), width > 0 ? ps.GetW(width) : width, color);
|
||||
break;
|
||||
case DRAWELLIPSE:
|
||||
r = ps.GetRect();
|
||||
ps % color / width % pencolor;
|
||||
DrawEllipse(r, color, width > 0 ? ps.GetW(width) : width, pencolor);
|
||||
break;
|
||||
#ifndef PLATFORM_WINCE
|
||||
case DRAWARC:
|
||||
r = ps.GetRect();
|
||||
ps % p % p1 % color % width;
|
||||
DrawArc(r, ps(p), ps(p1), width > 0 ? ps.GetW(width) : width, color);
|
||||
break;
|
||||
case DRAWPOLYPOLYLINE:
|
||||
{
|
||||
int version;
|
||||
ps / version;
|
||||
ps % width % color % doxor;
|
||||
ps % vertex_count % count_count;
|
||||
Buffer<Point> vertices(vertex_count);
|
||||
Buffer<int> counts(count_count);
|
||||
StreamUnpackPoints(ps, vertices, vertex_count);
|
||||
StreamUnpackInts(ps, counts, count_count);
|
||||
if(!ps.Identity()) {
|
||||
for(Point *p = vertices, *e = p + vertex_count; p < e; p++)
|
||||
ps.Transform(*p);
|
||||
if(width > 0)
|
||||
ps.TransformW(width);
|
||||
}
|
||||
DrawPolyPolyline(vertices, vertex_count, counts, count_count, width, color, doxor);
|
||||
}
|
||||
break;
|
||||
case DRAWPOLYPOLYPOLYGON:
|
||||
{
|
||||
Color outline;
|
||||
uint64 pattern;
|
||||
int subpolygon_count_count, disjunct_polygon_count_count;
|
||||
int version = 2;
|
||||
ps / version;
|
||||
ps % color % width % outline % pattern % doxor;
|
||||
ps % vertex_count % subpolygon_count_count % disjunct_polygon_count_count;
|
||||
Buffer<Point> vertices(vertex_count);
|
||||
Buffer<int> subpolygon_counts(subpolygon_count_count);
|
||||
Buffer<int> disjunct_polygon_counts(disjunct_polygon_count_count);
|
||||
StreamUnpackPoints(ps, vertices, vertex_count);
|
||||
StreamUnpackInts(ps, subpolygon_counts, subpolygon_count_count);
|
||||
StreamUnpackInts(ps, disjunct_polygon_counts, disjunct_polygon_count_count);
|
||||
if(!ps.Identity()) {
|
||||
for(Point *p = vertices, *e = p + vertex_count; p < e; p++)
|
||||
ps.Transform(*p);
|
||||
ps.TransformW(width);
|
||||
}
|
||||
DrawPolyPolyPolygon(vertices, vertex_count,
|
||||
subpolygon_counts, subpolygon_count_count,
|
||||
disjunct_polygon_counts, disjunct_polygon_count_count,
|
||||
color, width, outline, pattern, doxor);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case DRAWTEXT:
|
||||
{
|
||||
int n, angle;
|
||||
Font font;
|
||||
Color ink;
|
||||
byte cs;
|
||||
ps % x % y % angle % font % ink / n % cs;
|
||||
if(font.GetHeight() == 0) {
|
||||
FontInfo fi = font.Info();
|
||||
font.Height(fi.GetHeight() - fi.GetInternal());
|
||||
}
|
||||
bool unicode = cs == CHARSET_UNICODE;
|
||||
WString text;
|
||||
if(unicode) {
|
||||
Buffer<wchar> txt(n);
|
||||
ps.Stream::GetW(txt, n);
|
||||
text = WString(txt, n);
|
||||
}
|
||||
else {
|
||||
Buffer<char> txt(n);
|
||||
ps.Stream::Get(txt, n);
|
||||
text = ToUnicode(txt, n, cs);
|
||||
}
|
||||
LLOG("wsDrawText \"" << WString(text, n)
|
||||
<< "\" at: (" << x << ", " << y << ", " << angle << ")");
|
||||
bool dxb;
|
||||
ps % dxb;
|
||||
Buffer<int> dx(n);
|
||||
int *wd = dx;
|
||||
int nn = n;
|
||||
angle %= 3600;
|
||||
if(ps.Identity()) {
|
||||
if(dxb) {
|
||||
while(nn--)
|
||||
ps / *wd++;
|
||||
DrawText(x, y, angle, text, font, ink, dx);
|
||||
}
|
||||
else
|
||||
DrawText(x, y, angle, text, font, ink);
|
||||
}
|
||||
else {
|
||||
FontInfo fi = font.Info();
|
||||
const wchar *wp = ~text;
|
||||
int odd = (angle / 900) & 1;
|
||||
if(angle % 900 == 0) {
|
||||
int error = 0;
|
||||
int a, b;
|
||||
if(odd) {
|
||||
a = ps.target.cy;
|
||||
b = ps.source.cy;
|
||||
int ht = ps.GetCx(fi.GetFontHeight());
|
||||
font.Width(ps.GetCy(fi.GetAveWidth())).Height(ht ? ht : 1);
|
||||
FontInfo nf = font.Info();
|
||||
x = angle == 2700 ? ps.GetX(x - fi.GetAscent()) + nf.GetAscent()
|
||||
: ps.GetX(x + fi.GetAscent()) - nf.GetAscent();
|
||||
y = ps.GetY(y);
|
||||
}
|
||||
else {
|
||||
a = ps.target.cx;
|
||||
b = ps.source.cx;
|
||||
int ht = ps.GetCy(fi.GetFontHeight());
|
||||
font.Width(ps.GetCx(fi.GetAveWidth())).Height(ht ? ht : 1);
|
||||
FontInfo nf = font.Info();
|
||||
x = ps.GetX(x);
|
||||
y = angle == 1800 ? ps.GetY(y - fi.GetAscent()) + nf.GetAscent()
|
||||
: ps.GetY(y + fi.GetAscent()) - nf.GetAscent();
|
||||
}
|
||||
while(nn--) {
|
||||
int c;
|
||||
if(dxb)
|
||||
ps / c;
|
||||
else
|
||||
c = fi[*wp++];
|
||||
*wd++ = (c * a + error) / b;
|
||||
error = (c * a + error) % b;
|
||||
}
|
||||
DrawText(x, y, angle, text, font, ink, dx);
|
||||
}
|
||||
else {
|
||||
double ang = (double) (angle % 900) * M_2PI / 3600;
|
||||
double sx = (double) ps.target.cx / ps.source.cx;
|
||||
double sy = (double) ps.target.cy / ps.source.cy;
|
||||
double ang2 = atan((odd ? sx / sy : sy / sx) * tan(ang));
|
||||
double q = (odd ? sx : sy) * sin(ang) / sin(ang2);
|
||||
double error = 0;
|
||||
while(nn--) {
|
||||
int cx;
|
||||
if(dxb)
|
||||
ps / cx;
|
||||
else
|
||||
cx = fi[*wp++];
|
||||
double ncx = q * cx + error;
|
||||
*wd++ = cx = (int) ncx;
|
||||
error = ncx - cx;
|
||||
}
|
||||
int ht = (int)(fi.GetFontHeight() * (sx * sin(ang) * sin(ang2) + sy * cos(ang) * cos(ang2)));
|
||||
font.Width(int(q * fi.GetAveWidth())).Height(ht ? ht : 1);
|
||||
DrawText(ps.GetX(x), ps.GetY(y), int(ang2 * 3600 / M_2PI) + (angle / 900) * 900,
|
||||
text, font, ink, dx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// LOGEND();
|
||||
End();
|
||||
#ifdef _DEBUG
|
||||
ASSERT(GetCloffLevel() == cl);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Draw::DrawDrawing(int x, int y, int cx, int cy, const Drawing& w) {
|
||||
DrawDrawing(RectC(x, y, cx, cy), w);
|
||||
}
|
||||
|
||||
void DrawingDraw::Create(int cx, int cy) {
|
||||
Create(Size(cx, cy));
|
||||
}
|
||||
|
||||
void DrawingDraw::Create(Size sz) {
|
||||
drawing.Create();
|
||||
size = sz;
|
||||
#ifdef PLATFORM_WIN32
|
||||
cloff.Clear();
|
||||
#endif
|
||||
#ifdef PLATFORM_X11
|
||||
cloff.Clear();
|
||||
clip.Clear();
|
||||
Vector<Rect> cliplist;
|
||||
cliplist.Add(RectC(0, 0, sz.cx, sz.cy));
|
||||
Init(cliplist);
|
||||
#endif
|
||||
drawingclip = Rect(0, 0, sz.cx, sz.cy);
|
||||
pixels = false;
|
||||
LLOG("DrawingDraw::Create, sz = " << sz << " -> clip = " << GetClip());
|
||||
}
|
||||
|
||||
void DrawingDraw::DInit()
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
Attach(ScreenHDC());
|
||||
#endif
|
||||
#ifdef PLATFORM_X11
|
||||
gc = XCreateGC(Xdisplay, RootWindow(Xdisplay, Xscreenno), 0, 0);
|
||||
dw = RootWindow(Xdisplay, Xscreenno);
|
||||
#endif
|
||||
pixels = false;
|
||||
backdraw = true;
|
||||
LLOG("DrawingDraw::DInit: pixels = " << Pixels());
|
||||
}
|
||||
|
||||
DrawingDraw::DrawingDraw()
|
||||
{
|
||||
DInit();
|
||||
}
|
||||
|
||||
DrawingDraw::DrawingDraw(Size sz) {
|
||||
DInit();
|
||||
Create(sz);
|
||||
}
|
||||
|
||||
DrawingDraw::DrawingDraw(int cx, int cy) {
|
||||
DInit();
|
||||
Create(cx, cy);
|
||||
}
|
||||
|
||||
DrawingDraw::~DrawingDraw() {
|
||||
#ifdef PLATFORM_X11
|
||||
XFreeGC(Xdisplay, gc);
|
||||
#endif
|
||||
}
|
||||
|
||||
Size Drawing::RatioSize(int cx, int cy) const {
|
||||
return GetRatioSize(GetSize(), cx, cy);
|
||||
}
|
||||
|
||||
void Drawing::Append(Drawing& dw)
|
||||
{
|
||||
if(IsNull(size))
|
||||
size = dw.size;
|
||||
data << dw.data;
|
||||
for(int i = 0; i < dw.val.GetCount(); i++)
|
||||
val.Add(dw.val[i]);
|
||||
}
|
||||
|
||||
Drawing::Drawing(const Value& src)
|
||||
{
|
||||
if(IsNull(src))
|
||||
size = Null;
|
||||
else
|
||||
*this = RichValue<Drawing>::Extract(src);
|
||||
}
|
||||
|
||||
void Drawing::Serialize(Stream& s)
|
||||
{
|
||||
if(val.GetCount())
|
||||
size.cy |= 0x80000000;
|
||||
s % size;
|
||||
s % data;
|
||||
if(size.cy & 0x80000000) {
|
||||
size.cy &= ~0x80000000;
|
||||
s % val;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifndef PLATFORM_WINCE
|
||||
Drawing Drawing::FromWMF(const WinMetaFile& wmf) {
|
||||
if(!wmf) return Drawing();
|
||||
Size sz = wmf.GetSize();
|
||||
DrawingDraw dd(sz);
|
||||
wmf.Paint(dd, 0, 0, sz.cx, sz.cy);
|
||||
return dd;
|
||||
}
|
||||
|
||||
Drawing Drawing::LoadWMF(const char *file) {
|
||||
return FromWMF(WinMetaFile(file));
|
||||
}
|
||||
|
||||
Drawing Drawing::ReadClipboardWMF() {
|
||||
WinMetaFile wmf;
|
||||
wmf.ReadClipboard();
|
||||
return FromWMF(wmf);
|
||||
}
|
||||
|
||||
WinMetaFile Drawing::AsWMF() const {
|
||||
Size sz = GetSize();
|
||||
WinMetaFileDraw wd(sz.cx, sz.cy);
|
||||
wd.DrawDrawing(0, 0, sz.cx, sz.cy, *this);
|
||||
return wd.Close();
|
||||
}
|
||||
|
||||
void Drawing::WriteClipboardWMF() const {
|
||||
WinMetaFile wmf = AsWMF();
|
||||
wmf.WriteClipboard();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
702
archive/olddraw/Draw/Image.cpp
Normal file
702
archive/olddraw/Draw/Image.cpp
Normal file
|
|
@ -0,0 +1,702 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
int ImageBuffer::ScanKind() const
|
||||
{
|
||||
bool a255 = false;
|
||||
bool a0 = false;
|
||||
const RGBA *s = pixels;
|
||||
const RGBA *e = s + GetLength();
|
||||
while(s < e) {
|
||||
if(s->a == 0)
|
||||
a0 = true;
|
||||
else
|
||||
if(s->a == 255)
|
||||
a255 = true;
|
||||
else
|
||||
return IMAGE_ALPHA;
|
||||
s++;
|
||||
}
|
||||
return a255 ? a0 ? IMAGE_MASK : IMAGE_OPAQUE : IMAGE_EMPTY;
|
||||
}
|
||||
|
||||
void ImageBuffer::Create(int cx, int cy)
|
||||
{
|
||||
ASSERT(cx >= 0 && cy >= 0);
|
||||
size.cx = cx;
|
||||
size.cy = cy;
|
||||
pixels.Alloc(GetLength());
|
||||
#ifdef _DEBUG
|
||||
RGBA *s = pixels;
|
||||
RGBA *e = pixels + GetLength();
|
||||
byte a = 0;
|
||||
while(s < e) {
|
||||
s->a = a;
|
||||
a = ~a;
|
||||
s->r = 255;
|
||||
s->g = s->b = 0;
|
||||
s++;
|
||||
}
|
||||
#endif
|
||||
kind = IMAGE_UNKNOWN;
|
||||
spot2 = hotspot = Point(0, 0);
|
||||
dots = Size(0, 0);
|
||||
}
|
||||
|
||||
void ImageBuffer::DeepCopy(const ImageBuffer& img)
|
||||
{
|
||||
Create(img.GetSize());
|
||||
SetHotSpot(img.GetHotSpot());
|
||||
Set2ndSpot(img.Get2ndSpot());
|
||||
SetDots(img.GetDots());
|
||||
memcpy(pixels, img.pixels, GetLength() * sizeof(RGBA));
|
||||
}
|
||||
|
||||
void ImageBuffer::Set(Image& img)
|
||||
{
|
||||
if(img.data)
|
||||
if(img.data->refcount == 1) {
|
||||
size = img.GetSize();
|
||||
kind = IMAGE_UNKNOWN;
|
||||
hotspot = img.GetHotSpot();
|
||||
spot2 = img.Get2ndSpot();
|
||||
dots = img.GetDots();
|
||||
pixels = img.data->buffer.pixels;
|
||||
img.Clear();
|
||||
}
|
||||
else {
|
||||
DeepCopy(img.data->buffer);
|
||||
kind = IMAGE_UNKNOWN;
|
||||
img.Clear();
|
||||
}
|
||||
else
|
||||
Create(0, 0);
|
||||
}
|
||||
|
||||
|
||||
void ImageBuffer::operator=(Image& img)
|
||||
{
|
||||
Clear();
|
||||
Set(img);
|
||||
}
|
||||
|
||||
void ImageBuffer::operator=(ImageBuffer& img)
|
||||
{
|
||||
Clear();
|
||||
Image m = img;
|
||||
Set(m);
|
||||
}
|
||||
|
||||
ImageBuffer::ImageBuffer(Image& img)
|
||||
{
|
||||
Set(img);
|
||||
}
|
||||
|
||||
ImageBuffer::ImageBuffer(ImageDraw& w)
|
||||
{
|
||||
Image img = w;
|
||||
Set(img);
|
||||
}
|
||||
|
||||
ImageBuffer::ImageBuffer(ImageBuffer& b)
|
||||
{
|
||||
kind = b.kind;
|
||||
size = b.size;
|
||||
dots = b.dots;
|
||||
pixels = b.pixels;
|
||||
hotspot = b.hotspot;
|
||||
spot2 = b.spot2;
|
||||
}
|
||||
|
||||
void Image::Set(ImageBuffer& b)
|
||||
{
|
||||
if(b.GetWidth() == 0 || b.GetHeight() == 0)
|
||||
data = NULL;
|
||||
else
|
||||
data = new Data(b);
|
||||
}
|
||||
|
||||
void Image::Clear()
|
||||
{
|
||||
if(data)
|
||||
data->Release();
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
Image& Image::operator=(ImageBuffer& img)
|
||||
{
|
||||
if(data)
|
||||
data->Release();
|
||||
Set(img);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Image& Image::operator=(const Image& img)
|
||||
{
|
||||
Data *d = data;
|
||||
data = img.data;
|
||||
if(data)
|
||||
data->Retain();
|
||||
if(d)
|
||||
d->Release();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const RGBA* Image::operator~() const
|
||||
{
|
||||
return data ? ~data->buffer : NULL;
|
||||
}
|
||||
|
||||
Image::operator const RGBA*() const
|
||||
{
|
||||
return data ? ~data->buffer : NULL;
|
||||
}
|
||||
|
||||
const RGBA* Image::operator[](int i) const
|
||||
{
|
||||
ASSERT(data);
|
||||
return data->buffer[i];
|
||||
}
|
||||
|
||||
Size Image::GetSize() const
|
||||
{
|
||||
return data ? data->buffer.GetSize() : Size(0, 0);
|
||||
}
|
||||
|
||||
int Image::GetLength() const
|
||||
{
|
||||
return data ? data->buffer.GetLength() : 0;
|
||||
}
|
||||
|
||||
Point Image::GetHotSpot() const
|
||||
{
|
||||
return data ? data->buffer.GetHotSpot() : Point(0, 0);
|
||||
}
|
||||
|
||||
Point Image::Get2ndSpot() const
|
||||
{
|
||||
return data ? data->buffer.Get2ndSpot() : Point(0, 0);
|
||||
}
|
||||
|
||||
Size Image::GetDots() const
|
||||
{
|
||||
return data ? data->buffer.GetDots() : Size(0, 0);
|
||||
}
|
||||
|
||||
int Image::GetKindNoScan() const
|
||||
{
|
||||
return data ? data->buffer.GetKind() : IMAGE_EMPTY;
|
||||
}
|
||||
|
||||
int Image::Data::GetKind()
|
||||
{
|
||||
int k = buffer.GetKind();
|
||||
if(k != IMAGE_UNKNOWN)
|
||||
return k;
|
||||
k = buffer.ScanKind();
|
||||
buffer.SetKind(k);
|
||||
return k;
|
||||
}
|
||||
|
||||
int Image::GetKind() const
|
||||
{
|
||||
return data ? data->GetKind() : IMAGE_EMPTY;
|
||||
}
|
||||
|
||||
void Image::PaintImage(Draw& w, int x, int y, const Rect& src, Color c) const
|
||||
{
|
||||
if(data)
|
||||
data->Paint(w, x, y, src, c);
|
||||
}
|
||||
|
||||
void Image::Serialize(Stream& s)
|
||||
{
|
||||
int version = 0;
|
||||
s / version;
|
||||
Size sz = GetSize();
|
||||
Point p = GetHotSpot();
|
||||
Size dots = GetDots();
|
||||
s % sz % p % dots;
|
||||
int len = sz.cx * sz.cy;
|
||||
if(s.IsLoading())
|
||||
if(len) {
|
||||
ImageBuffer b(sz);
|
||||
if(!s.GetAll(~b, len * sizeof(RGBA)))
|
||||
s.SetError();
|
||||
b.SetDots(dots);
|
||||
b.SetHotSpot(p);
|
||||
*this = b;
|
||||
}
|
||||
else
|
||||
Clear();
|
||||
else
|
||||
s.Put(~*this, len * sizeof(RGBA));
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
RichValue<Image>::Register();
|
||||
}
|
||||
|
||||
bool Image::operator==(const Image& img) const
|
||||
{
|
||||
if(GetLength() != img.GetLength())
|
||||
return false;
|
||||
return memcmp(~*this, ~img, GetLength() * sizeof(RGBA)) == 0;
|
||||
}
|
||||
|
||||
bool Image::operator!=(const Image& img) const
|
||||
{
|
||||
return !operator==(img);
|
||||
}
|
||||
|
||||
dword Image::GetHashValue() const
|
||||
{
|
||||
return memhash(~*this, GetLength() * sizeof(RGBA));
|
||||
}
|
||||
|
||||
Image::Image(const Image& img)
|
||||
{
|
||||
data = img.data;
|
||||
if(data)
|
||||
data->Retain();
|
||||
}
|
||||
|
||||
Image::Image(Image (*fn)())
|
||||
{
|
||||
data = NULL;
|
||||
*this = (*fn)();
|
||||
}
|
||||
|
||||
Image::Image(const Value& src)
|
||||
{
|
||||
data = NULL;
|
||||
if(!IsNull(src))
|
||||
*this = RawValue<Image>::Extract(src);
|
||||
}
|
||||
|
||||
Image::Image(ImageBuffer& b)
|
||||
{
|
||||
Set(b);
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if(data)
|
||||
data->Release();
|
||||
}
|
||||
|
||||
Image::Image(const Init& init)
|
||||
{
|
||||
ASSERT(init.info[0] >= 1);
|
||||
Size sz;
|
||||
sz.cx = Peek32le(init.info + 1);
|
||||
sz.cy = Peek32le(init.info + 5);
|
||||
ImageBuffer b(sz);
|
||||
int i = 0;
|
||||
while(i < init.scan_count) {
|
||||
UnpackRLE(b[i], (const byte *)init.scans[i], sz.cx);
|
||||
i++;
|
||||
}
|
||||
while(i < sz.cy)
|
||||
memset(b[i++], 0, sizeof(RGBA) * sz.cx);
|
||||
b.SetHotSpot(Point(Peek32le(init.info + 9), Peek32le(init.info + 13)));
|
||||
Set(b);
|
||||
}
|
||||
|
||||
String Image::ToString() const
|
||||
{
|
||||
return String("Image ").Cat() << GetSize();
|
||||
}
|
||||
|
||||
Link<Image::Data> Image::Data::ResData[1];
|
||||
int Image::Data::ResCount;
|
||||
|
||||
Image::Data::Data(ImageBuffer& b)
|
||||
: buffer(b)
|
||||
{
|
||||
paintcount = 0;
|
||||
paintonly = false;
|
||||
refcount = 1;
|
||||
INTERLOCKED {
|
||||
static int64 gserial;
|
||||
serial = ++gserial;
|
||||
}
|
||||
SysInit();
|
||||
}
|
||||
|
||||
Image::Data::~Data()
|
||||
{
|
||||
DrawLock __;
|
||||
SysRelease();
|
||||
Unlink();
|
||||
}
|
||||
|
||||
void Image::Data::PaintOnlyShrink()
|
||||
{
|
||||
if(paintonly) {
|
||||
LTIMING("PaintOnlyShrink");
|
||||
DrawLock __;
|
||||
DropPixels___(buffer);
|
||||
ResCount -= GetResCount();
|
||||
Unlink();
|
||||
}
|
||||
}
|
||||
|
||||
Draw& ImageDraw::Alpha()
|
||||
{
|
||||
if(!has_alpha) {
|
||||
alpha.DrawRect(size, GrayColor(0));
|
||||
has_alpha = true;
|
||||
}
|
||||
return alpha;
|
||||
}
|
||||
|
||||
static void sMultiply(ImageBuffer& b, int (*op)(RGBA *t, const RGBA *s, int len))
|
||||
{
|
||||
if(b.GetKind() != IMAGE_OPAQUE && b.GetKind() != IMAGE_EMPTY)
|
||||
(*op)(~b, ~b, b.GetLength());
|
||||
}
|
||||
|
||||
void Premultiply(ImageBuffer& b)
|
||||
{
|
||||
sMultiply(b, Premultiply);
|
||||
}
|
||||
|
||||
void Unmultiply(ImageBuffer& b)
|
||||
{
|
||||
sMultiply(b, Unmultiply);
|
||||
}
|
||||
|
||||
static Image sMultiply(const Image& img, int (*op)(RGBA *t, const RGBA *s, int len))
|
||||
{
|
||||
int k = img.GetKind();
|
||||
if(k == IMAGE_OPAQUE || k == IMAGE_EMPTY)
|
||||
return img;
|
||||
ImageBuffer ib(img.GetSize());
|
||||
ib.SetHotSpot(img.GetHotSpot());
|
||||
ib.Set2ndSpot(img.Get2ndSpot());
|
||||
ib.SetKind(Premultiply(~ib, ~img, ib.GetLength()));
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image Premultiply(const Image& img)
|
||||
{
|
||||
return sMultiply(img, Premultiply);
|
||||
}
|
||||
|
||||
Image Unmultiply(const Image& img)
|
||||
{
|
||||
return sMultiply(img, Unmultiply);
|
||||
}
|
||||
|
||||
void SetPaintOnly___(Image& m)
|
||||
{
|
||||
if(m.data && m.data->refcount == 1)
|
||||
m.data->paintonly = true;
|
||||
}
|
||||
|
||||
void Iml::Init(int n)
|
||||
{
|
||||
for(int i = 0; i < n; i++)
|
||||
map.Add(name[i]);
|
||||
}
|
||||
|
||||
void Iml::Reset()
|
||||
{
|
||||
int n = map.GetCount();
|
||||
map.Clear();
|
||||
Init(n);
|
||||
}
|
||||
|
||||
void Iml::Set(int i, const Image& img)
|
||||
{
|
||||
map[i].image = img;
|
||||
map[i].loaded = true;
|
||||
}
|
||||
|
||||
static StaticCriticalSection sImgImlLock;
|
||||
|
||||
Image Iml::Get(int i)
|
||||
{
|
||||
IImage& m = map[i];
|
||||
if(!m.loaded) {
|
||||
INTERLOCKED_(sImgImlLock) {
|
||||
if(data.GetCount()) {
|
||||
int ii = 0;
|
||||
for(;;) {
|
||||
const Data& d = data[ii];
|
||||
if(i < d.count) {
|
||||
static const char *cached_data;
|
||||
static Vector<Image> cached;
|
||||
if(cached_data != d.data) {
|
||||
cached_data = d.data;
|
||||
cached = UnpackImlData(String(d.data, d.len));
|
||||
if(premultiply)
|
||||
for(int i = 0; i < cached.GetCount(); i++)
|
||||
cached[i] = Premultiply(cached[i]);
|
||||
}
|
||||
m.image = cached[i];
|
||||
break;
|
||||
}
|
||||
i -= d.count;
|
||||
ii++;
|
||||
}
|
||||
}
|
||||
else
|
||||
m.image = Premultiply(Image(img_init[i]));
|
||||
}
|
||||
m.loaded = true;
|
||||
}
|
||||
return m.image;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
int Iml::GetBinSize() const
|
||||
{
|
||||
int size = 0;
|
||||
for(int i = 0; i < map.GetCount(); i++) {
|
||||
const Image::Init& init = img_init[i];
|
||||
size += (int)strlen(name[i]) + 1 + 24;
|
||||
for(int q = 0; q < init.scan_count; q++)
|
||||
size += (int)strlen(init.scans[q]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
Iml::Iml(const Image::Init *img_init, const char **name, int n)
|
||||
: img_init(img_init),
|
||||
name(name)
|
||||
{
|
||||
#ifdef flagCHECKINIT
|
||||
RLOG("Constructing iml " << *name);
|
||||
#endif
|
||||
premultiply = true;
|
||||
Init(n);
|
||||
}
|
||||
|
||||
void Iml::AddData(const byte *_data, int len, int count)
|
||||
{
|
||||
Data& d = data.Add();
|
||||
d.data = (const char *)_data;
|
||||
d.len = len;
|
||||
d.count = count;
|
||||
data.Shrink();
|
||||
}
|
||||
|
||||
static StaticCriticalSection sImgMapLock;
|
||||
|
||||
static VectorMap<String, Iml *>& sImgMap()
|
||||
{
|
||||
static VectorMap<String, Iml *> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void Register(const char *imageclass, Iml& list)
|
||||
{
|
||||
#ifdef flagCHECKINIT
|
||||
RLOG("Registering iml " << imageclass);
|
||||
#endif
|
||||
INTERLOCKED_(sImgMapLock)
|
||||
sImgMap().GetAdd(imageclass) = &list;
|
||||
}
|
||||
|
||||
int GetImlCount()
|
||||
{
|
||||
int q;
|
||||
INTERLOCKED_(sImgMapLock)
|
||||
q = sImgMap().GetCount();
|
||||
return q;
|
||||
}
|
||||
|
||||
Iml& GetIml(int i)
|
||||
{
|
||||
return *sImgMap()[i];
|
||||
}
|
||||
|
||||
void Iml::Enter()
|
||||
{
|
||||
sImgMapLock.Enter();
|
||||
}
|
||||
|
||||
void Iml::Leave()
|
||||
{
|
||||
sImgMapLock.Leave();
|
||||
}
|
||||
|
||||
String GetImlName(int i)
|
||||
{
|
||||
String x;
|
||||
INTERLOCKED_(sImgMapLock)
|
||||
x = sImgMap().GetKey(i);
|
||||
return x;
|
||||
}
|
||||
|
||||
int FindIml(const char *name)
|
||||
{
|
||||
int q;
|
||||
INTERLOCKED_(sImgMapLock)
|
||||
q = sImgMap().Find(name);
|
||||
return q;
|
||||
}
|
||||
|
||||
Image GetImlImage(const char *name)
|
||||
{
|
||||
Image m;
|
||||
const char *w = strchr(name, ':');
|
||||
if(w) {
|
||||
int q = FindIml(String(name, w));
|
||||
if(q >= 0) {
|
||||
INTERLOCKED_(sImgMapLock) {
|
||||
Iml& iml = *sImgMap()[q];
|
||||
while(*w == ':')
|
||||
w++;
|
||||
q = iml.Find(w);
|
||||
if(q >= 0)
|
||||
m = iml.Get(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void SetImlImage(const char *name, const Image& m)
|
||||
{
|
||||
const char *w = strchr(name, ':');
|
||||
if(w) {
|
||||
int q = FindIml(String(name, w));
|
||||
if(q >= 0) {
|
||||
INTERLOCKED_(sImgMapLock) {
|
||||
Iml& iml = *sImgMap()[q];
|
||||
while(*w == ':')
|
||||
w++;
|
||||
q = iml.Find(w);
|
||||
if(q >= 0)
|
||||
iml.Set(q, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String StoreImageAsString(const Image& img)
|
||||
{
|
||||
if(img.GetKind() == IMAGE_EMPTY)
|
||||
return Null;
|
||||
int type = img.GetKind() == IMAGE_OPAQUE ? 3 : 4;
|
||||
StringStream ss;
|
||||
ss.Put(type);
|
||||
Size sz = img.GetSize();
|
||||
ss.Put16le(sz.cx);
|
||||
ss.Put16le(sz.cy);
|
||||
Point p = img.GetHotSpot();
|
||||
ss.Put16le(p.x);
|
||||
ss.Put16le(p.y);
|
||||
Size dots = img.GetDots();
|
||||
ss.Put16le(dots.cx);
|
||||
ss.Put16le(dots.cy);
|
||||
const RGBA *s = img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
Buffer<byte> b(type * img.GetLength());
|
||||
byte *t = b;
|
||||
if(type == 3)
|
||||
while(s < e) {
|
||||
*t++ = s->r;
|
||||
*t++ = s->g;
|
||||
*t++ = s->b;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
while(s < e) {
|
||||
*t++ = s->r;
|
||||
*t++ = s->g;
|
||||
*t++ = s->b;
|
||||
*t++ = s->a;
|
||||
s++;
|
||||
}
|
||||
MemReadStream m(b, type * img.GetLength());
|
||||
ZCompress(ss, m);
|
||||
return ss;
|
||||
}
|
||||
|
||||
Image LoadImageFromString(const String& src)
|
||||
{
|
||||
if(src.GetLength() < 13)
|
||||
return Null;
|
||||
StringStream ss(src);
|
||||
int type = ss.Get();
|
||||
Size sz;
|
||||
sz.cx = ss.Get16le();
|
||||
sz.cy = ss.Get16le();
|
||||
if(sz.cx < 0 || sz.cy < 0)
|
||||
return Null;
|
||||
Point p;
|
||||
p.x = ss.Get16le();
|
||||
p.y = ss.Get16le();
|
||||
if(p.x < 0 || p.y < 0)
|
||||
return Null;
|
||||
Size dots;
|
||||
dots.cx = ss.Get16le();
|
||||
dots.cy = ss.Get16le();
|
||||
if(dots.cx < 0 || dots.cy < 0)
|
||||
return Null;
|
||||
StringStream out;
|
||||
ZDecompress(out, ss);
|
||||
String data = out;
|
||||
if(data.GetLength() != type * sz.cx * sz.cy)
|
||||
return Image();
|
||||
ImageBuffer ib(sz);
|
||||
ib.SetHotSpot(p);
|
||||
ib.SetDots(dots);
|
||||
RGBA *t = ib;
|
||||
const RGBA *e = t + ib.GetLength();
|
||||
const byte *s = data;
|
||||
if(type == 3)
|
||||
while(t < e) {
|
||||
t->r = *s++;
|
||||
t->g = *s++;
|
||||
t->b = *s++;
|
||||
t->a = 255;
|
||||
t++;
|
||||
}
|
||||
else
|
||||
if(type == 4)
|
||||
while(t < e) {
|
||||
t->r = *s++;
|
||||
t->g = *s++;
|
||||
t->b = *s++;
|
||||
t->a = *s++;
|
||||
t++;
|
||||
}
|
||||
else
|
||||
return Image();
|
||||
return ib;
|
||||
}
|
||||
|
||||
Size GetImageStringSize(const String& src)
|
||||
{
|
||||
if(src.GetLength() < 13)
|
||||
return Size(0, 0);
|
||||
StringStream ss(src);
|
||||
ss.Get();
|
||||
Size sz;
|
||||
sz.cx = ss.Get16le();
|
||||
sz.cy = ss.Get16le();
|
||||
return sz;
|
||||
}
|
||||
|
||||
Size GetImageStringDots(const String& src)
|
||||
{
|
||||
if(src.GetLength() < 13)
|
||||
return Size(0, 0);
|
||||
StringStream ss(src);
|
||||
ss.SeekCur(9);
|
||||
Size sz;
|
||||
sz.cx = ss.Get16le();
|
||||
sz.cy = ss.Get16le();
|
||||
return sz;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
342
archive/olddraw/Draw/Image.h
Normal file
342
archive/olddraw/Draw/Image.h
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
#define NEWIMAGE
|
||||
|
||||
enum ImageKind {
|
||||
IMAGE_UNKNOWN,
|
||||
IMAGE_EMPTY,
|
||||
IMAGE_ALPHA,
|
||||
IMAGE_MASK,
|
||||
IMAGE_OPAQUE,
|
||||
};
|
||||
|
||||
inline bool operator==(const RGBA& a, const RGBA& b)
|
||||
{
|
||||
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
|
||||
}
|
||||
|
||||
inline bool operator!=(const RGBA& a, const RGBA& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline RGBA RGBAZero() { RGBA c; c.r = c.g = c.b = c.a = 0; return c; }
|
||||
|
||||
void Fill(RGBA *t, const RGBA& src, int n);
|
||||
void FillColor(RGBA *t, const RGBA& src, int n);
|
||||
|
||||
void Copy(RGBA *t, const RGBA *s, int n);
|
||||
|
||||
int Premultiply(RGBA *t, const RGBA *s, int len);
|
||||
int Unmultiply(RGBA *t, const RGBA *s, int len);
|
||||
|
||||
void AlphaBlend(RGBA *t, const RGBA *s, int len);
|
||||
void AlphaBlend(RGBA *t, const RGBA *s, int len, Color color);
|
||||
|
||||
void AlphaBlendOpaque(RGBA *t, const RGBA *s, int len, Color color);
|
||||
void AlphaBlendOpaque(RGBA *t, const RGBA *s, int len);
|
||||
|
||||
void AlphaBlendStraight(RGBA *b, const RGBA *f, int len);
|
||||
void AlphaBlendStraight(RGBA *b, const RGBA *f, int len, Color color);
|
||||
void AlphaBlendStraightOpaque(RGBA *t, const RGBA *s, int len);
|
||||
void AlphaBlendStraightOpaque(RGBA *t, const RGBA *s, int len, int alpha);
|
||||
|
||||
int GetChMaskPos32(dword mask);
|
||||
void AlphaBlendOverBgST(RGBA *b, RGBA bg, int len);
|
||||
|
||||
const byte *UnpackRLE(RGBA *t, const byte *src, int len);
|
||||
String PackRLE(const RGBA *s, int len);
|
||||
|
||||
inline int Grayscale(int r, int g, int b) { return (77 * r + 151 * g + 28 * b) >> 8; }
|
||||
inline int Grayscale(const RGBA& c) { return Grayscale(c.r, c.g, c.b); }
|
||||
inline byte Saturate255(int x) { return byte(~(x >> 24) & (x | (-(x >> 8) >> 24)) & 0xff); }
|
||||
|
||||
class Image;
|
||||
class ImageDraw;
|
||||
|
||||
class ImageBuffer : NoCopy {
|
||||
mutable int kind;
|
||||
Size size;
|
||||
Buffer<RGBA> pixels;
|
||||
Point hotspot;
|
||||
Point spot2;
|
||||
Size dots;
|
||||
|
||||
void Set(Image& img);
|
||||
void DeepCopy(const ImageBuffer& img);
|
||||
|
||||
RGBA* Line(int i) const { ASSERT(i >= 0 && i < size.cy); return (RGBA *)~pixels + i * size.cx; }
|
||||
friend void DropPixels___(ImageBuffer& b) { b.pixels.Clear(); }
|
||||
|
||||
friend class Image;
|
||||
|
||||
public:
|
||||
void SetKind(int k) { kind = k; }
|
||||
int GetKind() const { return kind; }
|
||||
int ScanKind() const;
|
||||
int GetScanKind() const { return kind == IMAGE_UNKNOWN ? ScanKind() : kind; }
|
||||
|
||||
void SetHotSpot(Point p) { hotspot = p; }
|
||||
Point GetHotSpot() const { return hotspot; }
|
||||
|
||||
void Set2ndSpot(Point p) { spot2 = p; }
|
||||
Point Get2ndSpot() const { return spot2; }
|
||||
|
||||
void SetDots(Size sz) { dots = sz; }
|
||||
Size GetDots() const { return dots; }
|
||||
|
||||
Size GetSize() const { return size; }
|
||||
int GetWidth() const { return size.cx; }
|
||||
int GetHeight() const { return size.cy; }
|
||||
int GetLength() const { return size.cx * size.cy; }
|
||||
|
||||
RGBA *operator[](int i) { return Line(i); }
|
||||
const RGBA *operator[](int i) const { return Line(i); }
|
||||
RGBA *operator~() { return pixels; }
|
||||
operator RGBA*() { return pixels; }
|
||||
const RGBA *operator~() const { return pixels; }
|
||||
operator const RGBA*() const { return pixels; }
|
||||
|
||||
void Create(int cx, int cy);
|
||||
void Create(Size sz) { Create(sz.cx, sz.cy); }
|
||||
bool IsEmpty() const { return (size.cx | size.cy) == 0; }
|
||||
void Clear() { Create(0, 0); }
|
||||
|
||||
void operator=(Image& img);
|
||||
void operator=(ImageBuffer& img);
|
||||
|
||||
ImageBuffer() { Create(0, 0); }
|
||||
ImageBuffer(int cx, int cy) { Create(cx, cy); }
|
||||
ImageBuffer(Size sz) { Create(sz.cx, sz.cy); }
|
||||
ImageBuffer(Image& img);
|
||||
ImageBuffer(ImageDraw& w);
|
||||
ImageBuffer(ImageBuffer& b);
|
||||
};
|
||||
|
||||
void Premultiply(ImageBuffer& b);
|
||||
void Unmultiply(ImageBuffer& b);
|
||||
|
||||
void SetSurface(Draw& w, int x, int y, int cx, int cy, const RGBA *pixels);
|
||||
|
||||
class Image : public AssignValueTypeNo< Image, 150, Moveable<Image> > {
|
||||
private:
|
||||
struct Data : Link<Data> {
|
||||
Atomic refcount;
|
||||
int64 serial;
|
||||
int paintcount;
|
||||
|
||||
static Link<Data> ResData[1];
|
||||
static int ResCount;
|
||||
|
||||
void Retain() { AtomicInc(refcount); }
|
||||
void Release() { if(AtomicDec(refcount) == 0) delete this; }
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
LPCSTR cursor_cheat;
|
||||
HBITMAP hbmp;
|
||||
HBITMAP hmask;
|
||||
HBITMAP himg;
|
||||
RGBA *section;
|
||||
|
||||
void CreateHBMP(HDC dc, const RGBA *data);
|
||||
int GetResCount() const { return !!hbmp + !!hmask + !!himg; }
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
int cursor_cheat;
|
||||
XPicture picture;
|
||||
XPicture picture8;
|
||||
int GetResCount() const { return !!picture; }
|
||||
#endif
|
||||
|
||||
ImageBuffer buffer;
|
||||
bool paintonly;
|
||||
|
||||
void SysInit();
|
||||
void SysRelease();
|
||||
int GetKind();
|
||||
void Paint(Draw& w, int x, int y, const Rect& src, Color c);
|
||||
void PaintOnlyShrink();
|
||||
|
||||
Data(ImageBuffer& b);
|
||||
~Data();
|
||||
};
|
||||
|
||||
Data *data;
|
||||
|
||||
static Link<Image::Data> ResData[1];
|
||||
static int ResCount;
|
||||
|
||||
void Set(ImageBuffer& b);
|
||||
|
||||
friend class ImageBuffer;
|
||||
friend struct Data;
|
||||
|
||||
friend class Draw;
|
||||
|
||||
void PaintImage(Draw& w, int x, int y, const Rect& src, Color c) const;
|
||||
|
||||
friend void SetPaintOnly___(Image& m);
|
||||
friend void DrawImageBandRLE(Draw& w, int x, int y, const Image& m, int minp);
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifndef PLATFORM_WINCE
|
||||
void SetCursorCheat(LPCSTR id) { data->cursor_cheat = id; }
|
||||
LPCSTR GetCursorCheat() const { return data ? data->cursor_cheat : NULL; }
|
||||
friend Image Win32IconCursor(LPCSTR id, int iconsize, bool cursor);
|
||||
friend HICON IconWin32(const Image& img, bool cursor);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
void SetCursorCheat(int id) { data->cursor_cheat = id; }
|
||||
int GetCursorCheat() const { return data ? data->cursor_cheat : -1; }
|
||||
friend Cursor X11Cursor(const Image&);
|
||||
friend Image sX11Cursor__(int c);
|
||||
#endif
|
||||
|
||||
public:
|
||||
const RGBA* operator~() const;
|
||||
operator const RGBA*() const;
|
||||
const RGBA* operator[](int i) const;
|
||||
|
||||
Size GetSize() const;
|
||||
int GetWidth() const { return GetSize().cx; }
|
||||
int GetHeight() const { return GetSize().cy; }
|
||||
int GetLength() const;
|
||||
Point GetHotSpot() const;
|
||||
Point Get2ndSpot() const;
|
||||
Size GetDots() const;
|
||||
int GetKindNoScan() const;
|
||||
int GetKind() const;
|
||||
|
||||
int64 GetSerialId() const { return data ? data->serial : 0; }
|
||||
bool IsSame(const Image& img) const { return GetSerialId() == img.GetSerialId(); }
|
||||
|
||||
bool operator==(const Image& img) const;
|
||||
bool operator!=(const Image& img) const;
|
||||
dword GetHashValue() const;
|
||||
String ToString() const;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
void Clear();
|
||||
|
||||
Image& operator=(const Image& img);
|
||||
Image& operator=(ImageBuffer& img);
|
||||
|
||||
bool IsNullInstance() const { Size sz = GetSize(); return (sz.cx|sz.cy) == 0; }
|
||||
|
||||
bool IsEmpty() const { return IsNullInstance(); }
|
||||
operator Value() const { return RichValue<Image>(*this); }
|
||||
|
||||
Image() { data = NULL; }
|
||||
Image(const Nuller&) { data = NULL; }
|
||||
Image(const Value& src);
|
||||
Image(const Image& img);
|
||||
Image(Image (*fn)());
|
||||
Image(ImageBuffer& b);
|
||||
~Image();
|
||||
|
||||
|
||||
static Image Arrow();
|
||||
static Image Wait();
|
||||
static Image IBeam();
|
||||
static Image No();
|
||||
static Image SizeAll();
|
||||
static Image SizeHorz();
|
||||
static Image SizeVert();
|
||||
static Image SizeTopLeft();
|
||||
static Image SizeTop();
|
||||
static Image SizeTopRight();
|
||||
static Image SizeLeft();
|
||||
static Image SizeRight();
|
||||
static Image SizeBottomLeft();
|
||||
static Image SizeBottom();
|
||||
static Image SizeBottomRight();
|
||||
static Image Cross();
|
||||
static Image Hand();
|
||||
|
||||
// IML support ("private"), deprecated - legacy .iml
|
||||
struct Init {
|
||||
const char *const *scans;
|
||||
int16 scan_count;
|
||||
char info[24];
|
||||
};
|
||||
explicit Image(const Init& init);
|
||||
};
|
||||
|
||||
Image Premultiply(const Image& img);
|
||||
Image Unmultiply(const Image& img);
|
||||
|
||||
Vector<Image> UnpackImlData(const void *ptr, int len);
|
||||
Vector<Image> UnpackImlData(const String& d);
|
||||
|
||||
class Iml {
|
||||
struct IImage : Moveable<IImage> {
|
||||
bool loaded;
|
||||
Image image;
|
||||
|
||||
IImage() { loaded = false; }
|
||||
};
|
||||
struct Data : Moveable<Data> {
|
||||
const char *data;
|
||||
int len, count;
|
||||
};
|
||||
Vector<Data> data;
|
||||
VectorMap<String, IImage> map;
|
||||
const Image::Init *img_init;
|
||||
const char **name;
|
||||
bool premultiply;
|
||||
|
||||
void Init(int n);
|
||||
|
||||
public:
|
||||
void Enter();
|
||||
void Leave();
|
||||
void Reset();
|
||||
int GetCount() const { return map.GetCount(); }
|
||||
String GetId(int i) { return map.GetKey(i); }
|
||||
Image Get(int i);
|
||||
int Find(const String& s) const { return map.Find(s); }
|
||||
void Set(int i, const Image& img);
|
||||
void Premultiplied() { premultiply = false; }
|
||||
|
||||
#ifdef _DEBUG
|
||||
int GetBinSize() const;
|
||||
#endif
|
||||
|
||||
Iml(const Image::Init *img_init, const char **name, int n);//Deprecated - legacy .iml
|
||||
void AddData(const byte *data, int len, int count);
|
||||
};
|
||||
|
||||
void Register(const char *imageclass, Iml& iml);
|
||||
|
||||
int GetImlCount();
|
||||
String GetImlName(int i);
|
||||
Iml& GetIml(int i);
|
||||
int FindIml(const char *name);
|
||||
Image GetImlImage(const char *name);
|
||||
void SetImlImage(const char *name, const Image& m);
|
||||
|
||||
String StoreImageAsString(const Image& img);
|
||||
Image LoadImageFromString(const String& s);
|
||||
Size GetImageStringSize(const String& src);
|
||||
Size GetImageStringDots(const String& src);
|
||||
|
||||
#include "Raster.h"
|
||||
#include "ImageOp.h"
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifndef PLATFORM_WINCE
|
||||
|
||||
Image Win32Icon(LPCSTR id, int iconsize = 0);
|
||||
Image Win32Icon(int id, int iconsize = 0);
|
||||
Image Win32Cursor(LPCSTR id);
|
||||
Image Win32Cursor(int id);
|
||||
HICON IconWin32(const Image& img, bool cursor = false);
|
||||
Image Win32DllIcon(const char *dll, int ii, bool large);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
Cursor X11Cursor(const Image& img);
|
||||
#endif
|
||||
399
archive/olddraw/Draw/ImageBlit.cpp
Normal file
399
archive/olddraw/Draw/ImageBlit.cpp
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void Fill(RGBA *t, const RGBA& src, int n)
|
||||
{
|
||||
while(n--)
|
||||
*t++ = src;
|
||||
}
|
||||
|
||||
void FillColor(RGBA *t, const RGBA& src, int n)
|
||||
{
|
||||
while(n--) {
|
||||
t->r = src.r;
|
||||
t->g = src.g;
|
||||
t->b = src.b;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void Copy(RGBA *t, const RGBA *s, int n)
|
||||
{
|
||||
while(n--)
|
||||
*t++ = *s++;
|
||||
}
|
||||
|
||||
const byte *UnpackRLE(RGBA *t, const byte *s, int len)
|
||||
{
|
||||
RGBA *e = t + len;
|
||||
while(t < e)
|
||||
if(*s & 0x80) {
|
||||
if(*s == 0x80)
|
||||
break;
|
||||
int count = min<int>((int)(*s & 0x3F), (int)(e - t));
|
||||
RGBA h;
|
||||
if(*s++ & 0x40)
|
||||
Zero(h);
|
||||
else {
|
||||
h.b = s[0];
|
||||
h.g = s[1];
|
||||
h.r = s[2];
|
||||
h.a = 255;
|
||||
s += 3;
|
||||
}
|
||||
count = min<int>(count, (int)(e - t));
|
||||
memsetex(t, &h, sizeof(RGBA), count);
|
||||
t += count;
|
||||
}
|
||||
else {
|
||||
if(*s == 0)
|
||||
break;
|
||||
int count = *s++;
|
||||
while(count-- && t < e) {
|
||||
RGBA h;
|
||||
h.b = s[0];
|
||||
h.g = s[1];
|
||||
h.r = s[2];
|
||||
h.a = 255;
|
||||
*t++ = h;
|
||||
s += 3;
|
||||
}
|
||||
}
|
||||
while(t < e)
|
||||
Zero(*t++);
|
||||
return s;
|
||||
}
|
||||
|
||||
String PackRLE(const RGBA *s, int len)
|
||||
{
|
||||
StringBuffer r;
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
const RGBA *q = s;
|
||||
if(s->a == 0) {
|
||||
s++;
|
||||
while(s < e && s->a == 0 && s - q < 0x3f)
|
||||
s++;
|
||||
r.Cat((0x80|0x40) + (int)(s - q));
|
||||
}
|
||||
else
|
||||
if(s + 1 < e && s[0] == s[1]) {
|
||||
s++;
|
||||
while(s + 1 < e && s[0] == s[1] && s - q < 0x3e)
|
||||
s++;
|
||||
s++;
|
||||
r.Cat(0x80 + (int)(s - q));
|
||||
r.Cat(q->b);
|
||||
r.Cat(q->g);
|
||||
r.Cat(q->r);
|
||||
}
|
||||
else {
|
||||
s++;
|
||||
while(s + 1 < e && s->a && s[0] != s[1] && s - q < 0x3f)
|
||||
s++;
|
||||
r.Cat((int)(s - q));
|
||||
while(q < s) {
|
||||
r.Cat(q->b);
|
||||
r.Cat(q->g);
|
||||
r.Cat(q->r);
|
||||
q++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int Premultiply(RGBA *t, const RGBA *s, int len)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
if(s->a != 255) {
|
||||
while(s < e) {
|
||||
byte a = s->a;
|
||||
if(s->a != 0 && s->a != 255) {
|
||||
while(s < e) {
|
||||
int alpha = s->a + (s->a >> 7);
|
||||
t->r = alpha * (s->r) >> 8;
|
||||
t->g = alpha * (s->g) >> 8;
|
||||
t->b = alpha * (s->b) >> 8;
|
||||
t->a = s->a;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return IMAGE_ALPHA;
|
||||
}
|
||||
t->r = a & s->r;
|
||||
t->g = a & s->g;
|
||||
t->b = a & s->b;
|
||||
t->a = s->a;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return IMAGE_MASK;
|
||||
}
|
||||
*t++ = *s++;
|
||||
}
|
||||
return IMAGE_OPAQUE;
|
||||
}
|
||||
|
||||
int um_table__[256];
|
||||
|
||||
void sInitUmTable__()
|
||||
{
|
||||
ONCELOCK {
|
||||
for(int i = 1; i < 256; i++)
|
||||
um_table__[i] = 65536 / i;
|
||||
}
|
||||
}
|
||||
|
||||
int Unmultiply(RGBA *t, const RGBA *s, int len)
|
||||
{
|
||||
sInitUmTable__();
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
if(s->a != 255) {
|
||||
while(s < e) {
|
||||
byte a = s->a;
|
||||
if(s->a != 0 && s->a != 255) {
|
||||
while(s < e) {
|
||||
int alpha = um_table__[s->a];
|
||||
t->r = (alpha * s->r) >> 8;
|
||||
t->g = (alpha * s->g) >> 8;
|
||||
t->b = (alpha * s->b) >> 8;
|
||||
t->a = s->a;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return IMAGE_ALPHA;
|
||||
}
|
||||
t->r = a & s->r;
|
||||
t->g = a & s->g;
|
||||
t->b = a & s->b;
|
||||
t->a = s->a;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return IMAGE_MASK;
|
||||
}
|
||||
*t++ = *s++;
|
||||
}
|
||||
return IMAGE_OPAQUE;
|
||||
}
|
||||
|
||||
void AlphaBlend(RGBA *t, const RGBA *s, int len)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
int alpha = 256 - (s->a + (s->a >> 7));
|
||||
t->r = s->r + (alpha * t->r >> 8);
|
||||
t->g = s->g + (alpha * t->g >> 8);
|
||||
t->b = s->b + (alpha * t->b >> 8);
|
||||
t->a = s->a + (alpha * t->a >> 8);
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendOpaque(RGBA *t, const RGBA *s, int len)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
int alpha = 256 - (s->a + (s->a >> 7));
|
||||
t->r = s->r + (alpha * t->r >> 8);
|
||||
t->g = s->g + (alpha * t->g >> 8);
|
||||
t->b = s->b + (alpha * t->b >> 8);
|
||||
t->a = 255;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlend(RGBA *t, const RGBA *s, int len, Color color)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
int r = color.GetR();
|
||||
int g = color.GetG();
|
||||
int b = color.GetB();
|
||||
while(s < e) {
|
||||
int alpha = s->a + (s->a >> 7);
|
||||
t->r += alpha * (r - t->r) >> 8;
|
||||
t->g += alpha * (g - t->g) >> 8;
|
||||
t->b += alpha * (b - t->b) >> 8;
|
||||
t->a = s->a + ((256 - alpha) * t->a >> 8);
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendOpaque(RGBA *t, const RGBA *s, int len, Color color)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
int r = color.GetR();
|
||||
int g = color.GetG();
|
||||
int b = color.GetB();
|
||||
while(s < e) {
|
||||
int alpha = s->a + (s->a >> 7);
|
||||
t->r += alpha * (r - t->r) >> 8;
|
||||
t->g += alpha * (g - t->g) >> 8;
|
||||
t->b += alpha * (b - t->b) >> 8;
|
||||
t->a = 255;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendStraightOpaque(RGBA *t, const RGBA *s, int len)
|
||||
{
|
||||
const RGBA *e = s + len;
|
||||
while(s < e) {
|
||||
int alpha = s->a + (s->a >> 7);
|
||||
t->r += alpha * (s->r - t->r) >> 8;
|
||||
t->g += alpha * (s->g - t->g) >> 8;
|
||||
t->b += alpha * (s->b - t->b) >> 8;
|
||||
t->a = 255;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendStraightOpaque(RGBA *t, const RGBA *s, int len, int alpha)
|
||||
{
|
||||
if(alpha >= 256) {
|
||||
AlphaBlendStraightOpaque(t, s, len);
|
||||
return;
|
||||
}
|
||||
const RGBA *e = s + len;
|
||||
alpha *= 0x102;
|
||||
while(s < e) {
|
||||
int a = (s->a * alpha) >> 16;
|
||||
t->r += a * (s->r - t->r) >> 8;
|
||||
t->g += a * (s->g - t->g) >> 8;
|
||||
t->b += a * (s->b - t->b) >> 8;
|
||||
t->a = 255;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
struct sBlends {
|
||||
int16 m;
|
||||
byte a;
|
||||
};
|
||||
|
||||
sBlends *sblends;
|
||||
|
||||
void sOnceInitBlends()
|
||||
{
|
||||
ONCELOCK {
|
||||
sblends = (sBlends *)MemoryAllocPermanent(256 * 256 * sizeof(sBlends));
|
||||
for(int Fa = 0; Fa <= 255; Fa++)
|
||||
for(int Ba = 0; Ba <= 255; Ba++) {
|
||||
double A = (Fa / 255.0 + Ba / 255.0 - Fa / 255.0 * Ba / 255.0);
|
||||
sblends[(Ba << 8) + Fa].a = minmax((int)(255 * A + 0.5), 0, 255);
|
||||
sblends[(Ba << 8) + Fa].m = A > 0.001 ? int(256 * (Fa / 255.0) / A + 0.5) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void sInitBlends()
|
||||
{
|
||||
if(!sblends)
|
||||
sOnceInitBlends();
|
||||
}
|
||||
|
||||
void AlphaBlendStraight(RGBA *b, const RGBA *f, int len)
|
||||
{
|
||||
sInitBlends();
|
||||
const RGBA *e = f + len;
|
||||
while(f < e) {
|
||||
sBlends& x = sblends[(b->a << 8) + f->a];
|
||||
int m = x.m;
|
||||
b->a = x.a;
|
||||
b->r += m * (f->r - b->r) >> 8;
|
||||
b->g += m * (f->g - b->g) >> 8;
|
||||
b->b += m * (f->b - b->b) >> 8;
|
||||
b++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendOverBgStraight(RGBA *b, RGBA bg, int len)
|
||||
{
|
||||
sInitBlends();
|
||||
const RGBA *e = b + len;
|
||||
while(b < e) {
|
||||
sBlends& x = sblends[(bg.a << 8) + b->a];
|
||||
int m = x.m;
|
||||
b->a = x.a;
|
||||
b->r = bg.r + (m * (b->r - bg.r) >> 8);
|
||||
b->g = bg.g + (m * (b->g - bg.g) >> 8);
|
||||
b->b = bg.b + (m * (b->b - bg.b) >> 8);
|
||||
b++;
|
||||
}
|
||||
}
|
||||
|
||||
void AlphaBlendStraight(RGBA *b, const RGBA *f, int len, Color color)
|
||||
{
|
||||
sInitBlends();
|
||||
const RGBA *e = f + len;
|
||||
int cr = color.GetR();
|
||||
int cg = color.GetG();
|
||||
int cb = color.GetB();
|
||||
while(f < e) {
|
||||
sBlends& x = sblends[(b->a << 8) + f->a];
|
||||
int m = x.m;
|
||||
b->a = x.a;
|
||||
b->r += m * (cr - b->r) >> 8;
|
||||
b->g += m * (cg - b->g) >> 8;
|
||||
b->b += m * (cb - b->b) >> 8;
|
||||
b++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
int GetChMaskPos32(dword mask)
|
||||
{
|
||||
if(mask == 0xff000000)
|
||||
return 3;
|
||||
if(mask == 0xff0000)
|
||||
return 2;
|
||||
if(mask == 0xff00)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vector<Image> UnpackImlData(const void *ptr, int len)
|
||||
{
|
||||
Vector<Image> img;
|
||||
String data = ZDecompress(ptr, len);
|
||||
const char *s = data;
|
||||
while(s + 6 * 2 + 1 <= data.End()) {
|
||||
ImageBuffer ib(Peek16le(s + 1), Peek16le(s + 3));
|
||||
ib.SetHotSpot(Point(Peek16le(s + 5), Peek16le(s + 7)));
|
||||
ib.Set2ndSpot(Point(Peek16le(s + 9), Peek16le(s + 11)));
|
||||
s += 13;
|
||||
int len = ib.GetLength();
|
||||
RGBA *t = ib;
|
||||
const RGBA *e = t + len;
|
||||
if(s + 4 * len > data.End())
|
||||
break;
|
||||
while(t < e) {
|
||||
t->a = s[3];
|
||||
t->r = s[0];
|
||||
t->g = s[1];
|
||||
t->b = s[2];
|
||||
s += 4;
|
||||
t++;
|
||||
}
|
||||
img.Add() = ib;
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
Vector<Image> UnpackImlData(const String& d)
|
||||
{
|
||||
return UnpackImlData(~d, d.GetLength());
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
380
archive/olddraw/Draw/ImageChOp.cpp
Normal file
380
archive/olddraw/Draw/ImageChOp.cpp
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
int Diff(RGBA a, RGBA b)
|
||||
{
|
||||
return max(abs(a.a - b.a), max(abs(a.r - b.r), max(abs(a.b - b.b), abs(a.g - b.g))));
|
||||
}
|
||||
|
||||
struct InterPoint {
|
||||
ImageBuffer &b;
|
||||
Rect rc;
|
||||
int sr, sg, sb;
|
||||
int sn, in;
|
||||
|
||||
InterPoint(ImageBuffer& b) : b(b) {
|
||||
sr = sg = sb = sn = in = 0;
|
||||
}
|
||||
void Add(int x, int y);
|
||||
};
|
||||
|
||||
void InterPoint::Add(int y, int x) {
|
||||
if(rc.Contains(x, y)) {
|
||||
RGBA ba = b[y][x];
|
||||
if(ba.a == 0)
|
||||
return;
|
||||
in++;
|
||||
sn++;
|
||||
sr += ba.r;
|
||||
sg += ba.g;
|
||||
sb += ba.b;
|
||||
}
|
||||
else
|
||||
in++;
|
||||
}
|
||||
|
||||
void Interpolate(ImageBuffer& b, Vector< Vector<bool> >& map, const Rect& rc)
|
||||
{
|
||||
Unmultiply(b);
|
||||
int todo;
|
||||
do {
|
||||
todo = 0;
|
||||
for(int x = rc.left; x < rc.right; x++)
|
||||
for(int y = rc.top; y < rc.bottom; y++) {
|
||||
RGBA& p = b[y][x];
|
||||
if(map[y][x]) {
|
||||
map[y][x] = 0;
|
||||
InterPoint ip(b);
|
||||
ip.rc = rc;
|
||||
ip.Add(y - 1, x - 1);
|
||||
ip.Add(y - 1, x);
|
||||
ip.Add(y - 1, x + 1);
|
||||
ip.Add(y, x - 1);
|
||||
ip.Add(y, x + 1);
|
||||
ip.Add(y + 1, x - 1);
|
||||
ip.Add(y + 1, x);
|
||||
ip.Add(y + 1, x + 1);
|
||||
if(ip.in >= 2) {
|
||||
if(ip.sn) {
|
||||
p.r = ip.sr / ip.sn;
|
||||
p.g = ip.sg / ip.sn;
|
||||
p.b = ip.sb / ip.sn;
|
||||
}
|
||||
else
|
||||
p = SColorFace();
|
||||
p.a = 255;
|
||||
}
|
||||
else
|
||||
todo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(todo);
|
||||
Premultiply(b);
|
||||
}
|
||||
|
||||
struct ButtonDecomposer {
|
||||
Image src;
|
||||
Image dst;
|
||||
int aa[8];
|
||||
int maxdiff;
|
||||
RGBA color;
|
||||
int gdiff;
|
||||
int gcount;
|
||||
|
||||
RGBA GetC(int p) {
|
||||
Size sz = src.GetSize();
|
||||
int xx[3];
|
||||
int yy[3];
|
||||
yy[0] = xx[0] = aa[p];
|
||||
xx[1] = sz.cx - aa[p] - 1;
|
||||
xx[2] = sz.cx / 2;
|
||||
yy[1] = sz.cy - aa[p] - 1;
|
||||
yy[2] = sz.cy / 2;
|
||||
return src[xx[p / 3]][xx[p % 3]];
|
||||
}
|
||||
|
||||
void Do() {
|
||||
Size sz = src.GetSize();
|
||||
int qa = min(4, min(sz.cy / 4, sz.cx / 4));
|
||||
if(qa == 0) {
|
||||
dst = src;
|
||||
return;
|
||||
}
|
||||
int a = 0;
|
||||
for(int p = 0; p < 8; p++) {
|
||||
aa[p] = qa;
|
||||
Color c = GetC(p);
|
||||
while(aa[p] > 0) {
|
||||
Color c1 = GetC(p);
|
||||
if(Diff(c, c1) > 30)
|
||||
break;
|
||||
c = c1;
|
||||
aa[p]--;
|
||||
}
|
||||
if(aa[p] > a)
|
||||
a = aa[p];
|
||||
}
|
||||
if(a < min(sz.cx / 3, sz.cy / 3))
|
||||
a++;
|
||||
dst = src;
|
||||
ImageBuffer b(dst);
|
||||
color = SColorText();
|
||||
maxdiff = gdiff = gcount = 0;
|
||||
Vector< Vector<bool> > map;
|
||||
for(int y = a; y < sz.cy - a; y++) {
|
||||
map.At(y).SetCount(sz.cx, false);
|
||||
RGBA *p = b[y];
|
||||
int x = a;
|
||||
Color c = p[x];
|
||||
while(x < sz.cx - a) {
|
||||
if(Diff(p[x], c) > 30)
|
||||
break;
|
||||
c = p[x++];
|
||||
}
|
||||
int xx = sz.cx - a;
|
||||
while(xx > x) {
|
||||
if(Diff(p[xx - 1], c) > 30)
|
||||
break;
|
||||
c = p[--xx];
|
||||
}
|
||||
for(int q = x; q < xx; q++) {
|
||||
int d = Diff(p[q], c);
|
||||
gcount++;
|
||||
gdiff += d;
|
||||
if(d >= maxdiff) {
|
||||
maxdiff = d;
|
||||
color = p[q];
|
||||
}
|
||||
}
|
||||
Fill(p + x, RGBAZero(), xx - x);
|
||||
map[y].Set(x, true, xx - x);
|
||||
}
|
||||
Interpolate(b, map, Rect(a, a, sz.cx - a, sz.cy - a));
|
||||
if(a < 2) a = 2;
|
||||
b.SetHotSpot(Point(a, a));
|
||||
dst = b;
|
||||
}
|
||||
};
|
||||
|
||||
Image Unglyph(const Image& m, Color& c, double& gfactor)
|
||||
{
|
||||
ButtonDecomposer b;
|
||||
b.src = Unmultiply(m);
|
||||
b.Do();
|
||||
c = b.color;
|
||||
gfactor = (double)b.gdiff / b.gcount;
|
||||
return Premultiply(b.dst);
|
||||
}
|
||||
|
||||
Image Unglyph(const Image& m, Color& c)
|
||||
{
|
||||
double dummy;
|
||||
return Unglyph(m, c, dummy);
|
||||
}
|
||||
|
||||
Image Unglyph(const Image& m)
|
||||
{
|
||||
Color dummy;
|
||||
return Unglyph(m, dummy);
|
||||
}
|
||||
|
||||
Image VertBlend(Image img1, Image img2, int y0, int y1)
|
||||
{
|
||||
Size sz = img1.GetSize();
|
||||
Size sz2 = img2.GetSize();
|
||||
sz.cx = min(sz.cx, sz2.cx);
|
||||
sz.cy = min(sz.cy, sz2.cy);
|
||||
ImageBuffer b(sz);
|
||||
for(int y = 0; y < sz.cy; y++)
|
||||
if(y >= y1)
|
||||
memcpy(b[y], img2[y], sz.cx * sizeof(RGBA));
|
||||
else
|
||||
if(y >= y0 && y1 > y0) {
|
||||
int alpha = 256 * (y - y0) / (y1 - y0);
|
||||
RGBA *t = b[y];
|
||||
const RGBA *s1 = img1[y];
|
||||
const RGBA *s2 = img2[y];
|
||||
const RGBA *e = s1 + sz.cx;
|
||||
while(s1 < e) {
|
||||
t->r = s1->r + ((alpha * (s2->r - s1->r)) >> 8);
|
||||
t->g = s1->g + ((alpha * (s2->g - s1->g)) >> 8);
|
||||
t->b = s1->b + ((alpha * (s2->b - s1->b)) >> 8);
|
||||
t->a = s1->a + ((alpha * (s2->a - s1->a)) >> 8);
|
||||
s1++;
|
||||
s2++;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy(b[y], img1[y], sz.cx * sizeof(RGBA));
|
||||
b.SetHotSpot(img1.GetHotSpot());
|
||||
b.Set2ndSpot(img1.Get2ndSpot());
|
||||
return b;
|
||||
}
|
||||
|
||||
Image HorzBlend(Image img1, Image img2, int x0, int x1)
|
||||
{
|
||||
Image m = RotateAntiClockwise(VertBlend(RotateClockwise(img1), RotateClockwise(img2), x0, x1));
|
||||
ImageBuffer b(m);
|
||||
b.SetHotSpot(img1.GetHotSpot());
|
||||
b.Set2ndSpot(img1.Get2ndSpot());
|
||||
return b;
|
||||
}
|
||||
|
||||
Image HorzSymm(Image src) {
|
||||
ImageBuffer b(src);
|
||||
Size sz = b.GetSize();
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
RGBA *l = b[y];
|
||||
for(int x = 0; x < sz.cx / 2; x++)
|
||||
l[sz.cx - x - 1] = l[x];
|
||||
}
|
||||
b.SetHotSpot(src.GetHotSpot());
|
||||
b.Set2ndSpot(src.Get2ndSpot());
|
||||
return b;
|
||||
}
|
||||
|
||||
bool EqLine(const Image& m, int l1, int l2, int x, int width)
|
||||
{
|
||||
return !memcmp(m[l1] + x, m[l2] + x, width * sizeof(RGBA));
|
||||
}
|
||||
|
||||
bool EqLine(const Image& m, int l1, int l2)
|
||||
{
|
||||
return EqLine(m, l1, l2, 0, m.GetWidth());
|
||||
}
|
||||
|
||||
bool EqColumn(const Image& m, int c1, int c2, int y, int height)
|
||||
{
|
||||
int cx = m.GetWidth();
|
||||
const RGBA *a = m[y] + c1;
|
||||
const RGBA *b = m[y] + c2;
|
||||
for(int w = 0; w < height; w++) {
|
||||
if(*a != *b)
|
||||
return false;
|
||||
a += cx;
|
||||
b += cx;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EqColumn(const Image& m, int c1, int c2)
|
||||
{
|
||||
return EqColumn(m, c1, c2, 0, m.GetHeight());
|
||||
}
|
||||
|
||||
int ClassifyContent(const Image& m, const Rect& rect)
|
||||
{
|
||||
if(IsNull(rect))
|
||||
return 0;
|
||||
bool vdup = true;
|
||||
for(int q = rect.top + 1; q < rect.bottom; q++)
|
||||
if(!EqLine(m, q, rect.top, rect.left, rect.GetWidth())) {
|
||||
vdup = false;
|
||||
break;
|
||||
}
|
||||
for(int q = rect.left + 1; q < rect.right; q++)
|
||||
if(!EqColumn(m, rect.left, q, rect.top, rect.GetHeight()))
|
||||
return vdup;
|
||||
return 2 + vdup;
|
||||
}
|
||||
|
||||
Image RecreateAlpha(const Image& overwhite, const Image& overblack)
|
||||
{
|
||||
Size sz = overwhite.GetSize();
|
||||
ASSERT(overblack.GetSize() == sz);
|
||||
ImageBuffer r(sz);
|
||||
const RGBA *ws = overwhite;
|
||||
const RGBA *bs = overblack;
|
||||
RGBA *t = r;
|
||||
RGBA *e = t + r.GetLength();
|
||||
while(t < e) {
|
||||
t->a = bs->r - ws->r + 255;
|
||||
if(t->a) {
|
||||
t->r = bs->r * 255 / t->a;
|
||||
t->g = bs->g * 255 / t->a;
|
||||
t->b = bs->b * 255 / t->a;
|
||||
}
|
||||
else
|
||||
t->r = t->g = t->b = 0;
|
||||
t++;
|
||||
bs++;
|
||||
ws++;
|
||||
}
|
||||
Premultiply(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
int ImageMargin(const Image& _m, int p, int dist)
|
||||
{
|
||||
Image m = Unmultiply(_m);
|
||||
Color c = m[p][p];
|
||||
int d;
|
||||
Size sz = m.GetSize();
|
||||
for(d = p; d >= 0; d--)
|
||||
if(Diff(m[d][d], c) > dist || Diff(m[sz.cx - d - 1][sz.cy - d - 1], c) > dist)
|
||||
break;
|
||||
return d + 1;
|
||||
}
|
||||
|
||||
int ImageMarginV(const Image& _m, int p, int dist)
|
||||
{
|
||||
Image m = Unmultiply(_m);
|
||||
Size sz = m.GetSize();
|
||||
Color c = m[sz.cx / 2][p];
|
||||
int d;
|
||||
for(d = p; d >= 0; d--)
|
||||
if(Diff(m[sz.cx / 2][d], c) > dist || Diff(m[sz.cx / 2][sz.cy - d - 1], c) > dist)
|
||||
break;
|
||||
return d + 1;
|
||||
}
|
||||
|
||||
ChPartMaker::ChPartMaker(const Image& m)
|
||||
{
|
||||
image = m;
|
||||
border = SColorShadow();
|
||||
bg = Null;
|
||||
ResetShape();
|
||||
}
|
||||
|
||||
void ChPartMaker::ResetShape()
|
||||
{
|
||||
t = b = l = r = true;
|
||||
tl = tr = bl = br = 0;
|
||||
}
|
||||
|
||||
Image ChPartMaker::Make() const
|
||||
{
|
||||
Size sz = image.GetSize();
|
||||
ASSERT(sz.cx >= 6 && sz.cy >= 6);
|
||||
Image h = image;
|
||||
ImageBuffer ib(h);
|
||||
for(int x = 0; x < sz.cx; x++) {
|
||||
if(t)
|
||||
ib[0][x] = x >= tl && x < sz.cx - tr ? border : bg;
|
||||
if(b)
|
||||
ib[sz.cy - 1][x] = x >= bl && x < sz.cx - br ? border : bg;
|
||||
}
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
if(l)
|
||||
ib[y][0] = y >= tl && y < sz.cy - bl ? border : bg;
|
||||
if(r)
|
||||
ib[y][sz.cx - 1] = y >= tr && y < sz.cy - br ? border : bg;
|
||||
}
|
||||
if(tl == 2)
|
||||
ib[1][1] = border;
|
||||
if(tr == 2)
|
||||
ib[1][sz.cx - 2] = border;
|
||||
if(bl == 2)
|
||||
ib[sz.cy - 2][1] = border;
|
||||
if(br == 2)
|
||||
ib[sz.cy - 2][sz.cx - 2] = border;
|
||||
int q = max(max(tl, tr), max(br, bl));
|
||||
ib.SetHotSpot(Point(q, q));
|
||||
ib.Set2ndSpot(Point(sz.cx - q - 1, sz.cy - q - 1));
|
||||
return ib;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
38
archive/olddraw/Draw/ImageDraw.h
Normal file
38
archive/olddraw/Draw/ImageDraw.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
class ImageDraw : public Draw, NoCopy {
|
||||
Size size;
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
struct Section {
|
||||
HDC dc;
|
||||
HBITMAP hbmp, hbmpOld;
|
||||
RGBA *pixels;
|
||||
|
||||
void Init(int cx, int cy);
|
||||
~Section();
|
||||
};
|
||||
|
||||
Section rgb;
|
||||
Section a;
|
||||
Draw alpha;
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
Draw alpha;
|
||||
#endif
|
||||
|
||||
bool has_alpha;
|
||||
|
||||
void Init();
|
||||
Image Get(bool pm) const;
|
||||
|
||||
public:
|
||||
Draw& Alpha();
|
||||
|
||||
operator Image() const;
|
||||
|
||||
Image GetStraight() const;
|
||||
|
||||
ImageDraw(Size sz);
|
||||
ImageDraw(int cx, int cy);
|
||||
~ImageDraw();
|
||||
};
|
||||
665
archive/olddraw/Draw/ImageOp.cpp
Normal file
665
archive/olddraw/Draw/ImageOp.cpp
Normal file
|
|
@ -0,0 +1,665 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
Image WithHotSpots(const Image& m, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
Image h = m;
|
||||
ImageBuffer b(h);
|
||||
b.SetHotSpot(Point(x1, y1));
|
||||
b.Set2ndSpot(Point(x2, y2));
|
||||
return b;
|
||||
}
|
||||
|
||||
Image WithHotSpot(const Image& m, int x1, int y1)
|
||||
{
|
||||
Image h = m;
|
||||
ImageBuffer b(h);
|
||||
b.SetHotSpot(Point(x1, y1));
|
||||
return b;
|
||||
}
|
||||
|
||||
Image CreateImage(Size sz, Color color)
|
||||
{
|
||||
ImageBuffer ib(sz);
|
||||
RGBA rgba = color;
|
||||
memsetex(ib, &rgba, sizeof(RGBA), ib.GetLength());
|
||||
return ib;
|
||||
}
|
||||
|
||||
Size DstSrc(ImageBuffer& dest, Point& p, const Image& src, Rect& sr)
|
||||
{
|
||||
if(p.x < 0) {
|
||||
sr.left += -p.x;
|
||||
p.x = 0;
|
||||
}
|
||||
if(p.y < 0) {
|
||||
sr.top += -p.y;
|
||||
p.y = 0;
|
||||
}
|
||||
sr = sr & src.GetSize();
|
||||
Size sz = dest.GetSize() - p;
|
||||
sz.cx = min(sz.cx, sr.GetWidth());
|
||||
sz.cy = min(sz.cy, sr.GetHeight());
|
||||
return sz;
|
||||
}
|
||||
|
||||
void DstSrcOp(ImageBuffer& dest, Point p, const Image& src, const Rect& srect,
|
||||
void (*op)(RGBA *t, const RGBA *s, int n))
|
||||
{
|
||||
Rect sr = srect;
|
||||
Size sz = DstSrc(dest, p, src, sr);
|
||||
if(sz.cx > 0)
|
||||
while(--sz.cy >= 0)
|
||||
(*op)(dest[p.y++] + p.x, src[sr.top++] + sr.left, sz.cx);
|
||||
}
|
||||
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, Copy);
|
||||
}
|
||||
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, AlphaBlend);
|
||||
}
|
||||
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect)
|
||||
{
|
||||
DstSrcOp(dest, p, src, srect, AlphaBlendStraightOpaque);
|
||||
}
|
||||
|
||||
void Copy(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
Copy(b, p, src, srect);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
void Over(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
Over(b, p, src, srect);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect)
|
||||
{
|
||||
Image src = _src;
|
||||
ImageBuffer b(dest);
|
||||
OverStraightOpaque(b, p, src, srect);
|
||||
dest = b;
|
||||
}
|
||||
|
||||
void Crop(RasterEncoder& tgt, Raster& img, const Rect& rc)
|
||||
{
|
||||
Rect r = rc & img.GetSize();
|
||||
tgt.Create(r.Size(), img);
|
||||
for(int y = r.top; y < r.bottom; y++)
|
||||
tgt.WriteLine(~img[y] + r.left);
|
||||
}
|
||||
|
||||
Image Crop(const Image& img, const Rect& rc)
|
||||
{
|
||||
if(rc.left == 0 && rc.top == 0 && rc.Size() == img.GetSize())
|
||||
return img;
|
||||
if((rc & img.GetSize()).IsEmpty())
|
||||
return Image();
|
||||
ImageRaster src(img);
|
||||
ImageEncoder tgt;
|
||||
Crop(tgt, src, rc);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
Image Crop(const Image& img, int x, int y, int cx, int cy)
|
||||
{
|
||||
return Crop(img, RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
Image ColorMask(const Image& src, Color key)
|
||||
{
|
||||
ImageBuffer ib(src.GetSize());
|
||||
const RGBA *s = src;
|
||||
const RGBA *e = src + src.GetLength();
|
||||
RGBA *t = ~ib;
|
||||
byte kr = key.GetR();
|
||||
byte kg = key.GetG();
|
||||
byte kb = key.GetB();
|
||||
while(s < e) {
|
||||
if(s->r == kr && s->g == kg && s->b == kb)
|
||||
*t++ = RGBAZero();
|
||||
else
|
||||
*t++ = *s;
|
||||
s++;
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
void CanvasSize(RasterEncoder& tgt, Raster& img, int cx, int cy)
|
||||
{
|
||||
tgt.Create(cx, cy, img);
|
||||
int ccx = min(img.GetWidth(), cx);
|
||||
int ccy = min(img.GetHeight(), cy);
|
||||
for(int y = 0; y < ccy; y++) {
|
||||
memcpy(~tgt, img[y], ccx * sizeof(RGBA));
|
||||
memset(~tgt + ccx, 0, (cx - ccx) * sizeof(RGBA));
|
||||
tgt.WriteLine();
|
||||
}
|
||||
for(int y = cy - ccy; --y >= 0;) {
|
||||
memset(~tgt, 0, cx * sizeof(RGBA));
|
||||
tgt.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
Image CanvasSize(const Image& img, int cx, int cy)
|
||||
{
|
||||
ImageRaster src(img);
|
||||
ImageEncoder tgt;
|
||||
CanvasSize(tgt, src, cx, cy);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
Image AssignAlpha(const Image& img, const Image& alpha)
|
||||
{
|
||||
Size sz = Size(min(img.GetWidth(), alpha.GetWidth()),
|
||||
min(img.GetHeight(), alpha.GetHeight()));
|
||||
if(sz.cx == 0 || sz.cy == 0)
|
||||
return Image();
|
||||
ImageBuffer ib(sz);
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
const RGBA *s = img[y];
|
||||
const RGBA *e = s + sz.cx;
|
||||
const RGBA *a = alpha[y];
|
||||
RGBA *t = ib[y];
|
||||
while(s < e) {
|
||||
*t = *s++;
|
||||
(t++)->a = (a++)->a;
|
||||
}
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
int EqualightCh(int c, int l, int h)
|
||||
{
|
||||
return Saturate255((c - l) * 255 / (h - l) + l);
|
||||
}
|
||||
|
||||
Image Equalight(const Image& img, int thold)
|
||||
{
|
||||
int histogram[256];
|
||||
ZeroArray(histogram);
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
while(s < e) {
|
||||
histogram[Grayscale(*s)]++;
|
||||
s++;
|
||||
}
|
||||
int n = (thold * img.GetLength()) >> 8;
|
||||
int h = 255;
|
||||
int l = 0;
|
||||
while(l < h) {
|
||||
if(n < 0)
|
||||
break;
|
||||
n -= histogram[l++];
|
||||
if(n < 0)
|
||||
break;
|
||||
n -= histogram[h--];
|
||||
}
|
||||
if(l >= h)
|
||||
return img;
|
||||
ImageBuffer w(img.GetSize());
|
||||
RGBA *t = w;
|
||||
s = ~img;
|
||||
while(s < e) {
|
||||
t->r = EqualightCh(s->r, l, h);
|
||||
t->g = EqualightCh(s->g, l, h);
|
||||
t->b = EqualightCh(s->b, l, h);
|
||||
t->a = s->a;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
Image Grayscale(const Image& img)
|
||||
{
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
RGBA *t = w;
|
||||
while(s < e) {
|
||||
int q = Grayscale(*s);
|
||||
t->r = q;
|
||||
t->g = q;
|
||||
t->b = q;
|
||||
t->a = s->a;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
Image Grayscale(const Image& img, int amount)
|
||||
{
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
RGBA *t = w;
|
||||
int na = 256 - amount;
|
||||
while(s < e) {
|
||||
int q = Grayscale(*s);
|
||||
t->r = Saturate255((amount * q + na * s->r) >> 8);
|
||||
t->g = Saturate255((amount * q + na * s->g) >> 8);
|
||||
t->b = Saturate255((amount * q + na * s->b) >> 8);
|
||||
t->a = s->a;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
Image Colorize(const Image& img, Color color, int alpha)
|
||||
{
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
Unmultiply(w);
|
||||
RGBA *t = w;
|
||||
byte r = color.GetR();
|
||||
byte g = color.GetG();
|
||||
byte b = color.GetB();
|
||||
alpha = alpha + (alpha >> 7);
|
||||
while(s < e) {
|
||||
int ga = Grayscale(*s);
|
||||
ga = ga + (ga >> 7);
|
||||
t->r = (alpha * (((ga * r) >> 8) - s->r) >> 8) + s->r;
|
||||
t->g = (alpha * (((ga * g) >> 8) - s->g) >> 8) + s->g;
|
||||
t->b = (alpha * (((ga * b) >> 8) - s->b) >> 8) + s->b;
|
||||
t->a = s->a;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
Premultiply(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
inline
|
||||
byte ContrastCh(int amount, int ch)
|
||||
{
|
||||
return Saturate255(128 + (amount * (ch - 128) >> 8));
|
||||
}
|
||||
|
||||
Image Contrast(const Image& img, int amount)
|
||||
{
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
Unmultiply(w);
|
||||
RGBA *t = w;
|
||||
while(s < e) {
|
||||
t->r = ContrastCh(amount, s->r);
|
||||
t->g = ContrastCh(amount, s->g);
|
||||
t->b = ContrastCh(amount, s->b);
|
||||
t->a = s->a;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
Premultiply(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
void sLine(RGBA *t, int cx, const RasterLine l[3], ImageFilter9& filter)
|
||||
{
|
||||
RGBA h[3][3];
|
||||
const RGBA *x[3];
|
||||
x[0] = h[0];
|
||||
x[1] = h[1];
|
||||
x[2] = h[2];
|
||||
if(cx == 1) {
|
||||
h[0][0] = l[0][0]; h[0][1] = l[0][0]; h[0][2] = l[0][0];
|
||||
h[1][0] = l[1][0]; h[1][1] = l[1][0]; h[1][2] = l[1][0];
|
||||
h[2][0] = l[2][0]; h[2][1] = l[2][0]; h[2][2] = l[2][0];
|
||||
*t = filter(x);
|
||||
return;
|
||||
}
|
||||
h[0][0] = l[0][0]; h[0][1] = l[0][0]; h[0][2] = l[0][1];
|
||||
h[1][0] = l[1][0]; h[1][1] = l[1][0]; h[1][2] = l[1][1];
|
||||
h[2][0] = l[2][0]; h[2][1] = l[2][0]; h[2][2] = l[2][1];
|
||||
*t++ = filter(x);
|
||||
for(int i = 1; i < cx - 1; i++) {
|
||||
x[0] = ~l[0] + i - 1;
|
||||
x[1] = ~l[1] + i - 1;
|
||||
x[2] = ~l[2] + i - 1;
|
||||
*t++ = filter(x);
|
||||
}
|
||||
h[0][0] = l[0][cx - 2]; h[0][1] = l[0][cx - 1]; h[0][2] = l[0][cx - 1];
|
||||
h[1][0] = l[1][cx - 2]; h[1][1] = l[1][cx - 1]; h[1][2] = l[1][cx - 1];
|
||||
h[2][0] = l[2][cx - 2]; h[2][1] = l[2][cx - 1]; h[2][2] = l[2][cx - 1];
|
||||
x[0] = h[0];
|
||||
x[1] = h[1];
|
||||
x[2] = h[2];
|
||||
*t++ = filter(x);
|
||||
}
|
||||
|
||||
void Filter(RasterEncoder& target, Raster& src, ImageFilter9& filter)
|
||||
{
|
||||
Size sz = src.GetSize();
|
||||
target.Create(sz, src);
|
||||
if(sz.cy < 1)
|
||||
return;
|
||||
RasterLine l[3];
|
||||
if(sz.cy == 1) {
|
||||
l[0] = src[0];
|
||||
l[1] = src[0];
|
||||
l[2] = src[0];
|
||||
sLine(target, sz.cx, l, filter);
|
||||
return;
|
||||
}
|
||||
l[0] = src[0];
|
||||
l[1] = src[0];
|
||||
l[2] = src[1];
|
||||
sLine(target, sz.cx, l, filter);
|
||||
target.WriteLine();
|
||||
for(int y = 1; y < sz.cy - 1; y++) {
|
||||
l[0] = l[1];
|
||||
l[1] = l[2];
|
||||
l[2] = src[y + 1];
|
||||
sLine(target, sz.cx, l, filter);
|
||||
target.WriteLine();
|
||||
}
|
||||
l[0] = l[1];
|
||||
l[1] = l[2];
|
||||
l[2] = src[sz.cy - 1];
|
||||
sLine(target, sz.cx, l, filter);
|
||||
target.WriteLine();
|
||||
}
|
||||
|
||||
Image Filter(const Image& img, ImageFilter9& filter)
|
||||
{
|
||||
ImageEncoder tgt;
|
||||
ImageRaster src(img);
|
||||
Filter(tgt, src, filter);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
struct RGBAI {
|
||||
int r, g, b, a;
|
||||
|
||||
RGBAI() { r = g = b = a= 0; }
|
||||
};
|
||||
|
||||
static void sGetS(RGBA q, RGBAI& p, int mul)
|
||||
{
|
||||
p.r += mul * q.r;
|
||||
p.g += mul * q.g;
|
||||
p.b += mul * q.b;
|
||||
p.a += mul * q.a;
|
||||
}
|
||||
|
||||
struct sSharpenFilter : ImageFilter9 {
|
||||
int amount;
|
||||
|
||||
virtual RGBA operator()(const RGBA **mx);
|
||||
};
|
||||
|
||||
RGBA sSharpenFilter::operator()(const RGBA **mx)
|
||||
{
|
||||
RGBAI q;
|
||||
sGetS(mx[0][0], q, 7);
|
||||
sGetS(mx[0][1], q, 9);
|
||||
sGetS(mx[0][2], q, 7);
|
||||
sGetS(mx[1][0], q, 9);
|
||||
sGetS(mx[1][2], q, 9);
|
||||
sGetS(mx[2][0], q, 7);
|
||||
sGetS(mx[2][1], q, 9);
|
||||
sGetS(mx[2][2], q, 7);
|
||||
const RGBA& s = mx[1][1];
|
||||
RGBA t;
|
||||
int na = 256 + amount;
|
||||
t.b = Saturate255((na * (s.b << 6) - amount * q.b) >> 14);
|
||||
t.g = Saturate255((na * (s.g << 6) - amount * q.g) >> 14);
|
||||
t.r = Saturate255((na * (s.r << 6) - amount * q.r) >> 14);
|
||||
t.a = Saturate255((na * (s.a << 6) - amount * q.a) >> 14);
|
||||
return t;
|
||||
}
|
||||
|
||||
void Sharpen(RasterEncoder& target, Raster& src, int amount)
|
||||
{
|
||||
Size sz = src.GetSize();
|
||||
target.Create(sz, src);
|
||||
sSharpenFilter f;
|
||||
f.amount = amount;
|
||||
Filter(target, src, f);
|
||||
}
|
||||
|
||||
Image Sharpen(const Image& img, int amount)
|
||||
{
|
||||
ImageEncoder tgt;
|
||||
ImageRaster src(img);
|
||||
Sharpen(tgt, src, amount);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
struct sEtchFilter : ImageFilter9 {
|
||||
virtual RGBA operator()(const RGBA **mx);
|
||||
};
|
||||
|
||||
RGBA sEtchFilter::operator()(const RGBA **mx)
|
||||
{
|
||||
RGBA t;
|
||||
RGBA s = mx[1][1];
|
||||
if(s.a == 255 && s.r + s.g + s.b < 400) {
|
||||
t.r = t.g = t.b = 128;
|
||||
t.a = 255;
|
||||
return t;
|
||||
}
|
||||
s = mx[0][0];
|
||||
if(s.a == 255 && s.r + s.g + s.b < 400) {
|
||||
t.r = t.g = t.b = t.a = 255;
|
||||
return t;
|
||||
}
|
||||
Zero(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
Image Etched(const Image& img)
|
||||
{
|
||||
sEtchFilter ef;
|
||||
return Filter(img, ef);
|
||||
}
|
||||
|
||||
Image SetColorKeepAlpha(const Image& img, Color c)
|
||||
{
|
||||
RGBA rgba = c;
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
ImageBuffer w(img.GetSize());
|
||||
RGBA *t = w;
|
||||
while(s < e) {
|
||||
*t = rgba;
|
||||
(t++)->a = (s++)->a;
|
||||
}
|
||||
w.SetHotSpot(img.GetHotSpot());
|
||||
w.Set2ndSpot(img.Get2ndSpot());
|
||||
return w;
|
||||
}
|
||||
|
||||
Image CreateHorzFadeOut(Size sz, Color color)
|
||||
{
|
||||
ImageBuffer ib(sz);
|
||||
RGBA c = color;
|
||||
for(int q = 0; q < sz.cx; q++) {
|
||||
c.a = q * 255 / sz.cx;
|
||||
RGBA *t = ~ib + q;
|
||||
for(int n = sz.cy; n > 0; n--) {
|
||||
*t = c;
|
||||
t += sz.cx;
|
||||
}
|
||||
}
|
||||
Premultiply(ib);
|
||||
return ib;
|
||||
}
|
||||
|
||||
struct FadeOutMaker : ImageMaker {
|
||||
Size sz;
|
||||
Color color;
|
||||
|
||||
virtual String Key() const {
|
||||
char h[sizeof(Size) + sizeof(Color)];
|
||||
memcpy(h, &sz, sizeof(sz));
|
||||
memcpy(h + sizeof(Size), &color, sizeof(Color));
|
||||
return String(h, sizeof(h));
|
||||
}
|
||||
|
||||
virtual Image Make() const {
|
||||
return CreateHorzFadeOut(sz, color);
|
||||
}
|
||||
};
|
||||
|
||||
Image HorzFadeOut(Size sz, Color color)
|
||||
{
|
||||
FadeOutMaker m;
|
||||
m.sz = sz;
|
||||
m.color = color;
|
||||
return MakeImage(m);
|
||||
}
|
||||
|
||||
Image HorzFadeOut(int cx, int cy, Color color)
|
||||
{
|
||||
return HorzFadeOut(Size(cx, cy), color);
|
||||
}
|
||||
|
||||
Image RotateClockwise(const Image& img)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
ImageBuffer ib(sz.cy, sz.cx);
|
||||
for(int x = 0; x < sz.cx; x++)
|
||||
for(int y = 0; y < sz.cy; y++)
|
||||
ib[x][y] = img[sz.cy - y - 1][x];
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image RotateAntiClockwise(const Image& img)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
ImageBuffer ib(sz.cy, sz.cx);
|
||||
for(int x = 0; x < sz.cx; x++)
|
||||
for(int y = 0; y < sz.cy; y++)
|
||||
ib[x][y] = img[y][sz.cx - x - 1];
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image MirrorHorz(const Image& img)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
Image h = img;
|
||||
ImageBuffer ib(h);
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
RGBA *b = ib[y] + 0;
|
||||
RGBA *e = b + sz.cx - 1;
|
||||
while(b < e) {
|
||||
Swap(*b, *e);
|
||||
b++;
|
||||
e--;
|
||||
}
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image MirrorVert(const Image& img)
|
||||
{
|
||||
Size sz = img.GetSize();
|
||||
Image h = img;
|
||||
ImageBuffer ib(h);
|
||||
|
||||
for(int y = 0; y < sz.cy / 2; y++) {
|
||||
RGBA *b = ib[y];
|
||||
RGBA *e = ib[sz.cy - y - 1];
|
||||
for(int x = 0; x < sz.cx; x++) {
|
||||
Swap(*b, *e);
|
||||
b++;
|
||||
e++;
|
||||
}
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
Image Magnify(const Image& img, int nx, int ny)
|
||||
{
|
||||
if(nx == 1 && ny == 1)
|
||||
return img;
|
||||
if(nx == 0 || ny == 0)
|
||||
return Image();
|
||||
Size sz = img.GetSize();
|
||||
bool xdown = nx < 0;
|
||||
nx = abs(nx);
|
||||
int ncx = xdown ? sz.cx / nx : sz.cx * nx;
|
||||
ImageBuffer b(ncx, sz.cy * ny);
|
||||
const RGBA *s = ~img;
|
||||
const RGBA *e = s + img.GetLength();
|
||||
RGBA *t = ~b;
|
||||
while(s < e) {
|
||||
RGBA *q = t;
|
||||
const RGBA *le = s + sz.cx;
|
||||
while(s < le) {
|
||||
Fill(q, *s, nx);
|
||||
q += nx;
|
||||
s++;
|
||||
}
|
||||
for(int n = ny - 1; n--;) {
|
||||
memcpy(q, t, ncx * sizeof(RGBA));
|
||||
q += ncx;
|
||||
}
|
||||
t = q;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static Pointf Cvp(double x, double y, double sina, double cosa)
|
||||
{
|
||||
return Pointf(x * cosa + y * sina, -x * sina + y * cosa);
|
||||
}
|
||||
|
||||
Image Rotate(const Image& m, int angle)
|
||||
{
|
||||
Size isz = m.GetSize();
|
||||
Point center = isz / 2;
|
||||
Pointf centerf = Pointf(Point(isz)) / 2.0;
|
||||
double sina, cosa;
|
||||
Draw::SinCos(-angle, sina, cosa);
|
||||
Pointf p1 = Cvp(-centerf.x, -centerf.y, sina, cosa);
|
||||
Pointf p2 = Cvp(centerf.x, -centerf.y, sina, cosa);
|
||||
Size sz2 = Size(2 * (int)max(tabs(p1.x), tabs(p2.x)),
|
||||
2 * (int)max(tabs(p1.y), tabs(p2.y)));
|
||||
Pointf dcenterf = Sizef(sz2) / 2.0;
|
||||
Point dcenter = sz2 / 2;
|
||||
|
||||
ImageBuffer ib(sz2);
|
||||
Fill(~ib, RGBAZero(), ib.GetLength());
|
||||
RGBA *t = ~ib;
|
||||
Draw::SinCos(angle, sina, cosa);
|
||||
int sini = int(sina * 128);
|
||||
int cosi = int(cosa * 128);
|
||||
Buffer<int> xmx(sz2.cx);
|
||||
Buffer<int> xmy(sz2.cx);
|
||||
for(int x = 0; x < sz2.cx; x++) {
|
||||
int xx = x + x - sz2.cx;
|
||||
xmx[x] = int(xx * cosi);
|
||||
xmy[x] = -int(xx * sini);
|
||||
}
|
||||
for(int y = 0; y < sz2.cy; y++) {
|
||||
int yy = y + y - sz2.cy;
|
||||
int ymx = int(yy * sini) + (isz.cx << 7);
|
||||
int ymy = int(yy * cosi) + (isz.cy << 7);
|
||||
for(int x = 0; x < sz2.cx; x++) {
|
||||
int xs = (xmx[x] + ymx) >> 8;
|
||||
int ys = (xmy[x] + ymy) >> 8;
|
||||
*t++ = xs >= 0 && xs < isz.cx && ys >= 0 && ys < isz.cy ? m[ys][xs] : RGBAZero();
|
||||
}
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
156
archive/olddraw/Draw/ImageOp.h
Normal file
156
archive/olddraw/Draw/ImageOp.h
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
Image CreateImage(Size sz, Color color);
|
||||
Image SetColorKeepAlpha(const Image& img, Color c);
|
||||
|
||||
Image WithHotSpots(const Image& m, int x1, int y1, int x2, int y2);
|
||||
Image WithHotSpot(const Image& m, int x1, int y1);
|
||||
|
||||
void Over(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Copy(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
|
||||
void Copy(Image& dest, Point p, const Image& src, const Rect& srect);
|
||||
void Over(Image& dest, Point p, const Image& src, const Rect& srect);
|
||||
|
||||
void OverStraightOpaque(ImageBuffer& dest, Point p, const Image& src, const Rect& srect);
|
||||
void OverStraightOpaque(Image& dest, Point p, const Image& _src, const Rect& srect);
|
||||
|
||||
void Crop(RasterEncoder& tgt, Raster& img, const Rect& rc);
|
||||
Image Crop(const Image& img, const Rect& rc);
|
||||
Image Crop(const Image& img, int x, int y, int cx, int cy);
|
||||
|
||||
Image ColorMask(const Image& src, Color transparent);
|
||||
|
||||
void CanvasSize(RasterEncoder& tgt, Raster& img, int cx, int cy);
|
||||
Image CanvasSize(const Image& img, int cx, int cy);
|
||||
|
||||
Image AssignAlpha(const Image& img, const Image& new_alpha);
|
||||
|
||||
Image Grayscale(const Image& img);
|
||||
Image Grayscale(const Image& img, int amount);
|
||||
Image Contrast(const Image& img, int amount = 256);
|
||||
|
||||
Image HorzFadeOut(int cx, int cy, Color color);
|
||||
Image HorzFadeOut(Size sz, Color color);
|
||||
|
||||
class RescaleImage {
|
||||
Raster *src;
|
||||
Size tsz;
|
||||
Vector<dword> horz;
|
||||
Vector<dword> vert;
|
||||
void (*row_proc)(dword *dest, const RGBA *src, const dword *map);
|
||||
Size size;
|
||||
int cx4;
|
||||
int count;
|
||||
int segment;
|
||||
int entry;
|
||||
int step;
|
||||
int segspan;
|
||||
bool bigseg;
|
||||
Buffer<dword> row_buffers;
|
||||
int first;
|
||||
int full;
|
||||
const dword *offsets;
|
||||
int offset;
|
||||
int y;
|
||||
|
||||
struct Ln {
|
||||
RasterLine line;
|
||||
int ii;
|
||||
};
|
||||
|
||||
Ln cache[4];
|
||||
int cii;
|
||||
const RGBA *GetLine(int i);
|
||||
|
||||
public:
|
||||
void Create(Size sz, Raster& src, const Rect& src_rc);
|
||||
void Get(RGBA *line);
|
||||
};
|
||||
|
||||
void DrawRasterData(Draw& w, int x, int y, int cx, int cy, const String& data);
|
||||
|
||||
bool Rescale(RasterEncoder& tgt, Size sz, Raster& src, const Rect& src_rc,
|
||||
Gate2<int, int> progress = false);
|
||||
Image Rescale(const Image& src, Size sz, const Rect& src_rc, Gate2<int, int> progress = false);
|
||||
Image Rescale(const Image& src, Size sz, Gate2<int, int> progress = false);
|
||||
Image Rescale(const Image& src, int cx, int cy, Gate2<int, int> progress = false);
|
||||
|
||||
struct ImageFilter9 {
|
||||
virtual RGBA operator()(const RGBA **mx) = 0;
|
||||
virtual ~ImageFilter9() {}
|
||||
};
|
||||
|
||||
Image Filter(const Image& img, ImageFilter9& filter);
|
||||
void Filter(RasterEncoder& target, Raster& src, ImageFilter9& filter);
|
||||
|
||||
Image Etched(const Image& img);
|
||||
Image Sharpen(const Image& img, int amount = 100);
|
||||
|
||||
Image RotateClockwise(const Image& img);
|
||||
Image RotateAntiClockwise(const Image& img);
|
||||
Image MirrorHorz(const Image& img);
|
||||
Image MirrorVert(const Image& img);
|
||||
Image Rotate(const Image& m, int angle);
|
||||
|
||||
// Experimental {
|
||||
Image Colorize(const Image& img, Color color, int alpha = 100);
|
||||
Image Equalight(const Image& img, int thold = 10);
|
||||
// }
|
||||
|
||||
//Chameleon support
|
||||
int Diff(RGBA a, RGBA b);
|
||||
Image Unglyph(const Image& m, Color& c, double& factor);
|
||||
Image Unglyph(const Image& m, Color& c);
|
||||
Image Unglyph(const Image& m);
|
||||
Image VertBlend(Image img1, Image img2, int y0, int y1);
|
||||
Image HorzBlend(Image img1, Image img2, int x0, int x1);
|
||||
Image HorzSymm(Image src);
|
||||
|
||||
enum {
|
||||
IMAGECONTENT_VERTDUP = 1,
|
||||
IMAGECONTENT_HORZDUP = 2,
|
||||
IMAGECONTENT_OPAQUEBODY = 4,
|
||||
};
|
||||
|
||||
int ClassifyContent(const Image& m, const Rect& rect);
|
||||
|
||||
Image RecreateAlpha(const Image& overwhite, const Image& overblack);
|
||||
int ImageMargin(const Image& m, int p, int dist);
|
||||
int ImageMarginV(const Image& _m, int p, int dist);
|
||||
|
||||
struct ChPartMaker {
|
||||
Image image;
|
||||
Color border;
|
||||
Color bg;
|
||||
|
||||
bool t, b, l, r;
|
||||
byte tl, tr, bl, br;
|
||||
|
||||
void ResetShape();
|
||||
Image Make() const;
|
||||
|
||||
ChPartMaker(const Image& m);
|
||||
};
|
||||
|
||||
// Image cache
|
||||
|
||||
struct ImageMaker {
|
||||
virtual String Key() const = 0;
|
||||
virtual Image Make() const = 0;
|
||||
virtual ~ImageMaker() {}
|
||||
};
|
||||
|
||||
Image MakeImage(const ImageMaker& m);
|
||||
Image MakeImage(const Image& image, Image (*make)(const Image& image));
|
||||
|
||||
void ClearMakeImageCache();
|
||||
void SetMakeImageCacheSize(int m);
|
||||
void SetMakeImageCacheMax(int m);
|
||||
|
||||
Image MakeImagePaintOnly(const ImageMaker& m);
|
||||
|
||||
Image CachedRescale(const Image& m, Size sz, const Rect& src);
|
||||
Image CachedRescale(const Image& m, Size sz);
|
||||
Image CachedRescalePaintOnly(const Image& m, Size sz, const Rect& src);
|
||||
Image CachedRescalePaintOnly(const Image& m, Size sz);
|
||||
|
||||
Image Magnify(const Image& img, int nx, int ny);
|
||||
511
archive/olddraw/Draw/ImageScale.cpp
Normal file
511
archive/olddraw/Draw/ImageScale.cpp
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
enum
|
||||
{
|
||||
MAXAA = 4,
|
||||
|
||||
MAP_COUNT = 0,
|
||||
MAP_SEGMENT = 1,
|
||||
MAP_BLOCK = 2,
|
||||
MAP_STEP = 3,
|
||||
MAP_DATA = 4,
|
||||
};
|
||||
|
||||
enum { LOG2_STRETCH_CURVE = 10, COUNT_STRETCH_CURVE = 1 << LOG2_STRETCH_CURVE };
|
||||
|
||||
static const byte *GetStretchCurve()
|
||||
{
|
||||
static byte cache[COUNT_STRETCH_CURVE];
|
||||
ONCELOCK {
|
||||
for(int i = 0; i < COUNT_STRETCH_CURVE; i++)
|
||||
{
|
||||
enum { HALF = COUNT_STRETCH_CURVE >> 1 };
|
||||
double a = (i <= HALF ? i / double(HALF) : (COUNT_STRETCH_CURVE - i) / double(HALF));
|
||||
double o = pow(a, 0.85);
|
||||
cache[i] = minmax<int>((int)((i <= HALF ? o : 2 - o) * 128), 0, 255);
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
Vector<dword> AAGetMap(int& dmin, int& dmax, int dclipmin, int dclipmax,
|
||||
int smin, int smax, int sclipmin, int sclipmax, int times, int avail)
|
||||
{
|
||||
Vector<dword> map;
|
||||
if(dmax == dmin || smax == smin)
|
||||
return map;
|
||||
if(dmax < dmin)
|
||||
{
|
||||
Swap(dmin, dmax);
|
||||
Swap(smin, smax);
|
||||
}
|
||||
int dw = dmax - dmin, sw = smax - smin, spos;
|
||||
if(sw > 0)
|
||||
{
|
||||
int x0 = dmin;
|
||||
if(smin < sclipmin)
|
||||
x0 += iscalefloor(sclipmin - smin, dw, sw);
|
||||
if(x0 < dclipmin)
|
||||
x0 = dclipmin;
|
||||
spos = smin * dw + (x0 - dmin) * sw;
|
||||
dmin = x0;
|
||||
if(smax > sclipmax)
|
||||
dmax -= iscalefloor(smax - sclipmax, dw, sw);
|
||||
if(dmax > dclipmax)
|
||||
dmax = dclipmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
int x0 = dmin;
|
||||
if(smin > sclipmax)
|
||||
x0 += iscalefloor(sclipmax - smin, dw, sw);
|
||||
if(x0 < dclipmin)
|
||||
x0 = dclipmin;
|
||||
spos = smin * dw + (x0 - dmin) * sw;
|
||||
dmin = x0;
|
||||
if(smax < sclipmin)
|
||||
dmax -= iscalefloor(smax - sclipmin, dw, sw);
|
||||
Swap(smin, smax);
|
||||
}
|
||||
int count = min(dclipmax, dmax) - dmin;
|
||||
if(smin < sclipmin)
|
||||
smin = sclipmin;
|
||||
if(smax > sclipmax)
|
||||
smax = sclipmax;
|
||||
if(smax <= smin || count <= 0)
|
||||
return map;
|
||||
int span = min(tabs(sw) % dw ? idivceil(tabs(sw), dw) + 1 : tabs(sw) / dw, smax - smin);
|
||||
bool bigseg = (span >= MAXAA);
|
||||
int segment = (bigseg ? MAXAA : span);
|
||||
int segstep = span / segment;
|
||||
map.SetCount(4 + count * (bigseg ? 1 : 1 + segment));
|
||||
map[MAP_COUNT] = dword(count);
|
||||
map[MAP_SEGMENT] = dword(segment);
|
||||
map[MAP_BLOCK] = 1 + (bigseg ? 0 : segment);
|
||||
map[MAP_STEP] = (span / segment) * times;
|
||||
dword *out = map.Begin() + MAP_DATA;
|
||||
int sendoffset = (smax - (segment - 1) * segstep - 1) * times;
|
||||
int last = 0;
|
||||
|
||||
if(smax - smin == 1)
|
||||
{
|
||||
ASSERT(segment == 1);
|
||||
dword dval = dword(smin * times);
|
||||
*out++ = dval;
|
||||
*out++ = avail;
|
||||
while(--count > 0)
|
||||
{
|
||||
*out++ = 0;
|
||||
*out++ = avail;
|
||||
}
|
||||
}
|
||||
else if(tabs(sw) >= dw)
|
||||
{ // size reduction
|
||||
int sbegin = smin * dw, send = smax * dw, aw = tabs(sw);
|
||||
for(spos += min(sw, 0); --count >= 0; spos += sw)
|
||||
{
|
||||
int pb = max(spos, sbegin), pe = min(spos + aw, send);
|
||||
int total = pe - pb, left = avail;
|
||||
int start = idivfloor(pb, dw), end = idivceil(pe, dw) - 1, rem = pb % dw;
|
||||
// DUMP(start);
|
||||
// DUMP(end);
|
||||
if(pb >= send)
|
||||
{
|
||||
last += *out++ = sendoffset - last;
|
||||
if(!bigseg)
|
||||
{
|
||||
int i = segment - 1;
|
||||
while(--i >= 0)
|
||||
*out++ = 0;
|
||||
*out++ = left;
|
||||
}
|
||||
}
|
||||
else if(end <= start)
|
||||
{ // 1 source pixel only
|
||||
// ASSERT(!bigseg);
|
||||
int scomp = minmax(start + segment - smax, 0, start - smin);
|
||||
last += *out++ = (start - scomp) * times - last;
|
||||
if(!bigseg)
|
||||
{
|
||||
int i = scomp;
|
||||
while(--i >= 0)
|
||||
*out++ = 0;
|
||||
*out++ = dword(left);
|
||||
i = segment - scomp - 1;
|
||||
while(--i >= 0)
|
||||
*out++ = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int delta = (dw - rem) * left / total;
|
||||
if(!delta)
|
||||
start++;
|
||||
int scomp = minmax(start + span - smax, 0, start - smin);
|
||||
last += *out++ = (start - scomp) * times - last;
|
||||
if(!bigseg)
|
||||
{
|
||||
int i = scomp;
|
||||
while(--i >= 0)
|
||||
*out++ = 0;
|
||||
i = segment - scomp;
|
||||
if(delta)
|
||||
{
|
||||
*out++ = delta;
|
||||
left -= delta;
|
||||
total -= dw - rem;
|
||||
i--;
|
||||
}
|
||||
while(++start < end)
|
||||
{
|
||||
ASSERT(i > 0);
|
||||
delta = dw * left / total;
|
||||
*out++ = delta;
|
||||
left -= delta;
|
||||
total -= dw;
|
||||
--i;
|
||||
}
|
||||
if(left > 0)
|
||||
{
|
||||
ASSERT(i > 0);
|
||||
*out++ = left;
|
||||
--i;
|
||||
}
|
||||
while(--i >= 0)
|
||||
*out++ = 0;
|
||||
}
|
||||
}
|
||||
// LOG("-> " << map[rec] << " + " << map[rec + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // size inflation
|
||||
static const byte *curve = GetStretchCurve();
|
||||
ASSERT(segment == 2 && !bigseg);
|
||||
int sbegin = smin * dw, send = (smax - 1) * dw;
|
||||
for(spos += (sw - dw) >> 1; --count >= 0; spos += sw)
|
||||
{
|
||||
if(spos <= sbegin)
|
||||
{
|
||||
last += out[0] = smin * times - last;
|
||||
out[1] = avail;
|
||||
out[2] = 0;
|
||||
}
|
||||
else if(spos >= send)
|
||||
{
|
||||
last += out[0] = sendoffset - last;
|
||||
out[1] = 0;
|
||||
out[2] = avail;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = spos / dw;
|
||||
int rel = spos % dw;
|
||||
last += out[0] = pos * times - last;
|
||||
out[1] = avail - (out[2] = curve[rel * COUNT_STRETCH_CURVE / dw]);
|
||||
}
|
||||
out += 3;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
ASSERT(out == map.End());
|
||||
int offs = 0, step = map[MAP_BLOCK], segspan = (map[MAP_SEGMENT] - 1) * map[MAP_STEP] + 1;
|
||||
for(int t = 0; t < (int)map[MAP_COUNT]; t++)
|
||||
{
|
||||
offs += map[MAP_DATA + t * step];
|
||||
ASSERT(offs >= times * smin && offs + segspan <= times * smax);
|
||||
}
|
||||
#endif
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static void BltAAMapRGBA1(dword *dest, const RGBA *s, const dword *map)
|
||||
{
|
||||
int count = map[MAP_COUNT];
|
||||
map += 4;
|
||||
while(count--) {
|
||||
s += map[0];
|
||||
dest[0] = s->b << 8;
|
||||
dest[1] = s->g << 8;
|
||||
dest[2] = s->r << 8;
|
||||
dest[3] = s->a << 8;
|
||||
map += 2;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void BltAAMapRGBA2(dword *dest, const RGBA *s, const dword *map)
|
||||
{
|
||||
int count = map[MAP_COUNT];
|
||||
map += 4;
|
||||
while(count--) {
|
||||
s += map[0];
|
||||
dest[0] = s[0].b * map[1] + s[1].b * map[2];
|
||||
dest[1] = s[0].g * map[1] + s[1].g * map[2];
|
||||
dest[2] = s[0].r * map[1] + s[1].r * map[2];
|
||||
dest[3] = s[0].a * map[1] + s[1].a * map[2];
|
||||
map += 3;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void BltAAMapRGBA3(dword *dest, const RGBA *s, const dword *map)
|
||||
{
|
||||
int count = map[MAP_COUNT];
|
||||
map += 4;
|
||||
while(count--) {
|
||||
s += map[0];
|
||||
dest[0] = s[0].b * map[1] + s[1].b * map[2] + s[2].b * map[3];
|
||||
dest[1] = s[0].g * map[1] + s[1].g * map[2] + s[2].g * map[3];
|
||||
dest[2] = s[0].r * map[1] + s[1].r * map[2] + s[2].r * map[3];
|
||||
dest[3] = s[0].a * map[1] + s[1].a * map[2] + s[2].a * map[3];
|
||||
map += 4;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void BltAAMapRGBA4(dword *dest, const RGBA *s, const dword *map)
|
||||
{
|
||||
int step = map[MAP_STEP];
|
||||
int count = map[MAP_COUNT];
|
||||
map += 4;
|
||||
while(count--) {
|
||||
s += map[0];
|
||||
dest[0] = (s[0].b + s[step].b + s[2 * step].b + s[3 * step].b) << 6;
|
||||
dest[1] = (s[0].g + s[step].g + s[2 * step].g + s[3 * step].g) << 6;
|
||||
dest[2] = (s[0].r + s[step].r + s[2 * step].r + s[3 * step].r) << 6;
|
||||
dest[3] = (s[0].a + s[step].a + s[2 * step].a + s[3 * step].a) << 6;
|
||||
map += 1;
|
||||
dest += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void BltAASet2Fix(RGBA *dest, const dword *src1, dword w1, const dword *src2, dword w2, int count)
|
||||
{
|
||||
while(count--) {
|
||||
dest->b = byte((src1[0] * w1 + src2[0] * w2) >> 16);
|
||||
dest->g = byte((src1[1] * w1 + src2[1] * w2) >> 16);
|
||||
dest->r = byte((src1[2] * w1 + src2[2] * w2) >> 16);
|
||||
dest->a = byte((src1[3] * w1 + src2[3] * w2) >> 16);
|
||||
dest++;
|
||||
src1 += 4;
|
||||
src2 += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void BltAASet3Fix(RGBA *dest,
|
||||
const dword *src1, dword w1, const dword *src2, dword w2, const dword *src3, dword w3,
|
||||
dword count)
|
||||
{
|
||||
while(count--) {
|
||||
dest->b = byte((src1[0] * w1 + src2[0] * w2 + src3[0] * w3) >> 16);
|
||||
dest->g = byte((src1[1] * w1 + src2[1] * w2 + src3[1] * w3) >> 16);
|
||||
dest->r = byte((src1[2] * w1 + src2[2] * w2 + src3[2] * w3) >> 16);
|
||||
dest->a = byte((src1[3] * w1 + src2[3] * w2 + src3[3] * w3) >> 16);
|
||||
dest++;
|
||||
src1 += 4;
|
||||
src2 += 4;
|
||||
src3 += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void BltAASet4Fix(RGBA *dest, const dword *src1, const dword *src2,
|
||||
const dword *src3, const dword *src4, int count)
|
||||
{
|
||||
while(count--) {
|
||||
dest->b = byte((src1[0] + src2[0] + src3[0] + src4[0]) >> 10);
|
||||
dest->g = byte((src1[1] + src2[1] + src3[1] + src4[1]) >> 10);
|
||||
dest->r = byte((src1[2] + src2[2] + src3[2] + src4[2]) >> 10);
|
||||
dest->a = byte((src1[3] + src2[3] + src3[3] + src4[3]) >> 10);
|
||||
dest++;
|
||||
src1 += 4;
|
||||
src2 += 4;
|
||||
src3 += 4;
|
||||
src4 += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void BltAAFix2(RGBA *dest, const dword *src, int count)
|
||||
{
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
const byte *s = (byte *)src + 1;
|
||||
#else
|
||||
const byte *s = (byte *)src + 2;
|
||||
#endif
|
||||
while(count--) {
|
||||
dest->b = s[0];
|
||||
dest->g = s[4];
|
||||
dest->r = s[8];
|
||||
dest->a = s[12];
|
||||
dest++;
|
||||
s += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void RescaleImage::Create(Size _tsz, Raster& _src, const Rect& src_rc)
|
||||
{
|
||||
y = -1;
|
||||
src = &_src;
|
||||
tsz = _tsz;
|
||||
if(tsz.cx == 0 || tsz.cy == 0)
|
||||
return;
|
||||
|
||||
size = src->GetSize();
|
||||
|
||||
Rect dr = tsz;
|
||||
horz = AAGetMap(dr.left, dr.right, dr.left, dr.right,
|
||||
src_rc.left, src_rc.right, 0, size.cx, 1, 0x100);
|
||||
if(horz.IsEmpty())
|
||||
return;
|
||||
|
||||
vert = AAGetMap(dr.top, dr.bottom, dr.top, dr.bottom,
|
||||
src_rc.top, src_rc.bottom, 0, size.cy, 1, 0x100);
|
||||
if(vert.IsEmpty())
|
||||
return;
|
||||
|
||||
switch(horz[MAP_SEGMENT]) {
|
||||
case 1: row_proc = BltAAMapRGBA1; break;
|
||||
case 2: row_proc = BltAAMapRGBA2; break;
|
||||
case 3: row_proc = BltAAMapRGBA3; break;
|
||||
case 4: row_proc = BltAAMapRGBA4; break;
|
||||
default: NEVER(); return;
|
||||
}
|
||||
|
||||
cx4 = 4 * tsz.cx;
|
||||
count = vert[MAP_COUNT];
|
||||
segment = vert[MAP_SEGMENT];
|
||||
entry = vert[MAP_BLOCK];
|
||||
step = vert[MAP_STEP];
|
||||
segspan = (segment - 1) * step + 1;
|
||||
bigseg = (segment == MAXAA);
|
||||
row_buffers.Alloc(cx4 * segment);
|
||||
first = vert[4];
|
||||
full = 0;
|
||||
offsets = vert.GetIter(4);
|
||||
offset = 0;
|
||||
y = 0;
|
||||
cii = 0;
|
||||
cache[0].ii = cache[1].ii = cache[2].ii = cache[3].ii = -1;
|
||||
}
|
||||
|
||||
const RGBA *RescaleImage::GetLine(int ii)
|
||||
{
|
||||
if(cache[0].ii == ii)
|
||||
return cache[0].line;
|
||||
if(cache[1].ii == ii)
|
||||
return cache[1].line;
|
||||
if(cache[2].ii == ii)
|
||||
return cache[2].line;
|
||||
if(cache[3].ii == ii)
|
||||
return cache[3].line;
|
||||
cache[cii].line = (*src)[ii];
|
||||
cache[cii].ii = ii;
|
||||
const RGBA *l = cache[cii].line;
|
||||
cii = (cii + 1) % 4;
|
||||
return l;
|
||||
}
|
||||
|
||||
void RescaleImage::Get(RGBA *tgt)
|
||||
{
|
||||
if(y < 0 || offsets >= vert.End()) {
|
||||
memset(tgt, 0, sizeof(RGBA) * tsz.cx);
|
||||
return;
|
||||
}
|
||||
offset += *offsets++;
|
||||
ASSERT(offset >= 0 && offset + segspan <= size.cy);
|
||||
if(bigseg) {
|
||||
row_proc(&row_buffers[0 * cx4], GetLine(offset + 0 * step), horz);
|
||||
row_proc(&row_buffers[1 * cx4], GetLine(offset + 1 * step), horz);
|
||||
row_proc(&row_buffers[2 * cx4], GetLine(offset + 2 * step), horz);
|
||||
row_proc(&row_buffers[3 * cx4], GetLine(offset + 3 * step), horz);
|
||||
BltAASet4Fix(tgt, &row_buffers[0 * cx4], &row_buffers[1 * cx4],
|
||||
&row_buffers[2 * cx4], &row_buffers[3 * cx4], tsz.cx);
|
||||
}
|
||||
else {
|
||||
int endoff = offset + segment;
|
||||
for(int next = first + full; next < endoff; next++) {
|
||||
if(full >= segment)
|
||||
first++;
|
||||
else
|
||||
full++;
|
||||
row_proc(&row_buffers[next % segment * cx4], GetLine(next), horz);
|
||||
}
|
||||
while(first > offset) {
|
||||
if(full < segment)
|
||||
full++;
|
||||
--first;
|
||||
row_proc(&row_buffers[first % segment * cx4], GetLine(first), horz);
|
||||
}
|
||||
ASSERT(offset >= first && endoff <= first + full);
|
||||
switch(segment) {
|
||||
case 1:
|
||||
BltAAFix2(tgt, &row_buffers[offset % segment * cx4], tsz.cx);
|
||||
offsets++;
|
||||
break;
|
||||
case 2:
|
||||
if(offsets[0] == 0)
|
||||
BltAAFix2(tgt, &row_buffers[(offset + 1) % segment * cx4], tsz.cx);
|
||||
else
|
||||
if(offsets[1] == 0)
|
||||
BltAAFix2(tgt, &row_buffers[offset % segment * cx4], tsz.cx);
|
||||
else
|
||||
BltAASet2Fix(tgt, &row_buffers[(offset + 0) % segment * cx4], offsets[0],
|
||||
&row_buffers[(offset + 1) % segment * cx4], offsets[1],
|
||||
tsz.cx);
|
||||
offsets += 2;
|
||||
break;
|
||||
case 3:
|
||||
BltAASet3Fix(tgt,
|
||||
&row_buffers[(offset + 0) % segment * cx4], offsets[0],
|
||||
&row_buffers[(offset + 1) % segment * cx4], offsets[1],
|
||||
&row_buffers[(offset + 2) % segment * cx4], offsets[2], tsz.cx);
|
||||
offsets += 3;
|
||||
break;
|
||||
default:
|
||||
NEVER();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Rescale(RasterEncoder& tgt, Size tsz, Raster& src, const Rect& src_rc,
|
||||
Gate2<int, int> progress)
|
||||
{
|
||||
tgt.Create(tsz, src);
|
||||
RescaleImage rs;
|
||||
rs.Create(tsz, src, src_rc);
|
||||
for(int i = 0; i < tsz.cy; i++) {
|
||||
if(progress(i, tsz.cy))
|
||||
return false;
|
||||
rs.Get(tgt);
|
||||
tgt.WriteLine();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Image Rescale(const Image& src, Size sz, const Rect& src_rc, Gate2<int, int> progress)
|
||||
{
|
||||
if(src.GetSize() == sz && src_rc == sz)
|
||||
return src;
|
||||
ImageRaster isrc(src);
|
||||
ImageEncoder tgt;
|
||||
Rescale(tgt, sz, isrc, src_rc);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
Image Rescale(const Image& src, Size sz, Gate2<int, int> progress)
|
||||
{
|
||||
return Rescale(src, sz, src.GetSize());
|
||||
}
|
||||
|
||||
Image Rescale(const Image& src, int cx, int cy, Gate2<int, int> progress)
|
||||
{
|
||||
return Rescale(src, Size(cx, cy));
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
614
archive/olddraw/Draw/ImageWin32.cpp
Normal file
614
archive/olddraw/Draw/ImageWin32.cpp
Normal file
|
|
@ -0,0 +1,614 @@
|
|||
#include "Draw.h"
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#define LTIMING(x) // RTIMING(x)
|
||||
|
||||
bool ImageFallBack
|
||||
// = true
|
||||
;
|
||||
|
||||
class BitmapInfo32__ {
|
||||
Buffer<byte> data;
|
||||
|
||||
public:
|
||||
operator BITMAPINFO *() { return (BITMAPINFO *)~data; }
|
||||
operator BITMAPINFOHEADER *() { return (BITMAPINFOHEADER *)~data; }
|
||||
BITMAPINFOHEADER *operator->() { return (BITMAPINFOHEADER *)~data; }
|
||||
|
||||
BitmapInfo32__(int cx, int cy);
|
||||
};
|
||||
|
||||
BitmapInfo32__::BitmapInfo32__(int cx, int cy)
|
||||
{
|
||||
data.Alloc(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
|
||||
BITMAPINFOHEADER *hi = (BITMAPINFOHEADER *) ~data;;
|
||||
memset(hi, 0, sizeof(BITMAPINFOHEADER));
|
||||
hi->biSize = sizeof(BITMAPINFOHEADER);
|
||||
hi->biPlanes = 1;
|
||||
#ifdef PLATFORM_WINCE
|
||||
hi->biBitCount = 32;
|
||||
hi->biCompression = BI_BITFIELDS;
|
||||
dword *x = (dword *)(~data + sizeof(BITMAPINFOHEADER));
|
||||
x[2] = 0xff;
|
||||
x[1] = 0xff00;
|
||||
x[0] = 0xff0000;
|
||||
#else
|
||||
hi->biBitCount = 32;
|
||||
hi->biCompression = BI_RGB;
|
||||
#endif
|
||||
hi->biSizeImage = 0;
|
||||
hi->biClrUsed = 0;
|
||||
hi->biClrImportant = 0;
|
||||
hi->biWidth = cx;
|
||||
hi->biHeight = -cy;
|
||||
}
|
||||
|
||||
HBITMAP CreateBitMask(const RGBA *data, Size sz, Size tsz, Size csz, RGBA *ct)
|
||||
{
|
||||
DrawLock __;
|
||||
memset(ct, 0, tsz.cx * tsz.cy * sizeof(RGBA));
|
||||
int linelen = (tsz.cx + 15) >> 4 << 1;
|
||||
Buffer<byte> mask(tsz.cy * linelen, 0xff);
|
||||
byte *m = mask;
|
||||
RGBA *ty = ct;
|
||||
const RGBA *sy = data;
|
||||
for(int y = 0; y < csz.cy; y++) {
|
||||
const RGBA *s = sy;
|
||||
RGBA *t = ty;
|
||||
for(int x = 0; x < csz.cx; x++) {
|
||||
if(s->a > 128) {
|
||||
*t = *s;
|
||||
m[x >> 3] &= ~(0x80 >> (x & 7));
|
||||
}
|
||||
else
|
||||
t->r = t->g = t->b = 0;
|
||||
t->a = 0;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
m += linelen;
|
||||
sy += sz.cx;
|
||||
ty += tsz.cx;
|
||||
}
|
||||
return ::CreateBitmap(tsz.cx, tsz.cy, 1, 1, mask);
|
||||
}
|
||||
|
||||
void SetSurface(HDC dc, int x, int y, int cx, int cy, const RGBA *pixels)
|
||||
{
|
||||
DrawLock __;
|
||||
BitmapInfo32__ bi(cx, cy);
|
||||
::SetDIBitsToDevice(dc, x, y, cx, cy, 0, 0, 0, cy, pixels,
|
||||
bi, DIB_RGB_COLORS);
|
||||
}
|
||||
|
||||
void SetSurface(Draw& w, int x, int y, int cx, int cy, const RGBA *pixels)
|
||||
{
|
||||
SetSurface(w.GetHandle(), x, y, cx, cy, pixels);
|
||||
}
|
||||
|
||||
class DrawSurface : NoCopy {
|
||||
int x, y;
|
||||
Size size;
|
||||
RGBA *pixels;
|
||||
HDC dc, dcMem;
|
||||
HBITMAP hbmp, hbmpOld;
|
||||
|
||||
void Init(Draw& w, int x, int y, int cx, int cy);
|
||||
RGBA* Line(int i) const { ASSERT(i >= 0 && i < size.cy); return (RGBA *)pixels + size.cx * (size.cy - i - 1); }
|
||||
|
||||
public:
|
||||
operator RGBA *() { return pixels; }
|
||||
Size GetSize() const { return size; }
|
||||
RGBA *operator[](int i) { return Line(i); }
|
||||
const RGBA *operator[](int i) const { return Line(i); }
|
||||
int GetLineDelta() const { return -size.cx; }
|
||||
|
||||
DrawSurface(Draw& w, const Rect& r);
|
||||
DrawSurface(Draw& w, int x, int y, int cx, int cy);
|
||||
~DrawSurface();
|
||||
};
|
||||
|
||||
void DrawSurface::Init(Draw& w, int _x, int _y, int cx, int cy)
|
||||
{
|
||||
DrawLock __;
|
||||
dc = w.GetHandle();
|
||||
size = Size(cx, cy);
|
||||
x = _x;
|
||||
y = _y;
|
||||
dcMem = ::CreateCompatibleDC(dc);
|
||||
BitmapInfo32__ bi(cx, cy);
|
||||
hbmp = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
|
||||
hbmpOld = (HBITMAP) ::SelectObject(dcMem, hbmp);
|
||||
::BitBlt(dcMem, 0, 0, cx, cy, dc, x, y, SRCCOPY);
|
||||
}
|
||||
|
||||
DrawSurface::DrawSurface(Draw& w, const Rect& r)
|
||||
{
|
||||
Init(w, r.left, r.top, r.Width(), r.Height());
|
||||
}
|
||||
|
||||
DrawSurface::DrawSurface(Draw& w, int x, int y, int cx, int cy)
|
||||
{
|
||||
Init(w, x, y, cx, cy);
|
||||
}
|
||||
|
||||
DrawSurface::~DrawSurface()
|
||||
{
|
||||
DrawLock __;
|
||||
::BitBlt(dc, x, y, size.cx, size.cy, dcMem, 0, 0, SRCCOPY);
|
||||
::DeleteObject(::SelectObject(dcMem, hbmpOld));
|
||||
::DeleteDC(dcMem);
|
||||
}
|
||||
|
||||
void Image::Data::SysInit()
|
||||
{
|
||||
hbmp = hmask = himg = NULL;
|
||||
cursor_cheat = NULL;
|
||||
}
|
||||
|
||||
void Image::Data::SysRelease()
|
||||
{
|
||||
if(hbmp) {
|
||||
DrawLock __;
|
||||
DeleteObject(hbmp);
|
||||
ResCount -= !paintonly;
|
||||
}
|
||||
if(hmask) {
|
||||
DrawLock __;
|
||||
DeleteObject(hmask);
|
||||
ResCount -= !paintonly;
|
||||
}
|
||||
if(himg) {
|
||||
DrawLock __;
|
||||
DeleteObject(himg);
|
||||
ResCount -= !paintonly;
|
||||
}
|
||||
himg = hbmp = hmask = NULL;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINCE
|
||||
typedef BOOL (WINAPI *tAlphaBlend)(HDC hdcDest, int nXOriginDest, int nYOriginDest,
|
||||
int nWidthDest, int nHeightDest,
|
||||
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc,
|
||||
int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction);
|
||||
|
||||
static tAlphaBlend fnAlphaBlend()
|
||||
{
|
||||
DrawLock __;
|
||||
static tAlphaBlend pSet;
|
||||
static bool inited = false;
|
||||
if(!inited) {
|
||||
inited = true;
|
||||
if(HMODULE hDLL = LoadLibrary("msimg32.dll"))
|
||||
pSet = (tAlphaBlend) GetProcAddress(hDLL, "AlphaBlend");
|
||||
}
|
||||
return pSet;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Image::Data::CreateHBMP(HDC dc, const RGBA *data)
|
||||
{
|
||||
DrawLock __;
|
||||
Size sz = buffer.GetSize();
|
||||
BitmapInfo32__ bi(sz.cx, sz.cy);
|
||||
HDC dcMem = ::CreateCompatibleDC(dc);
|
||||
RGBA *pixels;
|
||||
HBITMAP hbmp32 = CreateDIBSection(dcMem, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
|
||||
HDC hbmpOld = (HDC) ::SelectObject(dcMem, hbmp32);
|
||||
memcpy(pixels, data, buffer.GetLength() * sizeof(RGBA));
|
||||
HDC dcMem2 = ::CreateCompatibleDC(dc);
|
||||
hbmp = ::CreateCompatibleBitmap(dc, sz.cx, sz.cy);
|
||||
HBITMAP o2 = (HBITMAP)::SelectObject(dcMem2, hbmp);
|
||||
::BitBlt(dcMem2, 0, 0, sz.cx, sz.cy, dcMem, 0, 0, SRCCOPY);
|
||||
::SelectObject(dcMem2, o2);
|
||||
::DeleteDC(dcMem2);
|
||||
::SelectObject(dcMem, hbmpOld);
|
||||
::DeleteObject(hbmp32);
|
||||
::DeleteDC(dcMem);
|
||||
ResCount++;
|
||||
}
|
||||
|
||||
void Image::Data::Paint(Draw& w, int x, int y, const Rect& src, Color c)
|
||||
{
|
||||
DrawLock __;
|
||||
ASSERT(!paintonly || IsNull(c));
|
||||
int max = IsWinNT() ? 250 : 100;
|
||||
while(ResCount > max) {
|
||||
Image::Data *l = ResData->GetPrev();
|
||||
l->SysRelease();
|
||||
l->Unlink();
|
||||
}
|
||||
HDC dc = w.GetHandle();
|
||||
Size sz = buffer.GetSize();
|
||||
int len = sz.cx * sz.cy;
|
||||
Rect sr = src & sz;
|
||||
Size ssz = sr.Size();
|
||||
if(sr.IsEmpty())
|
||||
return;
|
||||
if(GetKind() == IMAGE_EMPTY)
|
||||
return;
|
||||
if(GetKind() == IMAGE_OPAQUE && !IsNull(c)) {
|
||||
w.DrawRect(x, y, sz.cx, sz.cy, c);
|
||||
return;
|
||||
}
|
||||
if(GetKind() == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz) && !w.IsMetaFile()
|
||||
&& IsWinNT() && !w.IsPrinter()) {
|
||||
LTIMING("Image Opaque direct set");
|
||||
SetSurface(w, x, y, sz.cx, sz.cy, buffer);
|
||||
paintcount++;
|
||||
return;
|
||||
}
|
||||
Unlink();
|
||||
LinkAfter(ResData);
|
||||
if(GetKind() == IMAGE_OPAQUE) {
|
||||
if(!hbmp) {
|
||||
LTIMING("Image Opaque create");
|
||||
CreateHBMP(dc, buffer);
|
||||
}
|
||||
LTIMING("Image Opaque blit");
|
||||
HDC dcMem = ::CreateCompatibleDC(dc);
|
||||
HBITMAP o = (HBITMAP)::SelectObject(dcMem, hbmp);
|
||||
::BitBlt(dc, x, y, ssz.cx, ssz.cy, dcMem, sr.left, sr.top, SRCCOPY);
|
||||
::SelectObject(dcMem, o);
|
||||
::DeleteDC(dcMem);
|
||||
PaintOnlyShrink();
|
||||
return;
|
||||
}
|
||||
if(GetKind() == IMAGE_MASK/* || GetKind() == IMAGE_OPAQUE*/) {
|
||||
HDC dcMem = ::CreateCompatibleDC(dc);
|
||||
if(!hmask) {
|
||||
LTIMING("Image Mask create");
|
||||
Buffer<RGBA> bmp(len);
|
||||
hmask = CreateBitMask(buffer, sz, sz, sz, bmp);
|
||||
ResCount++;
|
||||
if(!hbmp)
|
||||
CreateHBMP(dc, bmp);
|
||||
}
|
||||
LTIMING("Image Mask blt");
|
||||
HBITMAP o = (HBITMAP)::SelectObject(dcMem, ::CreateCompatibleBitmap(dc, sz.cx, sz.cy));
|
||||
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dc, x, y, SRCCOPY);
|
||||
HDC dcMem2 = ::CreateCompatibleDC(dc);
|
||||
::SelectObject(dcMem2, hmask);
|
||||
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, SRCAND);
|
||||
if(IsNull(c)) {
|
||||
::SelectObject(dcMem2, hbmp);
|
||||
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, SRCPAINT);
|
||||
}
|
||||
else {
|
||||
HBRUSH ho = (HBRUSH) SelectObject(dcMem, CreateSolidBrush(c));
|
||||
::BitBlt(dcMem, 0, 0, ssz.cx, ssz.cy, dcMem2, sr.left, sr.top, 0xba0b09);
|
||||
::DeleteObject(::SelectObject(dcMem, ho));
|
||||
}
|
||||
::BitBlt(dc, x, y, ssz.cx, ssz.cy, dcMem, 0, 0, SRCCOPY);
|
||||
::DeleteObject(::SelectObject(dcMem, o));
|
||||
::DeleteDC(dcMem2);
|
||||
::DeleteDC(dcMem);
|
||||
PaintOnlyShrink();
|
||||
return;
|
||||
}
|
||||
#ifndef PLATFORM_WINCE
|
||||
if(fnAlphaBlend() && IsNull(c) && !ImageFallBack) {
|
||||
if(!himg) {
|
||||
LTIMING("Image Alpha create");
|
||||
BitmapInfo32__ bi(sz.cx, sz.cy);
|
||||
himg = CreateDIBSection(ScreenHDC(), bi, DIB_RGB_COLORS,
|
||||
(void **)§ion, NULL, 0);
|
||||
ResCount++;
|
||||
memcpy(section, ~buffer, buffer.GetLength() * sizeof(RGBA));
|
||||
}
|
||||
LTIMING("Image Alpha blit");
|
||||
BLENDFUNCTION bf;
|
||||
bf.BlendOp = AC_SRC_OVER;
|
||||
bf.BlendFlags = 0;
|
||||
bf.SourceConstantAlpha = 255;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
HDC dcMem = ::CreateCompatibleDC(dc);
|
||||
::SelectObject(dcMem, himg);
|
||||
fnAlphaBlend()(dc, x, y, ssz.cx, ssz.cy, dcMem, sr.left, sr.top, ssz.cx, ssz.cy, bf);
|
||||
::DeleteDC(dcMem);
|
||||
PaintOnlyShrink();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
LTIMING("Image Alpha sw");
|
||||
DrawSurface sf(w, x, y, ssz.cx, ssz.cy);
|
||||
RGBA *t = sf;
|
||||
for(int i = sr.top; i < sr.bottom; i++) {
|
||||
if(IsNull(c))
|
||||
AlphaBlendOpaque(t, buffer[i] + sr.left, ssz.cx);
|
||||
else
|
||||
AlphaBlendOpaque(t, buffer[i] + sr.left, ssz.cx, c);
|
||||
t += ssz.cx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageDraw::Section::Init(int cx, int cy)
|
||||
{
|
||||
DrawLock __;
|
||||
dc = ::CreateCompatibleDC(ScreenHDC());
|
||||
BitmapInfo32__ bi(cx, cy);
|
||||
hbmp = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
|
||||
hbmpOld = (HBITMAP) ::SelectObject(dc, hbmp);
|
||||
}
|
||||
|
||||
ImageDraw::Section::~Section()
|
||||
{
|
||||
DrawLock __;
|
||||
::DeleteObject(::SelectObject(dc, hbmpOld));
|
||||
::DeleteDC(dc);
|
||||
}
|
||||
|
||||
void ImageDraw::Init()
|
||||
{
|
||||
DrawLock __;
|
||||
rgb.Init(size.cx, size.cy);
|
||||
a.Init(size.cx, size.cy);
|
||||
Attach(rgb.dc);
|
||||
alpha.Attach(a.dc);
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
Image ImageDraw::Get(bool pm) const
|
||||
{
|
||||
ImageBuffer b(size);
|
||||
int n = size.cx * size.cy;
|
||||
memcpy(~b, rgb.pixels, n * sizeof(RGBA));
|
||||
const RGBA *s = a.pixels;
|
||||
const RGBA *e = a.pixels + n;
|
||||
RGBA *t = b;
|
||||
if(has_alpha) {
|
||||
while(s < e) {
|
||||
t->a = s->r;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
if(pm)
|
||||
Premultiply(b);
|
||||
b.SetKind(IMAGE_ALPHA);
|
||||
}
|
||||
else {
|
||||
while(s < e) {
|
||||
t->a = 255;
|
||||
t++;
|
||||
s++;
|
||||
}
|
||||
b.SetKind(IMAGE_OPAQUE);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
ImageDraw::operator Image() const
|
||||
{
|
||||
return Get(true);
|
||||
}
|
||||
|
||||
Image ImageDraw::GetStraight() const
|
||||
{
|
||||
return Get(false);
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(Size sz)
|
||||
{
|
||||
size = sz;
|
||||
Init();
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(int cx, int cy)
|
||||
{
|
||||
size = Size(cx, cy);
|
||||
Init();
|
||||
}
|
||||
|
||||
ImageDraw::~ImageDraw()
|
||||
{
|
||||
Detach();
|
||||
alpha.Detach();
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINCE
|
||||
|
||||
Image Image::Arrow() { return Null; }
|
||||
Image Image::Wait() { return Null; }
|
||||
Image Image::IBeam() { return Null; }
|
||||
Image Image::No() { return Null; }
|
||||
Image Image::SizeAll() { return Null; }
|
||||
Image Image::SizeHorz() { return Null; }
|
||||
Image Image::SizeVert() { return Null; }
|
||||
Image Image::SizeTopLeft() { return Null; }
|
||||
Image Image::SizeTop() { return Null; }
|
||||
Image Image::SizeTopRight() { return Null; }
|
||||
Image Image::SizeLeft() { return Null; }
|
||||
Image Image::SizeRight() { return Null; }
|
||||
Image Image::SizeBottomLeft() { return Null; }
|
||||
Image Image::SizeBottom() { return Null; }
|
||||
Image Image::SizeBottomRight() { return Null; }
|
||||
|
||||
#else
|
||||
|
||||
static Image sWin32Icon(HICON icon, bool cursor)
|
||||
{
|
||||
DrawLock __;
|
||||
ICONINFO iconinfo;
|
||||
if(!icon || !GetIconInfo(icon, &iconinfo))
|
||||
return Image();
|
||||
BITMAP bm;
|
||||
::GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm);
|
||||
HDC dcMem = ::CreateCompatibleDC(NULL);
|
||||
Size sz(bm.bmWidth, bm.bmHeight);
|
||||
BitmapInfo32__ bi(sz.cx, sz.cy);
|
||||
int len = sz.cx * sz.cy;
|
||||
Buffer<RGBA> mask(len);
|
||||
::SelectObject(dcMem, iconinfo.hbmColor);
|
||||
::GetDIBits(dcMem, iconinfo.hbmMask, 0, sz.cy, ~mask, bi, DIB_RGB_COLORS);
|
||||
ImageBuffer b(sz.cx, iconinfo.hbmColor ? sz.cy : sz.cy / 2);
|
||||
b.SetHotSpot(Point(iconinfo.xHotspot, iconinfo.yHotspot));
|
||||
if(iconinfo.hbmColor) {
|
||||
::SelectObject(dcMem, iconinfo.hbmColor);
|
||||
::GetDIBits(dcMem, iconinfo.hbmColor, 0, sz.cy, ~b, bi, DIB_RGB_COLORS);
|
||||
RGBA *s = ~b;
|
||||
RGBA *e = s + len;
|
||||
RGBA *m = mask;
|
||||
while(s < e) {
|
||||
if(s->a != 255 && s->a != 0) {
|
||||
Premultiply(b);
|
||||
goto alpha;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
s = ~b;
|
||||
while(s < e) {
|
||||
s->a = m->r ? 0 : 255;
|
||||
s++;
|
||||
m++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
len /= 2;
|
||||
RGBA *s = ~b;
|
||||
RGBA *e = s + len;
|
||||
RGBA *c = mask + len;
|
||||
RGBA *m = mask;
|
||||
while(s < e) {
|
||||
s->a = (m->r & ~c->r) ? 0 : 255;
|
||||
s->r = s->g = s->b = (c->r & ~m->r) ? 255 : 0;
|
||||
s++;
|
||||
m++;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
alpha:
|
||||
::DeleteDC(dcMem);
|
||||
::DeleteObject(iconinfo.hbmColor);
|
||||
::DeleteObject(iconinfo.hbmMask);
|
||||
Image img(b);
|
||||
::DestroyIcon(icon);
|
||||
return img;
|
||||
}
|
||||
|
||||
Image Win32IconCursor(LPCSTR id, int iconsize, bool cursor)
|
||||
{
|
||||
HICON icon;
|
||||
if(cursor)
|
||||
icon = (HICON)LoadCursor(0, id);
|
||||
else
|
||||
if(iconsize)
|
||||
icon = (HICON)LoadImage(GetModuleHandle(NULL), id,
|
||||
IMAGE_ICON, iconsize, iconsize, LR_DEFAULTCOLOR);
|
||||
else
|
||||
icon = LoadIcon(0, id);
|
||||
Image img = sWin32Icon(icon, cursor);
|
||||
if(cursor)
|
||||
img.SetCursorCheat(id);
|
||||
return img;
|
||||
}
|
||||
|
||||
Image Win32DllIcon(const char *dll, int ii, bool large)
|
||||
{
|
||||
HICON icon;
|
||||
if(ExtractIconEx(dll, ii, large ? &icon : NULL, large ? NULL : &icon, 1) == 1)
|
||||
return sWin32Icon(icon, false);
|
||||
return Null;
|
||||
}
|
||||
|
||||
Image Win32Icon(LPCSTR id, int iconsize)
|
||||
{
|
||||
return Win32IconCursor(id, iconsize, false);
|
||||
}
|
||||
|
||||
Image Win32Icon(int id, int iconsize)
|
||||
{
|
||||
return Win32Icon(MAKEINTRESOURCE(id), iconsize);
|
||||
}
|
||||
|
||||
Image Win32Cursor(LPCSTR id)
|
||||
{
|
||||
return Win32IconCursor(id, 0, true);
|
||||
}
|
||||
|
||||
Image Win32Cursor(int id)
|
||||
{
|
||||
return Win32Cursor(MAKEINTRESOURCE(id));
|
||||
}
|
||||
|
||||
HICON IconWin32(const Image& img, bool cursor)
|
||||
{
|
||||
DrawLock __;
|
||||
if(img.IsEmpty())
|
||||
return NULL;
|
||||
if(cursor) {
|
||||
LPCSTR id = img.GetCursorCheat();
|
||||
if(id)
|
||||
return (HICON)LoadCursor(0, id);
|
||||
}
|
||||
Size sz = img.GetSize();
|
||||
ICONINFO iconinfo;
|
||||
iconinfo.fIcon = !cursor;
|
||||
Point p = img.GetHotSpot();
|
||||
iconinfo.xHotspot = p.x;
|
||||
iconinfo.yHotspot = p.y;
|
||||
static Size cursor_size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
|
||||
Size tsz = sz;
|
||||
if(!IsWin2K() && cursor)
|
||||
tsz = cursor_size;
|
||||
Size csz = Size(min(tsz.cx, sz.cx), min(tsz.cy, sz.cy));
|
||||
if(IsWinXP() && !ImageFallBack) {
|
||||
RGBA *pixels;
|
||||
BitmapInfo32__ bi(tsz.cx, tsz.cy);
|
||||
HDC dcMem = ::CreateCompatibleDC(NULL);
|
||||
iconinfo.hbmColor = ::CreateDIBSection(dcMem, bi, DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
|
||||
iconinfo.hbmMask = ::CreateBitmap(tsz.cx, tsz.cy, 1, 1, NULL);
|
||||
memset(pixels, 0, tsz.cx * tsz.cy * sizeof(RGBA));
|
||||
for(int y = 0; y < csz.cy; y++)
|
||||
memcpy(pixels + y * tsz.cx, img[y], csz.cx * sizeof(RGBA));
|
||||
::DeleteDC(dcMem);
|
||||
}
|
||||
else {
|
||||
Buffer<RGBA> h(tsz.cx * tsz.cy);
|
||||
HDC dc = ::GetDC(NULL);
|
||||
BitmapInfo32__ bi(tsz.cx, tsz.cy);
|
||||
iconinfo.hbmMask = CreateBitMask(~img, sz, tsz, csz, h);
|
||||
iconinfo.hbmColor = ::CreateDIBitmap(dc, bi, CBM_INIT, h, bi, DIB_RGB_COLORS);
|
||||
::ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
HICON icon = ::CreateIconIndirect(&iconinfo);
|
||||
::DeleteObject(iconinfo.hbmColor);
|
||||
::DeleteObject(iconinfo.hbmMask);
|
||||
return icon;
|
||||
}
|
||||
|
||||
#define WCURSOR_(x)\
|
||||
{ Image m; INTERLOCKED { static Image img = Win32Cursor(x); m = img; } return m; }
|
||||
|
||||
Image Image::Arrow() WCURSOR_(IDC_ARROW)
|
||||
Image Image::Wait() WCURSOR_(IDC_WAIT)
|
||||
Image Image::IBeam() WCURSOR_(IDC_IBEAM)
|
||||
Image Image::No() WCURSOR_(IDC_NO)
|
||||
Image Image::SizeAll() WCURSOR_(IDC_SIZEALL)
|
||||
Image Image::SizeHorz() WCURSOR_(IDC_SIZEWE)
|
||||
Image Image::SizeVert() WCURSOR_(IDC_SIZENS)
|
||||
Image Image::SizeTopLeft() WCURSOR_(IDC_SIZENWSE)
|
||||
Image Image::SizeTop() WCURSOR_(IDC_SIZENS)
|
||||
Image Image::SizeTopRight() WCURSOR_(IDC_SIZENESW)
|
||||
Image Image::SizeLeft() WCURSOR_(IDC_SIZEWE)
|
||||
Image Image::SizeRight() WCURSOR_(IDC_SIZEWE)
|
||||
Image Image::SizeBottomLeft() WCURSOR_(IDC_SIZENESW)
|
||||
Image Image::SizeBottom() WCURSOR_(IDC_SIZENS)
|
||||
Image Image::SizeBottomRight() WCURSOR_(IDC_SIZENWSE)
|
||||
Image Image::Cross() WCURSOR_(IDC_CROSS)
|
||||
Image Image::Hand() WCURSOR_(IDC_HAND)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
406
archive/olddraw/Draw/ImageX11.cpp
Normal file
406
archive/olddraw/Draw/ImageX11.cpp
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_X11
|
||||
|
||||
static void sInitXImage(XImage& ximg, Size sz)
|
||||
{
|
||||
Zero(ximg);
|
||||
ximg.width = sz.cx;
|
||||
ximg.height = sz.cy;
|
||||
ximg.xoffset = 0;
|
||||
ximg.format = ZPixmap;
|
||||
ximg.bitmap_bit_order = MSBFirst;
|
||||
#ifdef CPU_LITTLE_ENDIAN
|
||||
ximg.byte_order = LSBFirst;
|
||||
#else
|
||||
ximg.byte_order = MSBFirst;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetSurface(Draw& w, int x, int y, int cx, int cy, const RGBA *pixels)
|
||||
{
|
||||
DrawLock __;
|
||||
Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, cx, cy, 24);
|
||||
XPicture picture = XRenderCreatePicture(
|
||||
Xdisplay, pixmap,
|
||||
XRenderFindStandardFormat(Xdisplay, PictStandardRGB24),
|
||||
0, 0
|
||||
);
|
||||
XImage ximg;
|
||||
sInitXImage(ximg, Size(cx, cy));
|
||||
ximg.bitmap_pad = 32;
|
||||
ximg.bytes_per_line = 4 * cx;
|
||||
ximg.bits_per_pixel = 32;
|
||||
ximg.blue_mask = 0x00ff0000;
|
||||
ximg.green_mask = 0x0000ff00;
|
||||
ximg.red_mask = 0x000000ff;
|
||||
Buffer<RGBA> pma;
|
||||
ximg.bitmap_unit = 32;
|
||||
ximg.depth = 24;
|
||||
ximg.data = (char *)pixels;
|
||||
XInitImage(&ximg);
|
||||
GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
|
||||
XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, cx, cy);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
XFreePixmap(Xdisplay, pixmap);
|
||||
XRenderComposite(Xdisplay, PictOpOver,
|
||||
picture, 0, XftDrawPicture(w.GetXftDraw()),
|
||||
0, 0, 0, 0, x, y, cx, cy);
|
||||
XRenderFreePicture(Xdisplay, picture);
|
||||
}
|
||||
|
||||
void Image::Data::SysInit()
|
||||
{
|
||||
picture = 0;
|
||||
picture8 = 0;
|
||||
cursor_cheat = -1;
|
||||
}
|
||||
|
||||
void Image::Data::SysRelease()
|
||||
{
|
||||
if(picture) {
|
||||
DrawLock __;
|
||||
if(Xdisplay) XRenderFreePicture(Xdisplay, picture);
|
||||
ResCount -= !paintonly;
|
||||
picture = 0;
|
||||
}
|
||||
if(picture8) {
|
||||
DrawLock __;
|
||||
if(Xdisplay) XRenderFreePicture(Xdisplay, picture8);
|
||||
ResCount -= !paintonly;
|
||||
picture8 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct XRSolidFill {
|
||||
Color color;
|
||||
XPicture picture;
|
||||
Pixmap pixmap;
|
||||
};
|
||||
|
||||
enum { XRSolidFillCount = 67 };
|
||||
|
||||
static XRSolidFill sFill[XRSolidFillCount];
|
||||
|
||||
inline int s255d16(int x)
|
||||
{
|
||||
return (x << 8)|x;
|
||||
}
|
||||
|
||||
static XPicture sGetSolidFill(Color c)
|
||||
{
|
||||
DrawLock __;
|
||||
int q = GetHashValue(c) % (int)XRSolidFillCount;
|
||||
XRSolidFill& f = sFill[q];
|
||||
if(f.color == c && f.picture)
|
||||
return f.picture;
|
||||
if(f.picture)
|
||||
XRenderFreePicture(Xdisplay, f.picture);
|
||||
if(f.pixmap)
|
||||
XFreePixmap(Xdisplay, f.pixmap);
|
||||
f.pixmap = XCreatePixmap(Xdisplay, Xroot, 1, 1, 32);
|
||||
XRenderPictureAttributes attr;
|
||||
attr.repeat = XTrue;
|
||||
f.picture = XRenderCreatePicture(Xdisplay, f.pixmap,
|
||||
XRenderFindStandardFormat(Xdisplay, PictStandardARGB32),
|
||||
CPRepeat, &attr);
|
||||
f.color = c;
|
||||
XRenderColor xc;
|
||||
xc.red = s255d16(c.GetR());
|
||||
xc.green = s255d16(c.GetG());
|
||||
xc.blue = s255d16(c.GetB());
|
||||
xc.alpha = 65535;
|
||||
XRenderFillRectangle(Xdisplay, PictOpSrc, f.picture, &xc, 0, 0, 1, 1);
|
||||
return f.picture;
|
||||
}
|
||||
|
||||
void Image::Data::Paint(Draw& w, int x, int y, const Rect& src, Color c)
|
||||
{
|
||||
DrawLock __;
|
||||
while(ResCount > 512) {
|
||||
Image::Data *l = ResData->GetPrev();
|
||||
l->SysRelease();
|
||||
l->Unlink();
|
||||
}
|
||||
x += w.GetOffset().x;
|
||||
y += w.GetOffset().y;
|
||||
Size sz = buffer.GetSize();
|
||||
int len = sz.cx * sz.cy;
|
||||
Rect sr = src & sz;
|
||||
Size ssz = sr.Size();
|
||||
if(sr.IsEmpty())
|
||||
return;
|
||||
if(GetKind() == IMAGE_EMPTY)
|
||||
return;
|
||||
if(GetKind() == IMAGE_OPAQUE && !IsNull(c)) {
|
||||
w.DrawRect(x, y, sz.cx, sz.cy, c);
|
||||
return;
|
||||
}
|
||||
if(GetKind() == IMAGE_OPAQUE && paintcount == 0 && sr == Rect(sz)) {
|
||||
SetSurface(w, x, y, sz.cx, sz.cy, buffer);
|
||||
paintcount++;
|
||||
return;
|
||||
}
|
||||
Unlink();
|
||||
LinkAfter(ResData);
|
||||
if(IsNull(c)) {
|
||||
if(!picture) {
|
||||
bool opaque = GetKind() == IMAGE_OPAQUE;
|
||||
Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, opaque ? 24 : 32);
|
||||
picture = XRenderCreatePicture(
|
||||
Xdisplay, pixmap,
|
||||
XRenderFindStandardFormat(Xdisplay, opaque ? PictStandardRGB24
|
||||
: PictStandardARGB32),
|
||||
0, 0
|
||||
);
|
||||
ResCount++;
|
||||
XImage ximg;
|
||||
sInitXImage(ximg, sz);
|
||||
ximg.bitmap_pad = 32;
|
||||
ximg.bytes_per_line = 4 * sz.cx;
|
||||
ximg.bits_per_pixel = 32;
|
||||
ximg.blue_mask = 0x00ff0000;
|
||||
ximg.green_mask = 0x0000ff00;
|
||||
ximg.red_mask = 0x000000ff;
|
||||
ximg.bitmap_unit = 32;
|
||||
ximg.data = (char *)~buffer;
|
||||
ximg.depth = opaque ? 24 : 32;
|
||||
XInitImage(&ximg);
|
||||
GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
|
||||
XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
XFreePixmap(Xdisplay, pixmap);
|
||||
PaintOnlyShrink();
|
||||
}
|
||||
XRenderComposite(Xdisplay, PictOpOver,
|
||||
picture, 0, XftDrawPicture(w.GetXftDraw()),
|
||||
sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy);
|
||||
}
|
||||
else {
|
||||
ASSERT(!paintonly);
|
||||
if(!picture8) {
|
||||
Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 8);
|
||||
picture8 = XRenderCreatePicture(Xdisplay, pixmap,
|
||||
XRenderFindStandardFormat(Xdisplay, PictStandardA8),
|
||||
0, 0);
|
||||
ResCount++;
|
||||
Buffer<byte> ab(len);
|
||||
byte *t = ab;
|
||||
const RGBA *s = buffer;
|
||||
const RGBA *e = s + len;
|
||||
while(s < e)
|
||||
*t++ = (s++)->a;
|
||||
XImage ximg;
|
||||
sInitXImage(ximg, sz);
|
||||
ximg.data = (char *)~ab;
|
||||
ximg.bitmap_unit = 8;
|
||||
ximg.bitmap_pad = 8;
|
||||
ximg.depth = 8;
|
||||
ximg.bytes_per_line = sz.cx;
|
||||
ximg.bits_per_pixel = 8;
|
||||
XInitImage(&ximg);
|
||||
GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
|
||||
XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
XFreePixmap(Xdisplay, pixmap);
|
||||
}
|
||||
XRenderComposite(Xdisplay, PictOpOver,
|
||||
sGetSolidFill(c), picture8, XftDrawPicture(w.GetXftDraw()),
|
||||
sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageDraw::Init()
|
||||
{
|
||||
DrawLock __;
|
||||
dw = XCreatePixmap(Xdisplay, Xroot, max(size.cx, 1), max(size.cy, 1), Xdepth);
|
||||
gc = XCreateGC(Xdisplay, dw, 0, 0);
|
||||
xftdraw = XftDrawCreate(Xdisplay, (Drawable) dw, DefaultVisual(Xdisplay, Xscreenno), Xcolormap);
|
||||
|
||||
alpha.dw = XCreatePixmap(Xdisplay, Xroot, max(size.cx, 1), max(size.cy, 1), Xdepth);
|
||||
alpha.gc = XCreateGC(Xdisplay, alpha.dw, 0, 0);
|
||||
alpha.xftdraw = XftDrawCreate(Xdisplay, (Drawable) alpha.dw, DefaultVisual(Xdisplay, Xscreenno), Xcolormap);
|
||||
|
||||
Vector<Rect> clip;
|
||||
clip.Add(RectC(0, 0, size.cx, size.cy));
|
||||
Draw::Init(clip, Point(0, 0));
|
||||
alpha.Init(clip, Point(0, 0));
|
||||
|
||||
has_alpha = false;
|
||||
}
|
||||
|
||||
ImageDraw::operator Image() const
|
||||
{
|
||||
DrawLock __;
|
||||
XImage *xim = XGetImage(Xdisplay, dw, 0, 0, max(size.cx, 1), max(size.cy, 1), AllPlanes, ZPixmap);
|
||||
Visual *v = DefaultVisual(Xdisplay, Xscreenno);
|
||||
RasterFormat fmt;
|
||||
|
||||
RGBA palette[256];
|
||||
|
||||
switch(xim->depth) {
|
||||
case 15:
|
||||
case 16:
|
||||
if(xim->byte_order == LSBFirst)
|
||||
fmt.Set16le(v->red_mask, v->green_mask, v->blue_mask);
|
||||
else
|
||||
fmt.Set16be(v->red_mask, v->green_mask, v->blue_mask);
|
||||
break;
|
||||
case 8: {
|
||||
int n = min(v->map_entries, 256);
|
||||
XColor colors[256];
|
||||
for(int i = 0; i < 256; i++) {
|
||||
colors[i].pixel = i;
|
||||
colors[i].flags = DoRed|DoGreen|DoBlue;
|
||||
}
|
||||
XQueryColors(Xdisplay, Xcolormap, colors, n);
|
||||
XColor *s = colors;
|
||||
XColor *e = s + n;
|
||||
while(s < e) {
|
||||
RGBA& t = palette[s->pixel];
|
||||
t.r = s->red >> 8;
|
||||
t.g = s->green >> 8;
|
||||
t.b = s->blue >> 8;
|
||||
t.a = 255;
|
||||
s++;
|
||||
}
|
||||
fmt.Set8();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if(xim->bits_per_pixel == 32)
|
||||
if(xim->byte_order == LSBFirst)
|
||||
fmt.Set32le(v->red_mask, v->green_mask, v->blue_mask);
|
||||
else
|
||||
fmt.Set32be(v->red_mask, v->green_mask, v->blue_mask);
|
||||
else
|
||||
if(xim->byte_order == LSBFirst)
|
||||
fmt.Set24le(v->red_mask, v->green_mask, v->blue_mask);
|
||||
else
|
||||
fmt.Set24be(v->red_mask, v->green_mask, v->blue_mask);
|
||||
break;
|
||||
}
|
||||
|
||||
ImageBuffer ib(size);
|
||||
const byte *s = (const byte *)xim->data;
|
||||
RGBA *t = ib;
|
||||
for(int y = 0; y < size.cy; y++) {
|
||||
fmt.Read(t, s, size.cx, palette);
|
||||
s += xim->bytes_per_line;
|
||||
t += size.cx;
|
||||
}
|
||||
XDestroyImage(xim);
|
||||
if(has_alpha) {
|
||||
xim = XGetImage(Xdisplay, alpha.dw, 0, 0, size.cx, size.cy, AllPlanes, ZPixmap);
|
||||
const byte *s = (const byte *)xim->data;
|
||||
t = ib;
|
||||
Buffer<RGBA> line(size.cx);
|
||||
for(int y = 0; y < size.cy; y++) {
|
||||
fmt.Read(line, s, size.cx, palette);
|
||||
for(int x = 0; x < size.cx; x++)
|
||||
(t++)->a = line[x].r;
|
||||
s += xim->bytes_per_line;
|
||||
}
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
Premultiply(ib);
|
||||
return ib;
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(Size sz)
|
||||
{
|
||||
size = sz;
|
||||
Init();
|
||||
}
|
||||
|
||||
ImageDraw::ImageDraw(int cx, int cy)
|
||||
{
|
||||
size = Size(cx, cy);
|
||||
Init();
|
||||
}
|
||||
|
||||
ImageDraw::~ImageDraw()
|
||||
{
|
||||
DrawLock __;
|
||||
XftDrawDestroy(xftdraw);
|
||||
XFreePixmap(Xdisplay, dw);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
XftDrawDestroy(alpha.xftdraw);
|
||||
XFreePixmap(Xdisplay, alpha.dw);
|
||||
XFreeGC(Xdisplay, alpha.gc);
|
||||
}
|
||||
|
||||
Image sX11Cursor__(int c)
|
||||
{
|
||||
ImageBuffer b(32, 32);
|
||||
Image m(b);
|
||||
m.SetCursorCheat(c);
|
||||
return m;
|
||||
}
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#define FCURSOR_(x) { Image h; INTERLOCKED { static Image m = sX11Cursor__(x); h = m; } return h; }
|
||||
|
||||
Image Image::Arrow() FCURSOR_(XC_left_ptr)
|
||||
Image Image::Wait() FCURSOR_(XC_watch)
|
||||
Image Image::IBeam() FCURSOR_(XC_xterm)
|
||||
Image Image::No() FCURSOR_(XC_circle)
|
||||
Image Image::SizeAll() FCURSOR_(XC_fleur)
|
||||
Image Image::SizeHorz() FCURSOR_(XC_sb_h_double_arrow)
|
||||
Image Image::SizeVert() FCURSOR_(XC_double_arrow)
|
||||
Image Image::SizeTopLeft() FCURSOR_(XC_top_left_corner)
|
||||
Image Image::SizeTop() FCURSOR_(XC_top_side)
|
||||
Image Image::SizeTopRight() FCURSOR_(XC_top_right_corner)
|
||||
Image Image::SizeLeft() FCURSOR_(XC_left_side)
|
||||
Image Image::SizeRight() FCURSOR_(XC_right_side)
|
||||
Image Image::SizeBottomLeft() FCURSOR_(XC_bottom_left_corner)
|
||||
Image Image::SizeBottom() FCURSOR_(XC_bottom_side)
|
||||
Image Image::SizeBottomRight() FCURSOR_(XC_bottom_right_corner)
|
||||
Image Image::Cross() FCURSOR_(XC_crosshair)
|
||||
Image Image::Hand() FCURSOR_(XC_hand1)
|
||||
|
||||
Cursor X11Cursor(const Image& img)
|
||||
{
|
||||
DrawLock __;
|
||||
int q = img.GetCursorCheat();
|
||||
if(q >= 0)
|
||||
return XCreateFontCursor(Xdisplay, q);
|
||||
int len = img.GetLength();
|
||||
Size sz = img.GetSize();
|
||||
Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 32);
|
||||
XPicture picture = XRenderCreatePicture(
|
||||
Xdisplay, pixmap,
|
||||
XRenderFindStandardFormat(Xdisplay, PictStandardARGB32),
|
||||
0, 0
|
||||
);
|
||||
XImage ximg;
|
||||
sInitXImage(ximg, sz);
|
||||
ximg.bitmap_pad = 32;
|
||||
ximg.bytes_per_line = 4 * sz.cx;
|
||||
ximg.bits_per_pixel = 32;
|
||||
ximg.blue_mask = 0x00ff0000;
|
||||
ximg.green_mask = 0x0000ff00;
|
||||
ximg.red_mask = 0x000000ff;
|
||||
Buffer<RGBA> pma;
|
||||
pma.Alloc(len);
|
||||
memcpy(pma, ~img, len * sizeof(RGBA));
|
||||
ximg.bitmap_unit = 32;
|
||||
ximg.depth = 32;
|
||||
ximg.data = (char *)~pma;
|
||||
XInitImage(&ximg);
|
||||
GC gc = XCreateGC(Xdisplay, pixmap, 0, 0);
|
||||
XPutImage(Xdisplay, pixmap, gc, &ximg, 0, 0, 0, 0, sz.cx, sz.cy);
|
||||
XFreeGC(Xdisplay, gc);
|
||||
XFreePixmap(Xdisplay, pixmap);
|
||||
Point p = img.GetHotSpot();
|
||||
Cursor c = XRenderCreateCursor(Xdisplay, picture, p.x, p.y);
|
||||
XRenderFreePicture(Xdisplay, picture);
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
176
archive/olddraw/Draw/MakeCache.cpp
Normal file
176
archive/olddraw/Draw/MakeCache.cpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
static StaticCriticalSection sMakeImage;
|
||||
|
||||
static LRUCache<Image>& sImageCache()
|
||||
{
|
||||
static LRUCache<Image> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
struct scImageMaker : LRUCache<Image>::Maker {
|
||||
const ImageMaker *m;
|
||||
bool paintonly;
|
||||
|
||||
virtual String Key() const {
|
||||
// String q = m->Key();
|
||||
return m->Key();
|
||||
}
|
||||
virtual int Make(Image& object) const {
|
||||
object = m->Make();
|
||||
if(paintonly) {
|
||||
SetPaintOnly___(object);
|
||||
return object.GetLength() + 20000;
|
||||
}
|
||||
return object.GetLength() + 100;
|
||||
}
|
||||
};
|
||||
|
||||
static int sMaxSize;
|
||||
static int sMaxSizeMax = 4000000;
|
||||
|
||||
void ClearMakeImageCache()
|
||||
{
|
||||
sImageCache().Clear();
|
||||
}
|
||||
|
||||
void SetMakeImageCacheMax(int m)
|
||||
{
|
||||
sMaxSizeMax = m;
|
||||
}
|
||||
|
||||
void SetMakeImageCacheSize(int m)
|
||||
{
|
||||
sMaxSize = m;
|
||||
}
|
||||
|
||||
void SweepMkImageCache()
|
||||
{
|
||||
INTERLOCKED_(sMakeImage) {
|
||||
LRUCache<Image>& cache = sImageCache();
|
||||
cache.ClearCounters();
|
||||
}
|
||||
}
|
||||
|
||||
Image MakeImage__(const ImageMaker& m, bool paintonly)
|
||||
{
|
||||
Image result;
|
||||
INTERLOCKED_(sMakeImage) {
|
||||
LRUCache<Image>& cache = sImageCache();
|
||||
scImageMaker cm;
|
||||
cm.m = &m;
|
||||
cm.paintonly = paintonly;
|
||||
result = cache.Get(cm);
|
||||
int q = min(cache.GetFoundSize() + cache.GetNewSize(), sMaxSizeMax);
|
||||
if(q > sMaxSize) {
|
||||
sMaxSize = q;
|
||||
LLOG("ImageCache: Increasing maxsize to " << sMaxSize);
|
||||
}
|
||||
cache.Shrink(sMaxSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Image MakeImage(const ImageMaker& m)
|
||||
{
|
||||
return MakeImage__(m, false);
|
||||
}
|
||||
|
||||
Image MakeImagePaintOnly(const ImageMaker& m)
|
||||
{
|
||||
return MakeImage__(m, true);
|
||||
}
|
||||
|
||||
class SimpleImageMaker : public ImageMaker {
|
||||
Image (*make)(const Image& image);
|
||||
Image image;
|
||||
|
||||
public:
|
||||
virtual String Key() const;
|
||||
virtual Image Make() const;
|
||||
|
||||
SimpleImageMaker(const Image& image, Image (*make)(const Image& image))
|
||||
: make(make),image(image) {}
|
||||
};
|
||||
|
||||
String SimpleImageMaker::Key() const
|
||||
{
|
||||
String key;
|
||||
int64 k = image.GetSerialId();
|
||||
key.Cat((const char *)&k, sizeof(int64));
|
||||
key.Cat((const char *)&make, sizeof(make));
|
||||
return key;
|
||||
}
|
||||
|
||||
Image SimpleImageMaker::Make() const
|
||||
{
|
||||
return (*make)(image);
|
||||
}
|
||||
|
||||
Image MakeImage(const Image& image, Image (*make)(const Image& image))
|
||||
{
|
||||
return MakeImage(SimpleImageMaker(image, make));
|
||||
}
|
||||
|
||||
struct sCachedRescale : public ImageMaker
|
||||
{
|
||||
Rect src;
|
||||
Size sz;
|
||||
Image img;
|
||||
|
||||
virtual String Key() const {
|
||||
StringBuffer h;
|
||||
RawCat(h, src.left);
|
||||
RawCat(h, src.top);
|
||||
RawCat(h, src.right);
|
||||
RawCat(h, src.bottom);
|
||||
RawCat(h, sz.cx);
|
||||
RawCat(h, sz.cy);
|
||||
RawCat(h, img.GetSerialId());
|
||||
return h;
|
||||
}
|
||||
|
||||
virtual Image Make() const {
|
||||
return Rescale(img, sz, src);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Image CachedRescale(const Image& m, Size sz, const Rect& src)
|
||||
{
|
||||
if(m.GetSize() == sz)
|
||||
return m;
|
||||
sCachedRescale cr;
|
||||
cr.sz = sz;
|
||||
cr.src = src;
|
||||
cr.img = m;
|
||||
return MakeImage(cr);
|
||||
}
|
||||
|
||||
Image CachedRescale(const Image& m, Size sz)
|
||||
{
|
||||
return CachedRescale(m, sz, m.GetSize());
|
||||
}
|
||||
|
||||
Image CachedRescalePaintOnly(const Image& m, Size sz, const Rect& src)
|
||||
{
|
||||
if(m.GetSize() == sz)
|
||||
return m;
|
||||
sCachedRescale cr;
|
||||
cr.sz = sz;
|
||||
cr.src = src;
|
||||
cr.img = m;
|
||||
return MakeImagePaintOnly(cr);
|
||||
}
|
||||
|
||||
Image CachedRescalePaintOnly(const Image& m, Size sz)
|
||||
{
|
||||
return CachedRescalePaintOnly(m, sz, m.GetSize());
|
||||
}
|
||||
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
253
archive/olddraw/Draw/MetaFile.cpp
Normal file
253
archive/olddraw/Draw/MetaFile.cpp
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#ifndef PLATFORM_WINCE
|
||||
|
||||
void WinMetaFile::Init() {
|
||||
hemf = NULL;
|
||||
}
|
||||
|
||||
void WinMetaFile::Paint(Draw& w, const Rect& r) const {
|
||||
ChkP();
|
||||
if(hemf)
|
||||
PlayEnhMetaFile(w, hemf, r);
|
||||
}
|
||||
|
||||
void WinMetaFile::Paint(Draw& w, int x, int y, int cx, int cy) const {
|
||||
Paint(w, RectC(x, y, cx, cy));
|
||||
}
|
||||
|
||||
void WinMetaFile::ReadClipboard() {
|
||||
Clear();
|
||||
if(::IsClipboardFormatAvailable(CF_ENHMETAFILE) && ::OpenClipboard(NULL)) {
|
||||
HENHMETAFILE hemf = (HENHMETAFILE) ::GetClipboardData(CF_ENHMETAFILE);
|
||||
if(hemf) Attach(hemf);
|
||||
::CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
void WinMetaFile::WriteClipboard() const {
|
||||
if(hemf && ::OpenClipboard(NULL)) {
|
||||
::EmptyClipboard();
|
||||
::SetClipboardData(CF_ENHMETAFILE, CopyEnhMetaFile(hemf, NULL));
|
||||
::CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
void WinMetaFile::Clear() {
|
||||
if(hemf && !IsPicked())
|
||||
::DeleteEnhMetaFile(hemf);
|
||||
hemf = NULL;
|
||||
}
|
||||
|
||||
void WinMetaFile::Pick(pick_ WinMetaFile& src) {
|
||||
hemf = src.hemf;
|
||||
size = src.size;
|
||||
src.hemf = (HENHMETAFILE)(intptr_t) 0xffffffff;
|
||||
}
|
||||
|
||||
void WinMetaFile::Copy(const WinMetaFile& src) {
|
||||
hemf = ::CopyEnhMetaFile(src.hemf, NULL);
|
||||
size = src.size;
|
||||
}
|
||||
|
||||
void WinMetaFile::Attach(HENHMETAFILE _hemf) {
|
||||
Clear();
|
||||
ENHMETAHEADER info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.iType = EMR_HEADER;
|
||||
info.nSize = sizeof(info);
|
||||
info.dSignature = ENHMETA_SIGNATURE;
|
||||
if(_hemf && ::GetEnhMetaFileHeader(_hemf, sizeof(info), &info)
|
||||
&& info.rclFrame.left < info.rclFrame.right
|
||||
&& info.rclFrame.top < info.rclFrame.bottom) {
|
||||
size.cx = 600 * (info.rclFrame.right - info.rclFrame.left) / 2540;
|
||||
size.cy = 600 * (info.rclFrame.bottom - info.rclFrame.top) / 2540;
|
||||
hemf = _hemf;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct PLACEABLE_METAFILEHEADER
|
||||
{
|
||||
DWORD key;
|
||||
WORD hmf;
|
||||
short left, top, right, bottom;
|
||||
WORD inch;
|
||||
DWORD reserved;
|
||||
WORD checksum;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
bool WinMetaFile::Load(const char* path) {
|
||||
Clear();
|
||||
FileIn file(path);
|
||||
if(!file.Open(path) || file.GetSize() <= sizeof(ENHMETAHEADER))
|
||||
return false;
|
||||
|
||||
int first = file.Get32le();
|
||||
file.Seek(0);
|
||||
|
||||
HENHMETAFILE hemf;
|
||||
HMETAFILE hMF;
|
||||
Size sz(1000, 1000);
|
||||
|
||||
if(first == 0x9AC6CDD7) {
|
||||
PLACEABLE_METAFILEHEADER mfh;
|
||||
file.Get(&mfh, 22);
|
||||
String bits = LoadStream(file);
|
||||
if((hMF = ::SetMetaFileBitsEx(bits.GetLength(), bits)) == NULL)
|
||||
return false;
|
||||
sz = Size(mfh.right - mfh.left, mfh.bottom - mfh.top);
|
||||
}
|
||||
else
|
||||
if((hemf = ::GetEnhMetaFile(path)) != NULL) {
|
||||
Attach(hemf);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if((LOWORD(first) == 1 || LOWORD(first) == 2) && HIWORD(first) >= sizeof(METAHEADER) / 2) {
|
||||
METAHEADER mh;
|
||||
if(!file.GetAll(&mh, sizeof(mh)))
|
||||
return false;
|
||||
if(mh.mtVersion != 0x100 && mh.mtVersion != 0x300)
|
||||
return false;
|
||||
if((hMF = ::GetMetaFile(path)) == NULL)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
dword len = ::GetMetaFileBitsEx(hMF, 0, NULL);
|
||||
Buffer<byte> bits(len);
|
||||
::GetMetaFileBitsEx(hMF, len, bits);
|
||||
Attach(::SetWinMetaFileBits(len, bits, NULL, NULL));
|
||||
::DeleteMetaFile(hMF);
|
||||
size = sz;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinMetaFile::Serialize(Stream& s) {
|
||||
dword size = 0;
|
||||
if(s.IsStoring()) {
|
||||
if(hemf) {
|
||||
size = ::GetEnhMetaFileBits(hemf, 0, 0);
|
||||
s % size;
|
||||
Buffer<byte> buffer(size);
|
||||
::GetEnhMetaFileBits(hemf, size, buffer);
|
||||
s.SerializeRaw(buffer, size);
|
||||
}
|
||||
else
|
||||
s % size;
|
||||
}
|
||||
else {
|
||||
Clear();
|
||||
s % size;
|
||||
if(size) {
|
||||
Buffer<byte> buffer(size);
|
||||
s.SerializeRaw(buffer, size);
|
||||
HENHMETAFILE hemf = ::SetEnhMetaFileBits(size, buffer);
|
||||
Attach(hemf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WinMetaFile::WinMetaFile(HENHMETAFILE hemf) {
|
||||
Init();
|
||||
Attach(hemf);
|
||||
}
|
||||
|
||||
WinMetaFile::WinMetaFile(HENHMETAFILE hemf, Size sz) {
|
||||
Init();
|
||||
Attach(hemf);
|
||||
size = sz;
|
||||
}
|
||||
|
||||
WinMetaFile::WinMetaFile(const char *file) {
|
||||
Init();
|
||||
Load(file);
|
||||
}
|
||||
|
||||
bool WinMetaFileDraw::Create(HDC hdc, int cx, int cy, const char *app, const char *name, const char *file) {
|
||||
if(handle) Close();
|
||||
|
||||
String s;
|
||||
if(app) s.Cat(app);
|
||||
s.Cat('\0');
|
||||
if(name) s.Cat(name);
|
||||
s.Cat('\0');
|
||||
|
||||
bool del = false;
|
||||
if(!hdc) {
|
||||
hdc = ::GetWindowDC((HWND) NULL);
|
||||
del = true;
|
||||
}
|
||||
size = Size(iscale(cx, 2540, 600), iscale(cy, 2540, 600));
|
||||
|
||||
Rect r = size;
|
||||
|
||||
HDC mfdc = ::CreateEnhMetaFile(hdc, file, r, name || app ? (const char *)s : NULL);
|
||||
if(!mfdc)
|
||||
return false;
|
||||
Size px(max(1, ::GetDeviceCaps(mfdc, HORZRES)), max(1, ::GetDeviceCaps(mfdc, VERTRES)));
|
||||
Size mm(max(1, ::GetDeviceCaps(mfdc, HORZSIZE)), max(1, ::GetDeviceCaps(mfdc, VERTSIZE)));
|
||||
Attach(mfdc);
|
||||
|
||||
Init();
|
||||
|
||||
pixels = false;
|
||||
|
||||
::SetMapMode(handle, MM_ANISOTROPIC);
|
||||
::SetWindowOrgEx(handle, 0, 0, 0);
|
||||
::SetWindowExtEx(handle, 600, 600, 0);
|
||||
::SetViewportOrgEx(handle, 0, 0, 0);
|
||||
::SetViewportExtEx(handle, px.cx * 254 / (10 * mm.cx), px.cy * 254 / (10 * mm.cy), 0);
|
||||
::SelectClipRgn(mfdc, NULL);
|
||||
::IntersectClipRect(mfdc, 0, 0, cx, cy);
|
||||
|
||||
if(del) {
|
||||
::ReleaseDC((HWND) NULL, hdc);
|
||||
hdc = NULL;
|
||||
}
|
||||
|
||||
actual_offset = Point(0, 0);
|
||||
|
||||
printer = false;
|
||||
pixels = false;
|
||||
actual_offset = Point(0, 0);
|
||||
device = -1;
|
||||
aborted = false;
|
||||
palette = false;
|
||||
backdraw = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinMetaFileDraw::Create(int cx, int cy, const char *app, const char *name, const char *file) {
|
||||
return Create(NULL, cx, cy, app, name, file);
|
||||
}
|
||||
|
||||
WinMetaFile WinMetaFileDraw::Close() {
|
||||
HDC hdc = Detach();
|
||||
ASSERT(hdc);
|
||||
return WinMetaFile(CloseEnhMetaFile(hdc), size);
|
||||
}
|
||||
|
||||
WinMetaFileDraw::~WinMetaFileDraw() {
|
||||
if(handle) Close();
|
||||
}
|
||||
|
||||
WinMetaFileDraw::WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app, const char *name, const char *file) {
|
||||
Create(hdc, cx, cy, app, name, file);
|
||||
}
|
||||
|
||||
WinMetaFileDraw::WinMetaFileDraw(int cx, int cy, const char *app, const char *name, const char *file) {
|
||||
Create(cx, cy, app, name, file);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
41
archive/olddraw/Draw/Mt.cpp
Normal file
41
archive/olddraw/Draw/Mt.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
static StaticMutex sGuiLock;
|
||||
|
||||
static thread__ int sGuiLockLevel = 0;
|
||||
|
||||
void EnterGuiMutex()
|
||||
{
|
||||
if(sGuiLockLevel++ == 0)
|
||||
sGuiLock.Enter();
|
||||
}
|
||||
|
||||
void EnterGuiMutex(int n)
|
||||
{
|
||||
if(n > 0) {
|
||||
if(sGuiLockLevel == 0)
|
||||
sGuiLock.Enter();
|
||||
sGuiLockLevel += n;
|
||||
}
|
||||
}
|
||||
|
||||
void LeaveGuiMutex()
|
||||
{
|
||||
ASSERT(sGuiLockLevel > 0);
|
||||
if(--sGuiLockLevel == 0)
|
||||
sGuiLock.Leave();
|
||||
}
|
||||
|
||||
int LeaveGuiMutexAll()
|
||||
{
|
||||
int q = sGuiLockLevel;
|
||||
if(q) {
|
||||
sGuiLock.Leave();
|
||||
sGuiLockLevel = 0;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
281
archive/olddraw/Draw/Palette.cpp
Normal file
281
archive/olddraw/Draw/Palette.cpp
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LTIMING(x)
|
||||
|
||||
struct sPalCv {
|
||||
PaletteCv& cv_pal;
|
||||
const RGBA *palette;
|
||||
int ncolors;
|
||||
bool done[RASTER_MAP_G];
|
||||
struct Ginfo {
|
||||
int dist;
|
||||
byte g;
|
||||
byte ii;
|
||||
};
|
||||
|
||||
enum _n { BINS = 16, BINSHIFT = 11 };
|
||||
|
||||
Ginfo line[BINS][256];
|
||||
Ginfo *eline[BINS];
|
||||
byte *gline;
|
||||
|
||||
static int Sq(int a, int b) { return (a - b) * (a - b); }
|
||||
|
||||
void SetLine(int r, int b);
|
||||
int Get(int g);
|
||||
|
||||
sPalCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal);
|
||||
sPalCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal,
|
||||
int histogram[RASTER_MAP_R][RASTER_MAP_G][RASTER_MAP_B]);
|
||||
};
|
||||
|
||||
void sPalCv::SetLine(int r, int b)
|
||||
{
|
||||
gline = cv_pal.At(r, b);
|
||||
r = 255 * r / (RASTER_MAP_R - 1); //IMPROVE!
|
||||
b = 255 * b / (RASTER_MAP_B - 1);
|
||||
for(int i = 0; i < BINS; i++)
|
||||
eline[i] = line[i];
|
||||
for(int i = 0; i < ncolors; i++) {
|
||||
int dist = Sq(palette[i].r, r) + Sq(palette[i].b, b);
|
||||
int bini = dist >> BINSHIFT;
|
||||
Ginfo *t = eline[bini >= BINS ? BINS - 1 : bini]++;
|
||||
t->dist = dist;
|
||||
t->g = palette[i].g;
|
||||
t->ii = i;
|
||||
}
|
||||
ZeroArray(done);
|
||||
}
|
||||
|
||||
int sPalCv::Get(int g)
|
||||
{
|
||||
if(done[g])
|
||||
return gline[g];
|
||||
int gg = 255 * g / (RASTER_MAP_G - 1);
|
||||
int ii = 0;
|
||||
int dist = INT_MAX;
|
||||
for(int th = 0; th < BINS; th++) {
|
||||
Ginfo *s = line[th];
|
||||
Ginfo *e = eline[th];
|
||||
while(s < e) {
|
||||
int sdist = Sq(s->g, gg) + s->dist;
|
||||
if(sdist < dist) {
|
||||
ii = s->ii;
|
||||
dist = sdist;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if(th < BINS - 1 && dist < ((th + 1) << BINSHIFT))
|
||||
break;
|
||||
}
|
||||
done[g] = true;
|
||||
gline[g] = ii;
|
||||
return ii;
|
||||
}
|
||||
|
||||
sPalCv::sPalCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal)
|
||||
: cv_pal(cv_pal), palette(palette), ncolors(ncolors)
|
||||
{
|
||||
byte ender[256];
|
||||
for(int b = 0; b < RASTER_MAP_B; b++) {
|
||||
ZeroArray(ender);
|
||||
for(int r = 0; r < RASTER_MAP_R; r++) {
|
||||
SetLine(r, b);
|
||||
int g = 0;
|
||||
while(g < RASTER_MAP_G) {
|
||||
int ii = Get(g);
|
||||
int eg = max<int>(g, ender[ii]);
|
||||
if(Get(eg) == ii)
|
||||
while(eg < RASTER_MAP_G - 1 && Get(eg + 1) == ii)
|
||||
eg++;
|
||||
else
|
||||
while(Get(eg) != ii)
|
||||
eg--;
|
||||
ender[ii] = eg;
|
||||
g++;
|
||||
while(g <= eg - 1) {
|
||||
gline[g] = ii;
|
||||
done[g] = true;
|
||||
g++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sPalCv::sPalCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal,
|
||||
int histogram[RASTER_MAP_R][RASTER_MAP_G][RASTER_MAP_B])
|
||||
: cv_pal(cv_pal), palette(palette), ncolors(ncolors)
|
||||
{
|
||||
for(int b = 0; b < RASTER_MAP_B; b++) {
|
||||
for(int r = 0; r < RASTER_MAP_R; r++) {
|
||||
SetLine(r, b);
|
||||
for(int g = 0; g < RASTER_MAP_G; g++)
|
||||
if(histogram[r][g][b])
|
||||
Get(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sPalMaker {
|
||||
int histogram[RASTER_MAP_R][RASTER_MAP_G][RASTER_MAP_B];
|
||||
int colorcount;
|
||||
struct Dim {
|
||||
int l, h;
|
||||
|
||||
operator int() { return h - l; }
|
||||
};
|
||||
enum { G = 0, R = 1, B = 2 };
|
||||
void Copy(Dim *d, Dim *s) { d[R] = s[R]; d[G] = s[G]; d[B] = s[B]; }
|
||||
struct Box {
|
||||
int volume;
|
||||
int colorcount;
|
||||
int population;
|
||||
Dim dim[3];
|
||||
int avg_r, avg_g, avg_b;
|
||||
|
||||
Dim& operator[](int i) { return dim[i]; }
|
||||
};
|
||||
|
||||
void Update(Box& box, int ii);
|
||||
|
||||
sPalMaker(Raster& raster, RGBA *palette, int ncolors);
|
||||
};
|
||||
|
||||
void sPalMaker::Update(Box& x, int ii)
|
||||
{
|
||||
x.colorcount = 0;
|
||||
x.population = 0;
|
||||
int a[3][RASTER_MAP_MAX];
|
||||
ZeroArray(a[R]);
|
||||
ZeroArray(a[G]);
|
||||
ZeroArray(a[B]);
|
||||
x.avg_r = x.avg_g = x.avg_b = 0;
|
||||
for(int r = x[R].l; r < x[R].h; r++)
|
||||
for(int g = x[G].l; g < x[G].h; g++)
|
||||
for(int b = x[B].l; b < x[B].h; b++) {
|
||||
int q = histogram[r][g][b];
|
||||
a[R][r] += q;
|
||||
a[G][g] += q;
|
||||
a[B][b] += q;
|
||||
x.avg_r += q * r;
|
||||
x.avg_g += q * g;
|
||||
x.avg_b += q * b;
|
||||
#ifdef CPU_X86
|
||||
x.colorcount += q > 0;
|
||||
#else
|
||||
x.colorcount += (-q >> 31) & 1;
|
||||
#endif
|
||||
x.population += q;
|
||||
}
|
||||
for(int i = 0; i < 3; i++) {
|
||||
Dim& d = x[i];
|
||||
while(d.l < d.h && a[i][d.l] == 0)
|
||||
d.l++;
|
||||
while(d.h > d.l && a[i][d.h - 1] == 0)
|
||||
d.h--;
|
||||
}
|
||||
x.volume = x[R] * x[G] * x[B];
|
||||
}
|
||||
|
||||
static byte sRc(int avg, int pop, int div)
|
||||
{
|
||||
return Saturate255(255 * (avg + (pop >> 1)) / pop / (div - 1));
|
||||
}
|
||||
|
||||
sPalMaker::sPalMaker(Raster& raster, RGBA *palette, int ncolors)
|
||||
{
|
||||
ASSERT(ncolors <= 256);
|
||||
ZeroArray(histogram);
|
||||
Size sz = raster.GetSize();
|
||||
for(int y = 0; y < sz.cy; y++) {
|
||||
Raster::Line line = raster[y];
|
||||
const RGBA *s = line;
|
||||
const RGBA *e = s + sz.cx;
|
||||
while(s < e) {
|
||||
histogram[s->r >> RASTER_SHIFT_R][s->g >> RASTER_SHIFT_G][s->b >> RASTER_SHIFT_B]++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
Buffer<Box> box(256);
|
||||
box[0][R].l = 0;
|
||||
box[0][R].h = RASTER_MAP_R;
|
||||
box[0][G].l = 0;
|
||||
box[0][G].h = RASTER_MAP_G;
|
||||
box[0][B].l = 0;
|
||||
box[0][B].h = RASTER_MAP_B;
|
||||
Update(box[0], 0);
|
||||
if(box[0].population == 0)
|
||||
return;
|
||||
colorcount = box[0].colorcount;
|
||||
int count = 1;
|
||||
int method = 0;
|
||||
while(count < ncolors) {
|
||||
int ii = -1;
|
||||
int maxv = 0;
|
||||
if(2 * count > ncolors)
|
||||
method = 1;
|
||||
for(int i = 0; i < count; i++) {
|
||||
int v = method ? box[i].volume : box[i].colorcount;
|
||||
if(box[i].colorcount > 1 && v > maxv) {
|
||||
ii = i;
|
||||
maxv = v;
|
||||
}
|
||||
}
|
||||
if(ii < 0)
|
||||
break;
|
||||
Box& b = box[ii];
|
||||
int ci = b[R] > b[G] ? b[B] > b[R] ? B : R : b[B] > b[G] ? B : G;
|
||||
if(b[ci] == 1) {
|
||||
if(method == 1)
|
||||
break;
|
||||
method = 1;
|
||||
}
|
||||
else {
|
||||
int m = (b[ci].l + b[ci].h) >> 1;
|
||||
Box& b1 = box[count];
|
||||
b1 = b;
|
||||
b[ci].h = m;
|
||||
b1[ci].l = m;
|
||||
Update(b, ii);
|
||||
Update(b1, count++);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < count; i++) {
|
||||
RGBA& c = palette[i];
|
||||
Box& x = box[i];
|
||||
c.r = sRc(x.avg_r, x.population, RASTER_MAP_R);
|
||||
c.g = sRc(x.avg_g, x.population, RASTER_MAP_G);
|
||||
c.b = sRc(x.avg_b, x.population, RASTER_MAP_B);
|
||||
c.a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void CreatePaletteCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal)
|
||||
{
|
||||
LTIMING("PaletteCv");
|
||||
ASSERT(ncolors <= 256);
|
||||
delete new sPalCv(palette, ncolors, cv_pal);
|
||||
}
|
||||
|
||||
void CreatePalette(Raster& raster, RGBA *palette, int ncolors)
|
||||
{
|
||||
LTIMING("Palette");
|
||||
ASSERT(ncolors <= 256);
|
||||
delete new sPalMaker(raster, palette, ncolors);
|
||||
}
|
||||
|
||||
void CreatePalette(Raster& raster, RGBA *palette, int ncolors, PaletteCv& cv)
|
||||
{
|
||||
LTIMING("Palette+Cv");
|
||||
ASSERT(ncolors <= 256);
|
||||
One<sPalMaker> m = new sPalMaker(raster, palette, ncolors);
|
||||
if(m->colorcount < 15000) // Is that right!?
|
||||
delete new sPalCv(palette, ncolors, cv, m->histogram);
|
||||
else
|
||||
CreatePaletteCv(palette, ncolors, cv);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
255
archive/olddraw/Draw/Raster.cpp
Normal file
255
archive/olddraw/Draw/Raster.cpp
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
Raster::Info::Info()
|
||||
{
|
||||
bpp = 24;
|
||||
colors = 1 << 24;
|
||||
dots = Size(0, 0);
|
||||
hotspot = Point(0, 0);
|
||||
kind = IMAGE_OPAQUE;
|
||||
}
|
||||
|
||||
const RasterFormat *Raster::GetFormat()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Raster::SeekPage(int page)
|
||||
{
|
||||
ASSERT(page == 0);
|
||||
}
|
||||
|
||||
int Raster::GetPageCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Raster::Line::Pick(pick_ Line& b)
|
||||
{
|
||||
data = b.data;
|
||||
fmtdata = b.fmtdata;
|
||||
raster = b.raster;
|
||||
free = b.free;
|
||||
fmtfree = b.fmtfree;
|
||||
const_cast<Line *>(&b)->free = const_cast<Line *>(&b)->fmtfree = false;
|
||||
#ifdef _DEBUG
|
||||
const_cast<Line *>(&b)->data = NULL;
|
||||
const_cast<Line *>(&b)->fmtdata = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Raster::Line::MakeRGBA() const
|
||||
{
|
||||
ASSERT(fmtdata && raster);
|
||||
int cx = raster->GetWidth();
|
||||
const RasterFormat *f = raster->GetFormat();
|
||||
if(f) {
|
||||
RGBA *rgba = new RGBA[cx];
|
||||
free = true;
|
||||
f->Read(rgba, fmtdata, cx, raster->GetPalette());
|
||||
data = rgba;
|
||||
}
|
||||
else
|
||||
data = (const RGBA *)fmtdata;
|
||||
}
|
||||
|
||||
Raster::Info Raster::GetInfo()
|
||||
{
|
||||
Info f;
|
||||
f.bpp = 32;
|
||||
f.colors = 256*256*256;
|
||||
f.dots = Size(0, 0);
|
||||
f.hotspot = Point(0, 0);
|
||||
f.kind = IMAGE_ALPHA;
|
||||
return f;
|
||||
}
|
||||
|
||||
bool Raster::Create() { return true; }
|
||||
|
||||
bool Raster::IsError() { return false; }
|
||||
|
||||
int Raster::GetPaletteCount() { return 0; }
|
||||
|
||||
const RGBA *Raster::GetPalette() { return NULL; }
|
||||
|
||||
Image Raster::GetImage(int x, int y, int cx, int cy, const Gate2<int, int> progress)
|
||||
{
|
||||
Size size = GetSize();
|
||||
y = minmax(y, 0, size.cy);
|
||||
int yy = minmax(y + cy, y, size.cy);
|
||||
x = minmax(x, 0, size.cx);
|
||||
cx = minmax(x + cx, x, size.cx) - x;
|
||||
ImageBuffer b(cx, yy - y);
|
||||
RGBA* t = b;
|
||||
int y0 = y;
|
||||
while(y < yy) {
|
||||
if(progress(y - y0, yy - y0))
|
||||
return Null;
|
||||
memcpy(t, ~GetLine(y) + x, cx * sizeof(RGBA));
|
||||
t += cx;
|
||||
y++;
|
||||
}
|
||||
Info f = GetInfo();
|
||||
b.SetHotSpot(f.hotspot - Point(x, y0));
|
||||
if(size.cx && size.cy)
|
||||
b.SetDots(Size(f.dots.cx * cx / size.cx, f.dots.cy * cy / size.cy));
|
||||
return IsError() ? Image() : Image(b);
|
||||
}
|
||||
|
||||
Image Raster::GetImage(const Gate2<int, int> progress)
|
||||
{
|
||||
Size sz = GetSize();
|
||||
return GetImage(0, 0, sz.cx, sz.cy, progress);
|
||||
}
|
||||
|
||||
Raster::~Raster() {}
|
||||
|
||||
Raster::Line ImageRaster::GetLine(int line)
|
||||
{
|
||||
return Line(img[line], false);
|
||||
}
|
||||
|
||||
Size ImageRaster::GetSize()
|
||||
{
|
||||
return img.GetSize();
|
||||
}
|
||||
|
||||
Raster::Info ImageRaster::GetInfo()
|
||||
{
|
||||
Raster::Info f = Raster::GetInfo();
|
||||
f.dots = img.GetDots();
|
||||
f.hotspot = img.GetHotSpot();
|
||||
f.kind = img.GetKind();
|
||||
return f;
|
||||
}
|
||||
|
||||
MemoryRaster::MemoryRaster()
|
||||
: size(0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
void MemoryRaster::Load(Raster& raster)
|
||||
{
|
||||
info = raster.GetInfo();
|
||||
size = raster.GetSize();
|
||||
palette.SetCount(raster.GetPaletteCount());
|
||||
if(!palette.IsEmpty())
|
||||
memcpy(palette, raster.GetPalette(), palette.GetCount() * sizeof(RGBA));
|
||||
lines.SetCount(size.cy);
|
||||
if(const RasterFormat *fmt = raster.GetFormat()) {
|
||||
format = *fmt;
|
||||
int rowbytes = format.GetByteCount(size.cx);
|
||||
for(int i = 0; i < size.cy; i++) {
|
||||
lines[i].Alloc(rowbytes);
|
||||
memcpy(~lines[i], raster.GetLine(i).GetRawData(), rowbytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
format.SetRGBA();
|
||||
int rowbytes = sizeof(RGBA) * size.cx;
|
||||
for(int i = 0; i < size.cy; i++) {
|
||||
lines[i].Alloc(rowbytes);
|
||||
memcpy(~lines[i], raster.GetLine(i).GetRGBA(), rowbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Raster::Line MemoryRaster::GetLine(int line)
|
||||
{
|
||||
if(format.IsRGBA())
|
||||
return Line((const RGBA *)~lines[line], false);
|
||||
else
|
||||
return Line(~lines[line], this, false);
|
||||
}
|
||||
|
||||
int MemoryRaster::GetLength() const
|
||||
{
|
||||
return size.cy * (format.IsRGBA()
|
||||
? size.cx * sizeof(RGBA)
|
||||
: ((size.cx * info.bpp + 31) >> 5) * 4);
|
||||
}
|
||||
|
||||
bool StreamRaster::Open(Stream& _s)
|
||||
{
|
||||
s = &_s;
|
||||
error = !Create();
|
||||
return !error;
|
||||
}
|
||||
|
||||
bool StreamRaster::IsError()
|
||||
{
|
||||
return error || !s || s->IsError();
|
||||
}
|
||||
|
||||
Image StreamRaster::Load(Stream& s, const Gate2<int, int> progress)
|
||||
{
|
||||
if(Open(s)) {
|
||||
Image img = GetImage(progress);
|
||||
if(!IsError())
|
||||
return img;
|
||||
}
|
||||
return Image();
|
||||
}
|
||||
|
||||
Image StreamRaster::LoadFile(const char *fn, const Gate2<int, int> progress)
|
||||
{
|
||||
FileIn in(fn);
|
||||
return in ? Load(in, progress) : Image();
|
||||
}
|
||||
|
||||
Image StreamRaster::LoadString(const String& s, const Gate2<int, int> progress)
|
||||
{
|
||||
StringStream ss(s);
|
||||
return Load(ss, progress);
|
||||
}
|
||||
|
||||
static StaticCriticalSection sAnyRaster;
|
||||
|
||||
Vector<void *>& StreamRaster::Map()
|
||||
{
|
||||
static Vector<void *> x;
|
||||
return x;
|
||||
}
|
||||
|
||||
void StreamRaster::AddFormat(RasterFactory factory)
|
||||
{
|
||||
INTERLOCKED_(sAnyRaster)
|
||||
Map().Add((void *)factory);
|
||||
}
|
||||
|
||||
One<StreamRaster> StreamRaster::OpenAny(Stream& s)
|
||||
{
|
||||
INTERLOCKED_(sAnyRaster)
|
||||
for(int i = 0; i < Map().GetCount(); i++) {
|
||||
int64 p = s.GetPos();
|
||||
One<StreamRaster> raster = (*RasterFactory(Map()[i]))();
|
||||
s.ClearError();
|
||||
if(raster->Open(s))
|
||||
return raster;
|
||||
s.ClearError();
|
||||
s.Seek(p);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Image StreamRaster::LoadAny(Stream& s, const Gate2<int, int> progress)
|
||||
{
|
||||
One<StreamRaster> r = OpenAny(s);
|
||||
return r ? r->GetImage(progress) : Image();
|
||||
}
|
||||
|
||||
Image StreamRaster::LoadFileAny(const char *fn, const Gate2<int, int> progress)
|
||||
{
|
||||
FileIn in(fn);
|
||||
return LoadAny(in, progress);
|
||||
}
|
||||
|
||||
Image StreamRaster::LoadStringAny(const String& s, const Gate2<int, int> progress)
|
||||
{
|
||||
StringStream ss(s);
|
||||
return LoadAny(ss, progress);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
297
archive/olddraw/Draw/Raster.h
Normal file
297
archive/olddraw/Draw/Raster.h
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
enum {
|
||||
RASTER_1,
|
||||
RASTER_2,
|
||||
RASTER_4,
|
||||
RASTER_8,
|
||||
RASTER_8ALPHA,
|
||||
RASTER_16,
|
||||
RASTER_24,
|
||||
RASTER_32,
|
||||
RASTER_32ALPHA,
|
||||
RASTER_32PREMULTIPLIED,
|
||||
|
||||
RASTER_MSBFIRST = 0x80,
|
||||
|
||||
RASTER_MAP_R = 32,
|
||||
RASTER_SHIFT_R = 3,
|
||||
RASTER_MAP_G = 64,
|
||||
RASTER_SHIFT_G = 2,
|
||||
RASTER_MAP_B = 16,
|
||||
RASTER_SHIFT_B = 4,
|
||||
|
||||
RASTER_MAP_MAX = 64
|
||||
};
|
||||
|
||||
struct PaletteCv {
|
||||
Buffer<byte> cv;
|
||||
|
||||
byte *At(int r, int b) { return cv + (r << 10) + (b << 6); }
|
||||
byte Get(const RGBA& b) const { return cv[(int(b.r >> RASTER_SHIFT_R) << 10) +
|
||||
(int(b.g >> RASTER_SHIFT_G)) +
|
||||
(int(b.b >> RASTER_SHIFT_B) << 6)]; }
|
||||
PaletteCv() { cv.Alloc(RASTER_MAP_R * RASTER_MAP_G * RASTER_MAP_B); }
|
||||
};
|
||||
|
||||
struct RasterFormat {
|
||||
byte type;
|
||||
dword rmask, gmask, bmask, amask;
|
||||
|
||||
void Set1lf() { type = RASTER_1; }
|
||||
void Set1mf() { type = RASTER_1|RASTER_MSBFIRST; }
|
||||
void Set2lf() { type = RASTER_2; }
|
||||
void Set2mf() { type = RASTER_2|RASTER_MSBFIRST; }
|
||||
void Set4lf() { type = RASTER_4; }
|
||||
void Set4mf() { type = RASTER_4|RASTER_MSBFIRST; }
|
||||
void Set8() { type = RASTER_8; }
|
||||
void Set8A() { type = RASTER_8ALPHA; }
|
||||
void Set16le(dword rmask, dword gmask, dword bmask);
|
||||
void Set16be(dword rmask, dword gmask, dword bmask);
|
||||
void Set24le(dword rmask, dword gmask, dword bmask);
|
||||
void Set24be(dword rmask, dword gmask, dword bmask);
|
||||
void Set32le(dword rmask, dword gmask, dword bmask, dword amask = 0);
|
||||
void Set32be(dword rmask, dword gmask, dword bmask, dword amask = 0);
|
||||
void Set32leStraight(dword rmask, dword gmask, dword bmask, dword amask);
|
||||
void Set32beStraight(dword rmask, dword gmask, dword bmask, dword amask);
|
||||
void SetRGBA();
|
||||
void SetRGBAStraight();
|
||||
|
||||
int IsRGBA() const;
|
||||
int GetByteCount(int cx) const;
|
||||
int GetBpp() const;
|
||||
bool HasAlpha() const;
|
||||
int GetColorCount() const;
|
||||
int GetPaletteCount() const;
|
||||
|
||||
void Read(RGBA *t, const byte *s, int cx, const RGBA *palette) const;
|
||||
void Write(byte *t, const RGBA *s, int cx, const PaletteCv *palcv) const;
|
||||
|
||||
private:
|
||||
byte rpos, gpos, bpos, apos;
|
||||
static void TailBits(RGBA *t, const byte *src, int cx, byte andm, byte shift, const RGBA *palette);
|
||||
static void TailBitsMSB1st(RGBA *t, const byte *src, int cx, byte shift1, byte andm, byte shift, const RGBA *palette);
|
||||
};
|
||||
|
||||
class Raster {
|
||||
public:
|
||||
class Line {
|
||||
mutable const RGBA *data;
|
||||
const byte *fmtdata;
|
||||
Raster *raster;
|
||||
mutable bool free;
|
||||
bool fmtfree;
|
||||
|
||||
friend class Raster;
|
||||
|
||||
void MakeRGBA() const;
|
||||
|
||||
public:
|
||||
const RGBA *GetRGBA() const { if(!data) MakeRGBA(); return data; }
|
||||
const byte *GetRawData() const { return fmtdata; }
|
||||
operator const RGBA *() const { return GetRGBA(); }
|
||||
const RGBA *operator~() const { return GetRGBA(); }
|
||||
|
||||
Line(const RGBA *data, bool free)
|
||||
: data(data), fmtdata((byte *)data), raster(NULL), free(free), fmtfree(false) {}
|
||||
Line(const byte *fmtdata, Raster *raster, bool fmtfree)
|
||||
: data(NULL), fmtdata(fmtdata), raster(raster), free(false), fmtfree(fmtfree) {}
|
||||
Line(pick_ Line& b) { Pick(b); }
|
||||
Line() { data = NULL; fmtdata = NULL; raster = NULL; free = fmtfree = false; }
|
||||
~Line() { Free(); }
|
||||
|
||||
void Free() { if(free) delete[] data; if(fmtfree) delete[] fmtdata; }
|
||||
void Pick(pick_ Line& b);
|
||||
|
||||
void operator=(pick_ Line& b) { Free(); Pick(b); }
|
||||
};
|
||||
|
||||
struct Info {
|
||||
int bpp;
|
||||
int colors;
|
||||
Size dots;
|
||||
Point hotspot;
|
||||
int kind;
|
||||
|
||||
Info();
|
||||
};
|
||||
|
||||
public:
|
||||
virtual void SeekPage(int page);
|
||||
virtual int GetPageCount();
|
||||
|
||||
virtual bool Create();
|
||||
virtual Size GetSize() = 0;
|
||||
virtual Info GetInfo();
|
||||
virtual Line GetLine(int line) = 0;
|
||||
virtual bool IsError();
|
||||
virtual int GetPaletteCount();
|
||||
virtual const RGBA *GetPalette();
|
||||
virtual const RasterFormat *GetFormat();
|
||||
|
||||
int GetWidth() { return GetSize().cx; }
|
||||
int GetHeight() { return GetSize().cy; }
|
||||
Line operator[](int i) { return GetLine(i); }
|
||||
|
||||
Image GetImage(int x, int y, int cx, int cy, const Gate2<int, int> progress = false);
|
||||
Image GetImage(const Gate2<int, int> progress = false);
|
||||
|
||||
virtual ~Raster();
|
||||
};
|
||||
|
||||
typedef Raster::Line RasterLine;
|
||||
typedef Raster::Info RasterInfo;
|
||||
|
||||
void CreatePaletteCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal);
|
||||
void CreatePalette(Raster& raster, RGBA *palette, int ncolors);
|
||||
void CreatePalette(Raster& raster, RGBA *palette, int ncolors, PaletteCv& cv);
|
||||
|
||||
class ImageRaster : public Raster {
|
||||
Image img;
|
||||
|
||||
public:
|
||||
virtual Size GetSize();
|
||||
virtual Line GetLine(int line);
|
||||
virtual Info GetInfo();
|
||||
|
||||
ImageRaster(const Image& img) : img(img) {}
|
||||
};
|
||||
|
||||
class MemoryRaster : public Raster {
|
||||
public:
|
||||
MemoryRaster();
|
||||
MemoryRaster(Raster& raster) { Load(raster); }
|
||||
|
||||
virtual Size GetSize() { return size; }
|
||||
virtual Info GetInfo() { return info; }
|
||||
virtual Line GetLine(int line);
|
||||
virtual int GetPaletteCount() { return palette.GetCount(); }
|
||||
virtual const RGBA *GetPalette() { return palette.Begin(); }
|
||||
virtual const RasterFormat *GetFormat() { return &format; }
|
||||
|
||||
void Load(Raster& raster);
|
||||
int GetLength() const;
|
||||
|
||||
private:
|
||||
RasterFormat format;
|
||||
Info info;
|
||||
Size size;
|
||||
Vector< Buffer<byte> > lines;
|
||||
Vector<RGBA> palette;
|
||||
};
|
||||
|
||||
class StreamRaster : public Raster {
|
||||
Stream *s;
|
||||
bool error;
|
||||
|
||||
typedef StreamRaster *(*RasterFactory)();
|
||||
template <class T> static StreamRaster *FactoryFn() { return new T; }
|
||||
static void AddFormat(RasterFactory f);
|
||||
static Vector<void *>& Map();
|
||||
|
||||
public:
|
||||
Stream& GetStream() { return *s; }
|
||||
bool Open(Stream& _s);
|
||||
bool IsError();
|
||||
|
||||
void SetError() { error = true; }
|
||||
|
||||
Image Load(Stream& s, const Gate2<int, int> progress = false);
|
||||
Image LoadFile(const char *fn, const Gate2<int, int> progress = false);
|
||||
Image LoadString(const String& s, const Gate2<int, int> progress = false);
|
||||
|
||||
template <class T>
|
||||
static void Register() { AddFormat(&StreamRaster::FactoryFn<T>); }
|
||||
|
||||
static One<StreamRaster> OpenAny(Stream& s);
|
||||
static Image LoadAny(Stream& s, const Gate2<int, int> progress = false);
|
||||
static Image LoadFileAny(const char *fn, const Gate2<int, int> progress = false);
|
||||
static Image LoadStringAny(const String& s, const Gate2<int, int> progress = false);
|
||||
|
||||
StreamRaster() { error = true; }
|
||||
};
|
||||
|
||||
class RasterEncoder {
|
||||
Size size, dots;
|
||||
Point hotspot;
|
||||
RGBA *line;
|
||||
Buffer<byte> scanline;
|
||||
int line_bytes;
|
||||
Buffer<RGBA> h;
|
||||
Buffer<RGBA> palette;
|
||||
One<PaletteCv> palette_cv;
|
||||
|
||||
RGBA *Pal();
|
||||
|
||||
protected:
|
||||
RasterFormat format;
|
||||
void SetLine(RGBA *_line);
|
||||
|
||||
public:
|
||||
virtual int GetPaletteCount();
|
||||
virtual void Start(Size sz) = 0;
|
||||
virtual void WriteLineRaw(const byte *data) = 0;
|
||||
|
||||
void WriteLine();
|
||||
void WriteLine(const RGBA *s);
|
||||
|
||||
const RasterFormat& GetFormat() const { return format; }
|
||||
const RGBA *GetPalette();
|
||||
const PaletteCv *GetPaletteCv() { return ~palette_cv; }
|
||||
|
||||
operator RGBA *() { return line; }
|
||||
RGBA *operator~() { return line; }
|
||||
Size GetSize() const { return size; }
|
||||
int GetWidth() const { return GetSize().cx; }
|
||||
int GetHeight() const { return GetSize().cy; }
|
||||
|
||||
void SetHotSpot(Point p) { hotspot = p; }
|
||||
Point GetHotSpot() const { return hotspot; }
|
||||
|
||||
void SetDots(Size _dots) { dots = _dots; }
|
||||
Size GetDots() const { return dots; }
|
||||
|
||||
void SetPalette(const RGBA *palette);
|
||||
void SetPalette(Raster& pal_raster);
|
||||
|
||||
void Create(Size sz);
|
||||
void Create(int cx, int cy) { Create(Size(cx, cy)); }
|
||||
|
||||
void Create(Size sz, const RGBA *palette);
|
||||
void Create(int cx, int cy, const RGBA *palette);
|
||||
void Create(Size sz, Raster& pal_raster);
|
||||
void Create(int cx, int cy, Raster& pal_raster);
|
||||
|
||||
RasterEncoder();
|
||||
virtual ~RasterEncoder();
|
||||
};
|
||||
|
||||
class ImageEncoder : public RasterEncoder {
|
||||
int ii;
|
||||
ImageBuffer ib;
|
||||
|
||||
public:
|
||||
virtual void Start(Size sz);
|
||||
virtual void WriteLineRaw(const byte *data);
|
||||
|
||||
Size GetSize() const { return ib.GetSize(); }
|
||||
int GetWidth() const { return GetSize().cx; }
|
||||
int GetHeight() const { return GetSize().cy; }
|
||||
|
||||
operator const RGBA *() { return Image(ib); }
|
||||
operator Image() { return Image(ib); }
|
||||
};
|
||||
|
||||
class StreamRasterEncoder : public RasterEncoder {
|
||||
Stream *s;
|
||||
|
||||
public:
|
||||
Stream& GetStream() { return *s; }
|
||||
void SetStream(Stream& _s) { s = &_s; }
|
||||
|
||||
void Save(Stream& s, Raster& raster);
|
||||
bool SaveFile(const char *fn, Raster& raster);
|
||||
String SaveString(Raster& raster);
|
||||
|
||||
void Save(Stream& s, const Image& img);
|
||||
bool SaveFile(const char *fn, const Image& img);
|
||||
String SaveString(const Image& img);
|
||||
};
|
||||
178
archive/olddraw/Draw/RasterEncoder.cpp
Normal file
178
archive/olddraw/Draw/RasterEncoder.cpp
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
RasterEncoder::RasterEncoder()
|
||||
{
|
||||
size = Size(0, 0);
|
||||
dots = Size(0, 0);
|
||||
hotspot = Point(0, 0);
|
||||
format.SetRGBA();
|
||||
}
|
||||
|
||||
void RasterEncoder::SetLine(RGBA *_line)
|
||||
{
|
||||
line = _line;
|
||||
h.Clear();
|
||||
}
|
||||
|
||||
void RasterEncoder::WriteLine(const RGBA *s)
|
||||
{
|
||||
if(format.IsRGBA())
|
||||
WriteLineRaw((byte *)s);
|
||||
else {
|
||||
if(!scanline)
|
||||
scanline.Alloc(format.GetByteCount(size.cx));
|
||||
format.Write(scanline, s, size.cx, GetPaletteCv());
|
||||
WriteLineRaw(scanline);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterEncoder::WriteLine()
|
||||
{
|
||||
WriteLine(line);
|
||||
}
|
||||
|
||||
void RasterEncoder::Create(Size sz)
|
||||
{
|
||||
size = sz;
|
||||
h.Alloc(sz.cx);
|
||||
line = h;
|
||||
Start(sz);
|
||||
scanline.Clear();
|
||||
line_bytes = format.GetByteCount(size.cx);
|
||||
}
|
||||
|
||||
RGBA *RasterEncoder::Pal()
|
||||
{
|
||||
if(!palette)
|
||||
palette.Alloc(256);
|
||||
return palette;
|
||||
}
|
||||
|
||||
const RGBA *RasterEncoder::GetPalette()
|
||||
{
|
||||
if(!palette) {
|
||||
palette.Alloc(256);
|
||||
RGBA *p = palette;
|
||||
int n = GetPaletteCount();
|
||||
for(int i = 0; i < n; i++)
|
||||
p[i].r = p[i].g = p[i].b = p[i].a = 255 * i * (n - 1) / (n - 1);
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
void RasterEncoder::SetPalette(const RGBA *pal)
|
||||
{
|
||||
int n = GetPaletteCount();
|
||||
if(n) {
|
||||
memcpy(Pal(), pal, n * sizeof(RGBA));
|
||||
palette_cv.Create();
|
||||
CreatePaletteCv(Pal(), n, *palette_cv);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterEncoder::SetPalette(Raster& raster)
|
||||
{
|
||||
int n = GetPaletteCount();
|
||||
if(n) {
|
||||
if(raster.GetPaletteCount() == n)
|
||||
memcpy(Pal(), raster.GetPalette(), n * sizeof(RGBA));
|
||||
else
|
||||
CreatePalette(raster, Pal(), n);
|
||||
palette_cv.Create();
|
||||
CreatePaletteCv(Pal(), n, *palette_cv);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterEncoder::Create(Size sz, const RGBA *palette)
|
||||
{
|
||||
SetPalette(palette);
|
||||
Create(sz);
|
||||
}
|
||||
|
||||
void RasterEncoder::Create(int cx, int cy, const RGBA *palette)
|
||||
{
|
||||
SetPalette(palette);
|
||||
Create(cx, cy);
|
||||
}
|
||||
|
||||
void RasterEncoder::Create(Size sz, Raster& pal_raster)
|
||||
{
|
||||
SetPalette(pal_raster);
|
||||
Create(sz);
|
||||
}
|
||||
|
||||
void RasterEncoder::Create(int cx, int cy, Raster& pal_raster)
|
||||
{
|
||||
SetPalette(pal_raster);
|
||||
Create(cx, cy);
|
||||
}
|
||||
|
||||
int RasterEncoder::GetPaletteCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RasterEncoder::~RasterEncoder() {}
|
||||
|
||||
void ImageEncoder::Start(Size sz)
|
||||
{
|
||||
ii = 0;
|
||||
ib.Create(sz);
|
||||
if(sz.cy)
|
||||
SetLine(ib[0]);
|
||||
}
|
||||
|
||||
void ImageEncoder::WriteLineRaw(const byte *data)
|
||||
{
|
||||
if((RGBA *)data != ~*this)
|
||||
memcpy(~*this, data, GetSize().cx * sizeof(RGBA));
|
||||
if(++ii < GetHeight())
|
||||
SetLine(ib[ii]);
|
||||
}
|
||||
|
||||
void StreamRasterEncoder::Save(Stream& s, Raster& raster)
|
||||
{
|
||||
SetStream(s);
|
||||
Size sz = raster.GetSize();
|
||||
Create(sz, raster);
|
||||
SetDots(raster.GetInfo().dots);
|
||||
SetHotSpot(raster.GetInfo().hotspot);
|
||||
for(int i = 0; i < sz.cy; i++)
|
||||
WriteLine(raster[i]);
|
||||
}
|
||||
|
||||
bool StreamRasterEncoder::SaveFile(const char *fn, Raster& raster)
|
||||
{
|
||||
FileOut out(fn);
|
||||
Save(out, raster);
|
||||
return !out.IsError();
|
||||
}
|
||||
|
||||
String StreamRasterEncoder::SaveString(Raster& raster)
|
||||
{
|
||||
StringStream ss;
|
||||
Save(ss, raster);
|
||||
return ss;
|
||||
}
|
||||
|
||||
void StreamRasterEncoder::Save(Stream& s, const Image& img)
|
||||
{
|
||||
ImageRaster r(img);
|
||||
Save(s, r);
|
||||
}
|
||||
|
||||
bool StreamRasterEncoder::SaveFile(const char *fn, const Image& img)
|
||||
{
|
||||
ImageRaster r(img);
|
||||
return SaveFile(fn, r);
|
||||
}
|
||||
|
||||
String StreamRasterEncoder::SaveString(const Image& img)
|
||||
{
|
||||
ImageRaster r(img);
|
||||
return SaveString(r);
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
368
archive/olddraw/Draw/RasterFormat.cpp
Normal file
368
archive/olddraw/Draw/RasterFormat.cpp
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
static int sMaskPos16(dword mask)
|
||||
{
|
||||
if(mask > 0xffff)
|
||||
return 0;
|
||||
int pos = 0;
|
||||
while(((mask << pos) & 0x18000) != 0x8000)
|
||||
pos++;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void RasterFormat::Set16le(dword _rmask, dword _gmask, dword _bmask)
|
||||
{
|
||||
rpos = sMaskPos16(rmask = _rmask);
|
||||
gpos = sMaskPos16(gmask = _gmask);
|
||||
bpos = sMaskPos16(bmask = _bmask);
|
||||
type = RASTER_16;
|
||||
}
|
||||
|
||||
void RasterFormat::Set16be(dword _rmask, dword _gmask, dword _bmask)
|
||||
{
|
||||
Set16le(_rmask, _gmask, _bmask);
|
||||
type = RASTER_16|RASTER_MSBFIRST;
|
||||
}
|
||||
|
||||
void RasterFormat::Set24le(dword rmask, dword gmask, dword bmask)
|
||||
{
|
||||
rpos = GetChMaskPos32(rmask);
|
||||
gpos = GetChMaskPos32(gmask);
|
||||
bpos = GetChMaskPos32(bmask);
|
||||
apos = 0;
|
||||
type = RASTER_24;
|
||||
}
|
||||
|
||||
void RasterFormat::Set32le(dword rmask, dword gmask, dword bmask, dword amask)
|
||||
{
|
||||
Set24le(rmask, gmask, bmask);
|
||||
if(amask) {
|
||||
apos = GetChMaskPos32(amask);
|
||||
type = RASTER_32ALPHA;
|
||||
}
|
||||
else
|
||||
type = RASTER_32;
|
||||
}
|
||||
|
||||
void RasterFormat::Set24be(dword rmask, dword gmask, dword bmask)
|
||||
{
|
||||
rpos = 2 - GetChMaskPos32(rmask);
|
||||
gpos = 2 - GetChMaskPos32(gmask);
|
||||
bpos = 2 - GetChMaskPos32(bmask);
|
||||
apos = 0;
|
||||
type = RASTER_24;
|
||||
}
|
||||
|
||||
void RasterFormat::Set32be(dword rmask, dword gmask, dword bmask, dword amask)
|
||||
{
|
||||
rpos = 3 - GetChMaskPos32(rmask);
|
||||
gpos = 3 - GetChMaskPos32(gmask);
|
||||
bpos = 3 - GetChMaskPos32(bmask);
|
||||
if(amask) {
|
||||
apos = 3 - GetChMaskPos32(amask);
|
||||
type = RASTER_32PREMULTIPLIED;
|
||||
}
|
||||
else
|
||||
type = RASTER_32;
|
||||
}
|
||||
|
||||
void RasterFormat::Set32leStraight(dword rmask, dword gmask, dword bmask, dword amask)
|
||||
{
|
||||
Set32le(rmask, gmask, bmask, amask);
|
||||
type = RASTER_32ALPHA;
|
||||
}
|
||||
|
||||
void RasterFormat::Set32beStraight(dword rmask, dword gmask, dword bmask, dword amask)
|
||||
{
|
||||
Set32be(rmask, gmask, bmask, amask);
|
||||
type = RASTER_32ALPHA;
|
||||
}
|
||||
|
||||
void RasterFormat::SetRGBA()
|
||||
{
|
||||
type = RASTER_32PREMULTIPLIED;
|
||||
bpos = 0;
|
||||
gpos = 1;
|
||||
rpos = 2;
|
||||
apos = 3;
|
||||
}
|
||||
|
||||
void RasterFormat::SetRGBAStraight()
|
||||
{
|
||||
type = RASTER_32ALPHA;
|
||||
bpos = 0;
|
||||
gpos = 1;
|
||||
rpos = 2;
|
||||
apos = 3;
|
||||
}
|
||||
|
||||
int RasterFormat::IsRGBA() const
|
||||
{
|
||||
return (type & 31) == RASTER_32PREMULTIPLIED && bpos == 0 && gpos == 1 && rpos == 2 && apos == 3;
|
||||
}
|
||||
|
||||
static byte bits[16] = { 1, 2, 4, 8, 16, 16, 24, 32, 32, 32 };
|
||||
|
||||
int RasterFormat::GetByteCount(int cx) const
|
||||
{
|
||||
int b = bits[type & 15];
|
||||
return (cx * b + 7) >> 3;
|
||||
}
|
||||
|
||||
int RasterFormat::GetBpp() const
|
||||
{
|
||||
return bits[type & 15];
|
||||
}
|
||||
|
||||
bool RasterFormat::HasAlpha() const
|
||||
{
|
||||
return (type & 15) == RASTER_32ALPHA;
|
||||
}
|
||||
|
||||
int RasterFormat::GetColorCount() const
|
||||
{
|
||||
static int colors[16] = { 2, 4, 16, 256, 256, 65536, 256 * 256 * 256, 256 * 256 * 256, 256 * 256 * 256 };
|
||||
return colors[type & 15];
|
||||
}
|
||||
|
||||
int RasterFormat::GetPaletteCount() const
|
||||
{
|
||||
static int colors[16] = { 2, 4, 16, 256 };
|
||||
return (type & 15) < 4 ? colors[type & 15] : 0;
|
||||
}
|
||||
|
||||
void RasterFormat::TailBits(RGBA *t, const byte *src, int cx, byte andm, byte shift, const RGBA *palette)
|
||||
{
|
||||
if(cx) {
|
||||
byte c = *src;
|
||||
while(cx > 0) {
|
||||
*t++ = palette[c & andm]; c >>= shift;
|
||||
cx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterFormat::TailBitsMSB1st(RGBA *t, const byte *src, int cx, byte shift1, byte andm, byte shift, const RGBA *palette)
|
||||
{
|
||||
if(cx) {
|
||||
byte c = *src;
|
||||
while(cx > 0) {
|
||||
*t++ = palette[(c >> shift1) & andm]; c <<= shift;
|
||||
cx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterFormat::Read(RGBA *t, const byte *s, int cx, const RGBA *palette) const
|
||||
{
|
||||
switch(type) {
|
||||
case RASTER_1:
|
||||
{
|
||||
const byte *e = s + (cx >> 3);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[0] = palette[(c >> 0) & 1];
|
||||
t[1] = palette[(c >> 1) & 1];
|
||||
t[2] = palette[(c >> 2) & 1];
|
||||
t[3] = palette[(c >> 3) & 1];
|
||||
t[4] = palette[(c >> 4) & 1];
|
||||
t[5] = palette[(c >> 5) & 1];
|
||||
t[6] = palette[(c >> 6) & 1];
|
||||
t[7] = palette[(c >> 7) & 1];
|
||||
t += 8;
|
||||
}
|
||||
TailBits(t, s, cx & 7, 1, 1, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_1|RASTER_MSBFIRST:
|
||||
{
|
||||
const byte *e = s + (cx >> 3);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[7] = palette[(c >> 0) & 1];
|
||||
t[6] = palette[(c >> 1) & 1];
|
||||
t[5] = palette[(c >> 2) & 1];
|
||||
t[4] = palette[(c >> 3) & 1];
|
||||
t[3] = palette[(c >> 4) & 1];
|
||||
t[2] = palette[(c >> 5) & 1];
|
||||
t[1] = palette[(c >> 6) & 1];
|
||||
t[0] = palette[(c >> 7) & 1];
|
||||
t += 8;
|
||||
}
|
||||
TailBitsMSB1st(t, s, cx & 7, 7, 1, 1, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_2:
|
||||
{
|
||||
const byte *e = s + (cx >> 2);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[0] = palette[(c >> 0) & 3];
|
||||
t[1] = palette[(c >> 2) & 3];
|
||||
t[2] = palette[(c >> 4) & 3];
|
||||
t[3] = palette[(c >> 6) & 3];
|
||||
t += 4;
|
||||
}
|
||||
TailBits(t, s, cx & 3, 3, 2, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_2|RASTER_MSBFIRST:
|
||||
{
|
||||
const byte *e = s + (cx >> 2);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[3] = palette[(c >> 0) & 3];
|
||||
t[2] = palette[(c >> 2) & 3];
|
||||
t[1] = palette[(c >> 4) & 3];
|
||||
t[0] = palette[(c >> 6) & 3];
|
||||
t += 4;
|
||||
}
|
||||
TailBitsMSB1st(t, s, cx & 3, 6, 3, 2, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_4:
|
||||
{
|
||||
const byte *e = s + (cx >> 1);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[0] = palette[(c >> 0) & 15];
|
||||
t[1] = palette[(c >> 4) & 15];
|
||||
t += 2;
|
||||
}
|
||||
TailBits(t, s, cx & 1, 15, 4, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_4|RASTER_MSBFIRST:
|
||||
{
|
||||
const byte *e = s + (cx >> 1);
|
||||
while(s < e) {
|
||||
byte c = *s++;
|
||||
t[1] = palette[(c >> 0) & 15];
|
||||
t[0] = palette[(c >> 4) & 15];
|
||||
t += 2;
|
||||
}
|
||||
TailBitsMSB1st(t, s, cx & 1, 4, 15, 4, palette);
|
||||
}
|
||||
break;
|
||||
case RASTER_8:
|
||||
case RASTER_8|RASTER_MSBFIRST:
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e)
|
||||
*t++ = palette[*s++];
|
||||
}
|
||||
break;
|
||||
case RASTER_8ALPHA:
|
||||
case RASTER_8ALPHA|RASTER_MSBFIRST:
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
RGBA pal = palette[*s];
|
||||
pal.a = s[1];
|
||||
*t++ = pal;
|
||||
s += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RASTER_16:
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
word w = Peek16le(s);
|
||||
t->a = 255;
|
||||
t->r = byte((w & rmask) << rpos >> 8);
|
||||
t->g = byte((w & gmask) << gpos >> 8);
|
||||
t->b = byte((w & bmask) << bpos >> 8);
|
||||
s += 2;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_16|RASTER_MSBFIRST:
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
word w = Peek16be(s);
|
||||
t->a = 255;
|
||||
t->r = byte((w & rmask) << rpos >> 8);
|
||||
t->g = byte((w & gmask) << gpos >> 8);
|
||||
t->b = byte((w & bmask) << bpos >> 8);
|
||||
s += 2;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_24:
|
||||
case RASTER_24|RASTER_MSBFIRST:
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
t->a = 255;
|
||||
t->r = s[rpos];
|
||||
t->g = s[gpos];
|
||||
t->b = s[bpos];
|
||||
s += 3;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_32:
|
||||
case RASTER_32|RASTER_MSBFIRST:
|
||||
if(bpos == 0 && gpos == 1 && rpos == 2) {
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
*t = *(RGBA *)s;
|
||||
t->a = 255;
|
||||
s += 4;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
t->a = 255;
|
||||
t->r = s[rpos];
|
||||
t->g = s[gpos];
|
||||
t->b = s[bpos];
|
||||
s += 4;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_32ALPHA:
|
||||
case RASTER_32ALPHA|RASTER_MSBFIRST: {
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
t->a = s[apos];
|
||||
int alpha = t->a + (t->a >> 7);
|
||||
t->r = (alpha * s[rpos]) >> 8;
|
||||
t->g = (alpha * s[gpos]) >> 8;
|
||||
t->b = (alpha * s[bpos]) >> 8;
|
||||
s += 4;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_32PREMULTIPLIED:
|
||||
case RASTER_32PREMULTIPLIED|RASTER_MSBFIRST:
|
||||
if(bpos == 0 && gpos == 1 && rpos == 2 && apos == 3)
|
||||
memcpy(t, s, cx * sizeof(RGBA));
|
||||
else {
|
||||
RGBA *e = t + cx;
|
||||
while(t < e) {
|
||||
t->a = s[apos];
|
||||
t->r = s[rpos];
|
||||
t->g = s[gpos];
|
||||
t->b = s[bpos];
|
||||
s += 4;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
344
archive/olddraw/Draw/RasterWrite.cpp
Normal file
344
archive/olddraw/Draw/RasterWrite.cpp
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
extern int um_table__[256];
|
||||
void sInitUmTable__();
|
||||
|
||||
void RasterFormat::Write(byte *t, const RGBA *s, int cx, const PaletteCv *palcv) const
|
||||
{
|
||||
const RGBA *e = s + cx;
|
||||
switch(type) {
|
||||
case RASTER_1:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 3);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((palcv->Get(s[0]) & 1) << 0)
|
||||
| ((palcv->Get(s[1]) & 1) << 1)
|
||||
| ((palcv->Get(s[2]) & 1) << 2)
|
||||
| ((palcv->Get(s[3]) & 1) << 3)
|
||||
| ((palcv->Get(s[4]) & 1) << 4)
|
||||
| ((palcv->Get(s[5]) & 1) << 5)
|
||||
| ((palcv->Get(s[6]) & 1) << 6)
|
||||
| ((palcv->Get(s[7]) & 1) << 7)
|
||||
;
|
||||
s += 8;
|
||||
}
|
||||
cx &= 7;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 0;
|
||||
while(cx > 0) {
|
||||
c |= (palcv->Get(*s++)) << sh;
|
||||
sh++;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 3);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((s[0].g & 0x80) >> 7)
|
||||
| ((s[1].g & 0x80) >> 6)
|
||||
| ((s[2].g & 0x80) >> 5)
|
||||
| ((s[3].g & 0x80) >> 4)
|
||||
| ((s[4].g & 0x80) >> 3)
|
||||
| ((s[5].g & 0x80) >> 2)
|
||||
| ((s[6].g & 0x80) >> 1)
|
||||
| ((s[7].g & 0x80) >> 0)
|
||||
;
|
||||
s += 8;
|
||||
}
|
||||
cx &= 7;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 7;
|
||||
while(cx > 0) {
|
||||
c |= ((s++)->g & 0x80) >> sh;
|
||||
sh--;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_1|RASTER_MSBFIRST:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 3);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((palcv->Get(s[7]) & 1) << 0)
|
||||
| ((palcv->Get(s[6]) & 1) << 1)
|
||||
| ((palcv->Get(s[5]) & 1) << 2)
|
||||
| ((palcv->Get(s[4]) & 1) << 3)
|
||||
| ((palcv->Get(s[3]) & 1) << 4)
|
||||
| ((palcv->Get(s[2]) & 1) << 5)
|
||||
| ((palcv->Get(s[1]) & 1) << 6)
|
||||
| ((palcv->Get(s[0]) & 1) << 7)
|
||||
;
|
||||
s += 8;
|
||||
}
|
||||
cx &= 7;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 7;
|
||||
while(cx > 0) {
|
||||
c |= (palcv->Get(*s++)) << sh;
|
||||
sh--;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 3);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((s[7].g & 0x80) >> 7)
|
||||
| ((s[6].g & 0x80) >> 6)
|
||||
| ((s[5].g & 0x80) >> 5)
|
||||
| ((s[4].g & 0x80) >> 4)
|
||||
| ((s[3].g & 0x80) >> 3)
|
||||
| ((s[2].g & 0x80) >> 2)
|
||||
| ((s[1].g & 0x80) >> 1)
|
||||
| ((s[0].g & 0x80) >> 0)
|
||||
;
|
||||
s += 8;
|
||||
}
|
||||
cx &= 7;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 0;
|
||||
while(cx > 0) {
|
||||
c |= ((s++)->g & 0x80) >> sh;
|
||||
sh++;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_2:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 2);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((palcv->Get(s[0]) & 3) << 0)
|
||||
| ((palcv->Get(s[1]) & 3) << 2)
|
||||
| ((palcv->Get(s[2]) & 3) << 4)
|
||||
| ((palcv->Get(s[3]) & 3) << 6)
|
||||
;
|
||||
s += 4;
|
||||
}
|
||||
cx &= 3;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 0;
|
||||
while(cx > 0) {
|
||||
c |= (palcv->Get(*s++)) << sh;
|
||||
sh += 2;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 2);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((s[0].g & 0xc0) >> 6)
|
||||
| ((s[1].g & 0xc0) >> 4)
|
||||
| ((s[2].g & 0xc0) >> 2)
|
||||
| ((s[3].g & 0xc0) >> 0)
|
||||
;
|
||||
s += 4;
|
||||
}
|
||||
cx &= 3;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 6;
|
||||
while(cx > 0) {
|
||||
c |= ((s++)->g & 0xc0) >> sh;
|
||||
sh -= 2;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_2|RASTER_MSBFIRST:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 2);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((palcv->Get(s[3]) & 3) << 0)
|
||||
| ((palcv->Get(s[2]) & 3) << 2)
|
||||
| ((palcv->Get(s[1]) & 3) << 4)
|
||||
| ((palcv->Get(s[0]) & 3) << 6)
|
||||
;
|
||||
s += 4;
|
||||
}
|
||||
cx &= 3;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 6;
|
||||
while(cx > 0) {
|
||||
c |= (palcv->Get(*s++)) << sh;
|
||||
sh -= 2;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 2);
|
||||
while(t < e) {
|
||||
*t++ =
|
||||
((s[3].g & 0xc0) >> 6)
|
||||
| ((s[2].g & 0xc0) >> 4)
|
||||
| ((s[1].g & 0xc0) >> 2)
|
||||
| ((s[0].g & 0xc0) >> 0)
|
||||
;
|
||||
s += 4;
|
||||
}
|
||||
cx &= 3;
|
||||
if(cx) {
|
||||
byte c = 0;
|
||||
byte sh = 0;
|
||||
while(cx > 0) {
|
||||
c |= ((s++)->g & 0xc0) >> sh;
|
||||
sh += c;
|
||||
cx--;
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RASTER_4:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 1);
|
||||
while(t < e) {
|
||||
*t++ = (palcv->Get(s[0]) & 15) | ((palcv->Get(s[1]) & 15) << 4);
|
||||
s += 2;
|
||||
}
|
||||
if(cx & 1)
|
||||
*t = palcv->Get(*s) & 15;
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 1);
|
||||
while(t < e) {
|
||||
*t++ = ((Grayscale(s[0]) & 0xf0) >> 4) | ((Grayscale(s[1]) & 0xf0));
|
||||
s += 2;
|
||||
}
|
||||
if(cx & 1)
|
||||
*t = (Grayscale(s[0]) & 0xf0) >> 4;
|
||||
}
|
||||
break;
|
||||
case RASTER_4|RASTER_MSBFIRST:
|
||||
if(palcv) {
|
||||
const byte *e = t + (cx >> 1);
|
||||
while(t < e) {
|
||||
*t++ = (palcv->Get(s[1]) & 15) | ((palcv->Get(s[0]) & 15) << 4);
|
||||
s += 2;
|
||||
}
|
||||
if(cx & 1)
|
||||
*t = (palcv->Get(*s) & 15) << 4;
|
||||
}
|
||||
else {
|
||||
const byte *e = t + (cx >> 1);
|
||||
while(t < e) {
|
||||
*t++ = ((Grayscale(s[1]) & 0xf0) >> 4) | ((Grayscale(s[0]) & 0xf0));
|
||||
s += 2;
|
||||
}
|
||||
if(cx & 1)
|
||||
*t = Grayscale(s[0]) & 0xf0;
|
||||
}
|
||||
break;
|
||||
case RASTER_8:
|
||||
case RASTER_8|RASTER_MSBFIRST:
|
||||
if(palcv)
|
||||
while(s < e) {
|
||||
*t++ = palcv->Get(*s);
|
||||
s++;
|
||||
}
|
||||
else
|
||||
while(s < e)
|
||||
*t++ = Grayscale(*s++);
|
||||
break;
|
||||
case RASTER_16:
|
||||
while(s < e) {
|
||||
Poke16le(t, ((s->r << 8 >> rpos) & rmask) |
|
||||
((s->g << 8 >> gpos) & gmask) |
|
||||
((s->b << 8 >> bpos) & bmask));
|
||||
t += 2;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
case RASTER_16|RASTER_MSBFIRST:
|
||||
while(s < e) {
|
||||
Poke16be(t, ((s->r << 8 >> rpos) & rmask) |
|
||||
((s->g << 8 >> gpos) & gmask) |
|
||||
((s->b << 8 >> bpos) & bmask));
|
||||
t += 2;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
case RASTER_24:
|
||||
case RASTER_24|RASTER_MSBFIRST:
|
||||
while(s < e) {
|
||||
t[rpos] = s->r;
|
||||
t[gpos] = s->g;
|
||||
t[bpos] = s->b;
|
||||
t += 3;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
case RASTER_32:
|
||||
case RASTER_32|RASTER_MSBFIRST:
|
||||
while(s < e) {
|
||||
t[rpos] = s->r;
|
||||
t[gpos] = s->g;
|
||||
t[bpos] = s->b;
|
||||
t += 4;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
case RASTER_32ALPHA:
|
||||
case RASTER_32ALPHA|RASTER_MSBFIRST:
|
||||
sInitUmTable__();
|
||||
while(s < e) {
|
||||
int alpha = um_table__[t[apos] = s->a];
|
||||
t[rpos] = (alpha * s->r) >> 8;
|
||||
t[gpos] = (alpha * s->g) >> 8;
|
||||
t[bpos] = (alpha * s->b) >> 8;
|
||||
t += 4;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
case RASTER_32PREMULTIPLIED:
|
||||
case RASTER_32PREMULTIPLIED|RASTER_MSBFIRST:
|
||||
#ifdef PLATFORM_WIN32
|
||||
if(bpos == 0 && gpos == 1 && rpos == 2 && apos == 3)
|
||||
memcpy(t, s, cx * sizeof(RGBA));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while(s < e) {
|
||||
t[rpos] = s->r;
|
||||
t[gpos] = s->g;
|
||||
t[bpos] = s->b;
|
||||
t[apos] = s->a;
|
||||
t += 4;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
42
archive/olddraw/Draw/SSettings.cpp
Normal file
42
archive/olddraw/Draw/SSettings.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#include "Draw.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
CH_COLOR(SBlack, Black());
|
||||
CH_COLOR(SGray, Gray());
|
||||
CH_COLOR(SLtGray, LtGray());
|
||||
CH_COLOR(SWhiteGray, WhiteGray());
|
||||
CH_COLOR(SWhite, White());
|
||||
CH_COLOR(SRed, Red());
|
||||
CH_COLOR(SGreen, Green());
|
||||
CH_COLOR(SBrown, Brown());
|
||||
CH_COLOR(SBlue, Blue());
|
||||
CH_COLOR(SMagenta, Magenta());
|
||||
CH_COLOR(SCyan, Cyan());
|
||||
CH_COLOR(SYellow, Yellow());
|
||||
CH_COLOR(SLtRed, LtRed());
|
||||
CH_COLOR(SLtGreen, LtGreen());
|
||||
CH_COLOR(SLtYellow, LtYellow());
|
||||
CH_COLOR(SLtBlue, LtBlue());
|
||||
CH_COLOR(SLtMagenta, LtMagenta());
|
||||
CH_COLOR(SLtCyan, LtCyan());
|
||||
|
||||
CH_COLOR(SColorPaper, White());
|
||||
CH_COLOR(SColorFace, LtGray());
|
||||
CH_COLOR(SColorText, Black());
|
||||
CH_COLOR(SColorHighlight, Blue());
|
||||
CH_COLOR(SColorHighlightText, White());
|
||||
CH_COLOR(SColorMenu, LtGray());
|
||||
CH_COLOR(SColorMenuText, Black());
|
||||
CH_COLOR(SColorInfo, LtYellow());
|
||||
CH_COLOR(SColorInfoText, Black());
|
||||
CH_COLOR(SColorDisabled, Gray());
|
||||
CH_COLOR(SColorLight, White());
|
||||
CH_COLOR(SColorShadow, Gray());
|
||||
CH_COLOR(SColorMark, LtBlue());
|
||||
|
||||
CH_COLOR(SColorLtFace, Blend(SColorFace, SColorLight));
|
||||
CH_COLOR(SColorDkShadow, Blend(SColorShadow, SColorText));
|
||||
CH_COLOR(SColorLabel, SColorText());
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
22
archive/olddraw/Draw/gdk.dli
Normal file
22
archive/olddraw/Draw/gdk.dli
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
FN(G_obj *, gdk_x11_colormap_foreign_new, (G_obj *visual, Colormap xcolormap))
|
||||
FN(G_obj *, gdkx_visual_get, (VisualID xvisualid))
|
||||
FN(G_obj *, gdk_pixmap_foreign_new, (uint32 anid))
|
||||
FN(void, gdk_drawable_set_colormap, (G_obj *drawable, G_obj *colormap))
|
||||
FN(G_obj *, gdk_x11_display_get_xdisplay, (G_obj *display))
|
||||
|
||||
FN(void, gdk_draw_pixbuf, (G_obj *drawable,
|
||||
G_obj *gc,
|
||||
G_obj *pixbuf,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height,
|
||||
int dither,
|
||||
int x_dither,
|
||||
int y_dither))
|
||||
|
||||
FN(G_obj *, gdk_rgb_get_colormap, (void))
|
||||
FN(G_obj *, gdk_x11_colormap_get_xcolormap, (G_obj *))
|
||||
FN(G_obj *, gdk_gc_new, (G_obj *))
|
||||
1
archive/olddraw/Draw/gnome.dli
Normal file
1
archive/olddraw/Draw/gnome.dli
Normal file
|
|
@ -0,0 +1 @@
|
|||
FN(void, gnome_triggers_vdo, (const char *msg, const char *level, const char *supinfo[]))
|
||||
2
archive/olddraw/Draw/gobj.dli
Normal file
2
archive/olddraw/Draw/gobj.dli
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
FN(void, g_object_unref, (G_obj *object))
|
||||
FN(void, g_object_get, (G_obj *object, const char *first_property_name, ...))
|
||||
6
archive/olddraw/Draw/gpixbuf.dli
Normal file
6
archive/olddraw/Draw/gpixbuf.dli
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
FN(int, gdk_pixbuf_get_width, (const G_obj *pixbuf))
|
||||
FN(int, gdk_pixbuf_get_height, (const G_obj *pixbuf))
|
||||
FN(int, gdk_pixbuf_get_has_alpha, (const G_obj *pixbuf))
|
||||
FN(int, gdk_pixbuf_get_bits_per_sample, (const G_obj *pixbuf))
|
||||
FN(int, gdk_pixbuf_get_n_channels, (const G_obj *pixbuf))
|
||||
FN(byte *, gdk_pixbuf_get_pixels, (const G_obj *pixbuf))
|
||||
185
archive/olddraw/Draw/gtk.dli
Normal file
185
archive/olddraw/Draw/gtk.dli
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
FN(void, gtk_init, (int *, char ***))
|
||||
FN(G_obj *, gtk_window_new, (int))
|
||||
FN(void, gtk_widget_realize, (G_obj *))
|
||||
FN(G_obj *, gtk_fixed_new, (void))
|
||||
FN(void, gtk_container_add, (G_obj *, G_obj *))
|
||||
FN(void, gtk_fixed_put, (G_obj *, G_obj *, int, int))
|
||||
FN(void, gtk_widget_show, (G_obj *))
|
||||
FN(G_obj *, gtk_widget_get_style, (G_obj *widget))
|
||||
FN(G_obj *, gtk_settings_get_default, (void))
|
||||
|
||||
FN(void, gtk_object_sink, (G_obj *widget))
|
||||
|
||||
FN(void, gtk_paint_box, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_check, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_option, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_tab, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_slider, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int orientation
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_handle, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int orientation
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_resize_grip, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
G_obj *edge,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_arrow, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int arrow_type,
|
||||
int fill,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height
|
||||
))
|
||||
|
||||
FN(void, gtk_paint_extension, (
|
||||
G_obj *style,
|
||||
G_obj *window,
|
||||
int state_type,
|
||||
int shadow_type,
|
||||
void *area,
|
||||
G_obj *widget,
|
||||
const char *detail,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int gap_side
|
||||
))
|
||||
|
||||
FN(G_obj *, gtk_widget_render_icon, (G_obj *widget, const char *stock_id, int size, const char *detail))
|
||||
|
||||
FN(G_obj *, gtk_adjustment_new, (
|
||||
double value,
|
||||
double lower,
|
||||
double upper,
|
||||
double step_increment,
|
||||
double page_increment,
|
||||
double page_size
|
||||
))
|
||||
|
||||
FN(void, gtk_widget_set_state, (G_obj *widget, int state))
|
||||
FN(void, gtk_widget_set_sensitive, (G_obj *widget, int sensitive))
|
||||
|
||||
FN(void, gtk_toggle_button_set_active, (G_obj *toggle_button, int is_active))
|
||||
FN(void, gtk_toggle_button_set_inconsistent, (G_obj *toggle_button, int setting))
|
||||
FN(G_obj *, gtk_widget_get_display, (G_obj *widget))
|
||||
FN(void, gtk_widget_destroy, (G_obj *widget))
|
||||
|
||||
FN(void, gtk_widget_style_get, (G_obj *widget, const char *first_property_name, ...))
|
||||
FN(G_obj *, gtk_widget_get_parent, (G_obj *widget))
|
||||
FN(void, gtk_widget_set, (G_obj *widget, const char *first_property_name, ...))
|
||||
FN(void, gtk_window_set_default, (G_obj *window, G_obj *default_widget))
|
||||
|
||||
FN(G_obj *, gtk_dialog_new, (void))
|
||||
FN(G_obj *, gtk_button_new, (void))
|
||||
FN(G_obj *, gtk_radio_button_new, (void *group))
|
||||
FN(G_obj *, gtk_check_button_new, (void))
|
||||
FN(G_obj *, gtk_vscrollbar_new, (G_obj *adjustment))
|
||||
FN(G_obj *, gtk_hscrollbar_new, (G_obj *adjustment))
|
||||
FN(G_obj *, gtk_image_new, (void))
|
||||
FN(G_obj *, gtk_menu_bar_new, (void))
|
||||
FN(void, gtk_menu_shell_append, (G_obj *menu_shell, G_obj *child))
|
||||
FN(void, gtk_menu_item_set_submenu, (G_obj *item, G_obj *submenu))
|
||||
|
||||
|
||||
FN(G_obj *, gtk_menu_new, (void))
|
||||
FN(G_obj *, gtk_menu_item_new, (void))
|
||||
FN(G_obj *, gtk_notebook_new, (void))
|
||||
|
||||
FN(void, gtk_misc_get_alignment, (G_obj *misc, float *xalign, float *yalign))
|
||||
FN(void, gtk_misc_get_padding, (G_obj *misc, int *xpad, int *ypad))
|
||||
9
archive/olddraw/Draw/iml.h
Normal file
9
archive/olddraw/Draw/iml.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
//#BLITZ_APPROVE
|
||||
|
||||
#define IMAGE_KEEP
|
||||
|
||||
#include "iml_header.h"
|
||||
|
||||
#undef IMAGE_KEEP
|
||||
|
||||
#include "iml_source.h"
|
||||
63
archive/olddraw/Draw/iml_header.h
Normal file
63
archive/olddraw/Draw/iml_header.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//#BLITZ_APPROVE
|
||||
|
||||
//$-
|
||||
|
||||
#define IMAGE_META(k, v)
|
||||
#define IMAGE_SCAN(s)
|
||||
#define IMAGE_PACKED(n, d)
|
||||
|
||||
#define PREMULTIPLIED
|
||||
#define IMAGE_BEGIN_DATA
|
||||
#define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)
|
||||
#define IMAGE_END_DATA(n, c)
|
||||
|
||||
class IMAGECLASS {
|
||||
public:
|
||||
#define IMAGE_BEGIN(n) I_##n,
|
||||
#define IMAGE_ID(n) I_##n,
|
||||
enum {
|
||||
#include IMAGEFILE
|
||||
COUNT
|
||||
};
|
||||
#undef IMAGE_BEGIN
|
||||
#undef IMAGE_ID
|
||||
|
||||
public:
|
||||
static UPP::Iml& Iml();
|
||||
|
||||
static void Register__() { Register(ASSTRING(IMAGECLASS), Iml()); }
|
||||
|
||||
static int Find(const UPP::String& s);
|
||||
static int Find(const char *s);
|
||||
static int GetCount() { return Iml().GetCount(); }
|
||||
static UPP::String GetId(int i) { return Iml().GetId(i); }
|
||||
|
||||
static UPP::Image Get(int i);
|
||||
static UPP::Image Get(const char *s);
|
||||
static UPP::Image Get(const UPP::String& s);
|
||||
|
||||
static void Set(int i, const UPP::Image& m);
|
||||
static void Set(const char *s, const UPP::Image& m);
|
||||
|
||||
static void Reset() { Iml().Reset(); }
|
||||
|
||||
#define IMAGE_BEGIN(n) static UPP::Image n() { return Get(I_##n); }
|
||||
#define IMAGE_ID(n) static UPP::Image n() { return Get(I_##n); }
|
||||
#include IMAGEFILE
|
||||
#undef IMAGE_BEGIN
|
||||
#undef IMAGE_ID
|
||||
|
||||
};
|
||||
|
||||
#undef IMAGE_SCAN
|
||||
#undef IMAGE_PACKED
|
||||
#undef IMAGE_META
|
||||
|
||||
#undef IMAGE_BEGIN_DATA
|
||||
#undef IMAGE_END_DATA
|
||||
#undef IMAGE_DATA
|
||||
|
||||
#ifndef IMAGE_KEEP
|
||||
#undef IMAGECLASS
|
||||
#undef IMAGEFILE
|
||||
#endif
|
||||
140
archive/olddraw/Draw/iml_source.h
Normal file
140
archive/olddraw/Draw/iml_source.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
//#BLITZ_APPROVE
|
||||
|
||||
//$
|
||||
|
||||
#define IMAGE_META(k, v)
|
||||
|
||||
#define PREMULTIPLIED
|
||||
#define IMAGE_ID(n)
|
||||
#define IMAGE_BEGIN_DATA
|
||||
#define IMAGE_END_DATA(n, c)
|
||||
#define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)
|
||||
|
||||
#define IMAGE_BEGIN(n) const char *COMBINE(COMBINE(IMAGECLASS, _), n##__scans__)[] = {
|
||||
#define IMAGE_SCAN(s) s,
|
||||
#define IMAGE_PACKED(n, d) };
|
||||
#define IMAGE_DATA_BEGIN
|
||||
|
||||
|
||||
#include IMAGEFILE
|
||||
|
||||
#undef IMAGE_BEGIN
|
||||
#undef IMAGE_SCAN
|
||||
#undef IMAGE_PACKED
|
||||
|
||||
// -----------------------
|
||||
|
||||
#define IMAGE_SCAN(s)
|
||||
#define IMAGE_BEGIN(n)
|
||||
|
||||
// -----------------------
|
||||
|
||||
|
||||
UPP::Iml& IMAGECLASS::Iml() {
|
||||
static UPP::Image::Init init[] = {
|
||||
#define IMAGE_PACKED(n, d) { COMBINE(COMBINE(IMAGECLASS, _), n##__scans__), __countof(COMBINE(COMBINE(IMAGECLASS, _), n##__scans__)), d },
|
||||
|
||||
#include IMAGEFILE
|
||||
|
||||
{ NULL }
|
||||
#undef IMAGE_PACKED
|
||||
};
|
||||
|
||||
static const char *name[IMAGECLASS::COUNT] = {
|
||||
#define IMAGE_PACKED(n, d) #n,
|
||||
#undef IMAGE_ID
|
||||
#define IMAGE_ID(n) #n,
|
||||
|
||||
#include IMAGEFILE
|
||||
|
||||
#undef IMAGE_PACKED
|
||||
#undef IMAGE_ID
|
||||
#define IMAGE_ID(n)
|
||||
#define IMAGE_PACKED(n, d)
|
||||
};
|
||||
static UPP::Iml iml(init, name, COUNT);
|
||||
static bool imlinit;
|
||||
if(!imlinit) {
|
||||
imlinit = true;
|
||||
|
||||
#undef IMAGE_BEGIN_DATA
|
||||
#undef IMAGE_DATA
|
||||
#undef IMAGE_END_DATA
|
||||
#define IMAGE_BEGIN_DATA { static const UPP::byte data[] = {
|
||||
#define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)\
|
||||
a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf,
|
||||
|
||||
#define IMAGE_END_DATA(n, c) }; iml.AddData(data, n, c); }
|
||||
|
||||
#include IMAGEFILE
|
||||
|
||||
#undef IMAGE_BEGIN_DATA
|
||||
#undef IMAGE_END_DATA
|
||||
#undef IMAGE_DATA
|
||||
#define IMAGE_BEGIN_DATA
|
||||
#define IMAGE_END_DATA(n, c)
|
||||
#define IMAGE_DATA(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)
|
||||
|
||||
#undef PREMULTIPLIED
|
||||
#define PREMULTIPLIED iml.Premultiplied();
|
||||
#include IMAGEFILE
|
||||
#undef PREMULTIPLIED
|
||||
#define PREMULTIPLIED
|
||||
|
||||
}
|
||||
return iml;
|
||||
}
|
||||
|
||||
UPP::Image IMAGECLASS::Get(int i)
|
||||
{
|
||||
return Iml().Get(i);
|
||||
}
|
||||
|
||||
UPP::Image IMAGECLASS::Get(const char *s)
|
||||
{
|
||||
return Iml().Get(Find(s));
|
||||
}
|
||||
|
||||
int IMAGECLASS::Find(const UPP::String& s)
|
||||
{
|
||||
return Iml().Find(s);
|
||||
}
|
||||
|
||||
int IMAGECLASS::Find(const char *s)
|
||||
{
|
||||
return Iml().Find(s);
|
||||
}
|
||||
|
||||
void IMAGECLASS::Set(int i, const UPP::Image& m)
|
||||
{
|
||||
Iml().Set(i, m);
|
||||
}
|
||||
|
||||
void IMAGECLASS::Set(const char *s, const UPP::Image& m)
|
||||
{
|
||||
Iml().Set(Find(s), m);
|
||||
}
|
||||
|
||||
struct COMBINE(IMAGECLASS, __Reg) {
|
||||
COMBINE(IMAGECLASS, __Reg()) {
|
||||
IMAGECLASS::Register__();
|
||||
}
|
||||
};
|
||||
|
||||
static COMBINE(IMAGECLASS, __Reg) COMBINE(IMAGECLASS, ___Reg);
|
||||
|
||||
#undef IMAGE_BEGIN_DATA
|
||||
#undef IMAGE_DATA
|
||||
#undef IMAGE_END_DATA
|
||||
#undef IMAGE_PACKED
|
||||
#undef IMAGE_ID
|
||||
|
||||
#undef IMAGE_SCAN
|
||||
#undef IMAGE_BEGIN
|
||||
|
||||
#ifndef IMAGE_KEEP
|
||||
#undef IMAGECLASS
|
||||
#undef IMAGEFILE
|
||||
#endif
|
||||
|
||||
#undef IMAGE_META
|
||||
4
archive/olddraw/Draw/init
Normal file
4
archive/olddraw/Draw/init
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _Draw_icpp_init_stub
|
||||
#define _Draw_icpp_init_stub
|
||||
#include "Core/init"
|
||||
#endif
|
||||
15
archive/olddraw/Draw/src.tpp/Display$en-us.tpp
Normal file
15
archive/olddraw/Draw/src.tpp/Display$en-us.tpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
TITLE("Display")
|
||||
COMPRESSED
|
||||
120,156,237,27,139,114,219,54,242,87,48,238,99,100,159,164,35,41,201,146,229,235,77,18,199,73,61,205,37,29,217,233,205,141,199,182,32,10,146,112,166,72,149,15,59,206,163,223,126,187,11,144,4,37,82,150,31,73,51,215,52,157,136,36,128,125,97,95,216,69,78,29,246,253,247,86,221,250,206,186,229,191,254,115,49,225,137,23,159,157,202,118,187,183,207,157,206,254,229,47,111,246,246,119,158,212,118,219,219,8,197,6,40,173,174,221,234,117,90,118,219,217,133,191,236,150,237,116,156,86,219,238,57,123,237,94,171,213,179,250,174,199,163,232,236,212,115,122,189,125,92,228,192,34,167,219,113,236,110,187,215,238,217,173,110,207,129,181,142,101,57,86,215,233,216,237,86,207,233,244,199,34,114,207,78,121,175,181,191,51,216,133,69,45,196,4,192,45,123,215,105,119,219,142,213,178,156,54,160,178,123,189,182,221,237,244,90,123,187,187,125,151,47,98,25,248,26,151,180,109,199,222,31,217,221,125,160,249,143,63,254,104,218,109,75,81,208,6,96,182,213,6,82,109,248,102,
|
||||
181,157,174,221,217,179,246,58,61,187,103,181,0,120,167,107,117,250,11,30,242,121,53,235,157,91,89,239,90,125,25,11,0,177,243,55,219,238,194,146,221,250,238,119,118,187,11,140,246,90,237,78,175,107,1,114,199,113,90,45,199,110,57,123,123,78,103,183,211,237,207,4,31,139,240,236,244,195,197,167,31,14,95,55,222,30,179,211,200,222,255,229,137,197,78,127,176,172,134,101,61,169,89,77,171,233,116,58,219,76,75,54,253,14,148,177,139,244,149,61,151,209,194,227,55,103,63,158,157,70,206,126,250,202,184,63,78,159,135,13,192,36,175,196,88,1,18,17,11,133,15,159,216,111,220,75,4,147,126,28,176,120,38,88,180,16,174,156,72,152,23,10,55,230,254,52,241,120,200,120,40,120,147,13,196,68,192,42,23,22,195,108,13,56,194,65,150,68,176,66,250,108,206,253,27,118,45,199,83,17,195,0,252,31,199,161,28,37,49,44,225,147,9,64,148,254,148,240,40,236,248,22,76,244,2,69,74,212,100,90,21,153,156,47,60,49,23,126,204,113,167,17,71,196,142,227,
|
||||
113,202,29,208,176,16,225,36,8,231,140,123,30,227,46,206,138,88,45,18,130,141,132,23,92,51,24,51,23,160,158,133,146,212,102,187,169,69,133,63,86,246,115,186,195,126,147,81,194,61,22,197,55,158,96,46,0,4,33,0,47,103,25,151,192,213,112,139,134,135,91,140,20,71,196,32,199,145,140,217,196,227,211,8,25,202,185,131,193,89,48,142,104,43,22,97,112,37,199,130,241,241,88,34,17,128,70,250,72,191,226,143,143,130,36,134,165,191,39,50,4,60,87,138,16,190,88,8,64,2,82,239,43,34,119,52,177,164,247,153,170,167,26,179,195,14,222,14,142,223,12,26,31,51,229,120,153,72,38,148,32,153,140,152,155,132,33,62,214,134,91,51,78,175,81,16,14,183,182,155,103,6,220,254,16,254,164,170,3,143,47,222,28,188,61,238,151,96,163,1,80,123,6,8,77,68,8,122,18,184,73,212,92,3,245,248,240,213,225,193,73,25,88,53,146,177,208,248,184,196,68,4,207,110,44,198,107,137,30,28,62,125,254,230,245,171,255,148,33,72,199,170,81,128,202,143,
|
||||
135,141,192,247,110,82,36,36,248,14,216,103,110,149,5,123,188,146,97,140,91,150,193,188,10,228,184,194,100,193,198,127,229,96,117,197,225,90,250,122,78,172,132,252,250,92,13,224,99,113,234,240,199,28,86,139,45,13,214,115,26,72,133,43,136,32,44,3,16,164,198,130,143,235,176,132,247,199,66,182,173,209,208,243,58,60,191,87,225,33,80,7,129,23,132,26,20,61,87,137,184,5,230,117,249,88,160,22,124,33,42,249,39,96,227,235,32,28,107,96,244,92,13,140,220,71,113,120,251,98,73,152,218,65,157,204,64,23,83,205,82,222,4,181,147,92,17,122,64,84,162,212,87,43,143,21,163,2,115,215,5,10,200,219,6,134,83,39,209,55,217,235,32,22,224,134,57,40,58,233,250,155,95,200,87,22,66,4,46,76,208,141,161,7,28,179,255,38,145,246,208,44,190,89,128,39,134,149,215,96,228,224,84,229,212,135,69,8,160,134,51,221,144,71,51,22,128,151,15,175,101,36,96,115,27,26,141,235,73,164,205,13,198,24,0,162,5,240,41,71,210,147,49,57,115,96,
|
||||
137,66,3,16,142,252,164,1,134,28,72,59,55,221,3,82,247,198,71,52,137,178,177,16,198,78,120,136,1,37,19,75,217,188,223,97,158,230,39,128,120,161,36,9,30,165,100,42,170,81,227,227,113,50,157,138,40,86,172,138,105,24,36,200,44,106,77,217,26,165,47,230,170,17,119,47,111,91,165,20,3,8,51,162,80,243,243,121,159,103,25,73,223,252,208,55,63,244,112,63,132,121,34,37,64,47,223,30,101,177,148,252,12,166,79,144,222,68,152,255,80,130,148,58,172,220,55,65,250,72,74,169,161,215,25,228,141,44,154,5,137,55,134,116,226,74,40,171,129,165,30,71,115,138,130,185,184,70,208,128,61,205,105,210,76,79,57,48,240,59,9,154,145,7,238,5,169,87,235,225,129,18,93,200,219,48,151,51,172,82,123,128,140,144,38,171,229,142,210,36,141,205,209,25,186,30,36,102,4,203,128,17,9,76,9,99,225,221,212,33,43,133,201,201,116,6,227,224,218,138,180,73,244,156,19,233,43,233,161,235,91,50,72,242,167,68,118,204,163,203,237,111,94,80,205,163,
|
||||
241,59,122,66,178,138,99,249,62,181,123,124,172,118,140,47,69,12,103,134,213,57,181,47,227,100,170,236,239,88,25,66,40,226,36,244,25,197,100,30,130,190,1,157,164,42,83,136,220,62,187,162,173,52,206,125,77,118,216,156,54,153,156,100,250,39,35,227,120,114,52,231,176,47,117,140,207,81,1,1,170,53,202,0,141,21,159,105,34,90,198,66,190,19,30,28,210,158,153,58,173,22,105,195,74,87,137,119,180,11,161,88,64,172,207,78,113,26,158,74,68,214,41,100,54,184,243,119,8,8,68,20,113,135,218,164,81,40,197,69,238,205,92,225,238,161,242,110,10,50,64,70,254,52,253,48,130,221,202,241,193,92,230,190,187,231,186,155,205,244,113,160,183,60,83,192,212,157,41,21,188,20,98,145,158,245,57,250,120,240,67,40,183,205,182,220,24,4,62,26,31,7,233,161,248,90,142,227,89,147,29,77,216,123,17,6,166,222,142,48,62,204,23,73,172,60,42,226,47,32,134,165,241,12,184,43,197,113,99,226,152,9,57,157,197,15,65,242,238,161,186,91,252,233,84,148,
|
||||
132,162,56,76,150,19,165,124,183,158,198,113,120,2,54,152,57,16,42,167,0,119,30,184,100,29,133,96,71,175,68,24,203,145,71,254,63,55,76,163,108,82,199,231,1,138,196,44,43,193,183,3,176,105,17,230,197,149,24,197,112,61,19,152,248,107,246,22,88,106,162,128,42,41,45,72,105,162,35,4,193,153,193,95,128,28,68,60,150,19,42,47,197,16,174,71,128,100,28,44,168,90,228,7,254,176,225,39,88,225,201,139,73,42,56,10,114,50,133,152,229,148,136,140,108,238,223,199,49,122,60,109,117,250,173,74,118,177,33,55,69,47,5,199,177,226,85,163,42,219,29,66,245,2,206,96,26,15,62,86,33,153,224,152,70,130,243,82,167,185,30,248,166,169,34,133,107,147,133,60,218,62,28,182,10,235,26,250,179,165,136,94,68,81,64,144,238,255,121,174,157,41,72,211,233,89,236,40,79,152,151,14,35,138,198,34,121,69,7,150,125,221,206,84,31,171,145,153,186,84,166,29,46,230,76,51,177,52,97,213,132,135,59,152,151,53,31,131,207,95,205,108,254,49,57,165,
|
||||
29,250,170,88,5,210,76,107,88,98,150,108,166,96,46,5,86,39,107,88,69,59,42,227,113,162,121,44,140,111,200,98,223,100,141,158,61,57,245,135,53,112,52,195,237,254,253,4,64,32,86,217,55,28,186,172,224,158,223,166,210,179,32,148,239,129,77,172,23,35,22,60,119,53,217,211,5,86,156,211,144,172,10,245,79,95,29,189,124,61,188,120,117,248,226,164,158,190,28,28,190,62,57,28,144,59,214,95,6,71,47,127,62,185,77,36,175,196,36,30,214,238,45,14,92,158,75,35,99,140,164,100,176,230,193,180,219,40,81,145,232,1,180,40,0,27,80,163,131,164,75,243,111,35,139,130,230,3,168,162,245,27,16,21,82,190,178,89,234,27,128,91,224,113,16,94,80,128,174,149,102,119,229,118,146,197,110,56,52,195,161,211,200,224,87,61,195,19,107,149,183,50,133,47,100,202,134,202,27,51,102,220,112,126,195,29,195,42,98,19,122,38,156,3,4,137,121,81,148,145,0,39,241,8,139,148,105,62,74,66,203,146,9,210,123,108,32,81,197,210,76,50,96,179,49,1,
|
||||
252,60,60,146,42,92,35,123,231,236,250,255,155,203,52,245,90,206,186,150,14,58,95,152,211,22,171,250,61,78,15,215,105,139,83,139,102,229,59,121,212,172,75,153,246,6,39,137,239,234,246,222,212,11,70,220,139,134,91,88,139,74,191,71,250,184,140,228,167,13,70,248,164,123,171,84,175,151,84,26,83,171,243,131,59,77,117,77,155,99,31,62,180,58,45,171,191,219,238,90,51,123,255,73,205,177,192,198,105,52,93,229,243,185,56,235,247,245,199,188,3,10,223,206,159,56,244,121,71,157,127,179,140,255,220,200,254,97,218,79,172,148,251,102,46,6,149,236,3,243,49,237,78,226,123,34,138,116,205,63,115,27,212,151,229,35,8,72,219,77,68,94,141,218,60,108,220,13,63,121,194,97,131,98,32,30,209,30,133,156,194,57,231,110,244,168,56,113,127,74,40,247,203,104,49,223,114,58,50,172,52,204,106,105,3,153,250,46,17,106,231,141,58,33,21,106,157,73,148,90,207,210,73,109,69,24,112,94,69,50,115,137,20,63,24,2,145,115,137,151,5,64,129,205,211,35,
|
||||
85,113,99,80,121,119,38,140,160,69,117,3,152,58,145,96,170,215,179,192,203,142,87,234,182,193,18,25,84,127,202,104,48,223,74,36,161,138,85,249,225,147,235,45,169,171,236,136,118,64,71,242,56,88,12,27,152,99,96,219,201,135,152,190,132,247,133,140,193,176,139,216,87,191,85,210,16,185,220,83,181,130,9,226,164,139,15,105,53,118,121,175,181,174,20,113,149,125,173,196,150,169,155,244,55,193,53,254,25,204,197,67,147,41,199,89,58,124,119,228,170,40,98,171,202,33,86,112,224,203,76,130,163,30,5,225,120,85,226,88,209,6,221,204,168,41,190,151,160,215,19,214,203,250,211,167,162,151,103,21,225,174,226,194,205,106,235,204,236,81,177,139,126,89,238,178,8,229,21,143,69,69,84,252,23,24,60,31,121,226,156,165,79,217,196,127,172,69,246,207,139,52,54,102,99,232,79,184,50,246,165,10,15,245,46,220,96,62,146,190,200,28,19,6,200,98,196,65,105,153,247,106,244,77,149,225,150,190,133,162,219,202,16,200,204,230,77,147,29,17,234,244,212,101,240,158,
|
||||
241,164,163,21,140,217,78,47,29,173,76,82,255,58,87,38,30,220,66,188,24,254,116,113,76,139,84,78,116,95,192,37,13,197,28,52,213,39,30,181,191,136,176,141,25,214,102,213,230,35,255,42,184,4,5,86,93,56,208,65,84,72,78,245,230,84,109,177,36,152,127,173,172,39,63,70,211,236,43,232,132,173,59,233,125,21,70,180,182,201,112,207,222,196,205,253,150,61,86,43,228,155,241,62,204,120,87,109,86,181,75,30,102,180,239,234,12,178,76,23,126,168,141,179,108,191,172,134,217,93,29,19,189,186,106,31,213,117,135,167,180,167,254,149,155,246,35,181,178,111,219,169,124,225,221,125,237,106,229,232,87,74,53,48,53,44,52,191,30,153,217,91,219,178,127,106,187,52,149,108,70,229,131,130,216,95,178,41,250,5,116,228,46,208,192,130,223,111,182,247,135,32,67,224,148,238,66,5,57,13,181,232,125,19,221,22,254,220,108,87,213,223,114,142,205,168,94,224,234,88,100,135,241,251,150,232,242,211,214,18,160,98,184,207,241,175,54,34,214,92,215,28,163,251,46,221,
|
||||
208,59,178,89,184,44,113,103,38,213,181,139,226,141,139,37,6,175,214,48,88,105,141,87,133,251,11,247,102,238,203,109,94,238,220,190,140,228,204,139,3,107,37,185,172,40,159,65,208,7,120,107,47,23,245,118,126,159,101,14,71,214,34,189,88,64,75,70,17,248,64,186,182,204,61,143,138,200,234,16,194,221,88,213,123,253,64,119,85,100,224,15,183,234,249,60,35,138,34,231,185,235,215,119,172,200,9,88,117,102,45,27,127,73,74,255,152,119,138,40,49,40,153,83,153,22,12,140,235,93,183,5,251,205,66,251,237,252,164,74,173,207,33,69,205,174,224,169,116,214,70,92,45,43,221,42,95,27,223,48,179,242,30,219,40,8,188,77,136,41,199,24,135,248,15,179,10,23,247,34,177,220,231,51,208,174,86,138,106,101,93,20,49,95,196,55,249,228,186,10,207,126,144,91,105,164,110,244,223,9,211,103,114,89,75,163,101,252,228,69,48,98,36,191,79,188,46,32,105,184,183,134,165,63,145,215,207,226,164,185,183,137,44,223,85,201,146,252,88,181,247,46,149,234,178,15,
|
||||
7,18,74,188,4,252,156,253,15,162,7,123,54,
|
||||
1852
archive/olddraw/Draw/src.tpp/Draw$en-us.tpp
Normal file
1852
archive/olddraw/Draw/src.tpp/Draw$en-us.tpp
Normal file
File diff suppressed because it is too large
Load diff
13
archive/olddraw/Draw/src.tpp/Font$en-us.tpp
Normal file
13
archive/olddraw/Draw/src.tpp/Font$en-us.tpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
TITLE("Font")
|
||||
COMPRESSED
|
||||
120,156,189,90,9,115,219,182,18,254,43,232,180,205,200,142,236,240,180,100,169,237,196,241,209,106,154,216,25,31,233,235,120,44,11,34,33,11,45,69,234,17,144,28,191,76,242,219,187,0,72,10,148,120,72,178,251,236,177,69,145,216,19,187,223,98,1,222,90,232,135,31,140,166,241,189,81,243,211,57,33,35,60,11,248,221,45,117,156,118,23,91,110,247,239,223,47,14,187,187,111,27,7,206,142,224,98,2,23,187,101,218,109,215,54,29,235,0,254,153,182,105,185,150,237,152,109,235,208,105,219,118,219,232,120,1,102,236,238,54,176,218,237,174,32,178,128,200,106,185,150,217,114,218,78,219,180,91,109,11,104,45,195,176,140,150,229,154,142,221,182,220,142,79,152,119,119,139,219,118,119,247,242,0,136,108,33,9,152,27,230,129,229,180,28,203,176,13,203,1,81,102,187,237,152,45,183,109,31,30,28,116,60,60,229,52,10,19,89,212,52,45,179,59,52,91,93,208,249,219,183,111,251,166,99,40,13,28,96,102,26,14,168,106,194,61,195,177,90,166,123,104,28,186,109,179,
|
||||
109,216,192,220,109,25,110,103,138,99,60,41,55,221,173,53,189,101,116,40,39,192,98,247,181,105,182,128,228,160,121,240,189,233,180,192,208,182,237,184,237,150,1,194,45,203,178,109,203,180,173,195,67,203,61,112,91,157,49,193,62,137,239,110,191,220,127,253,241,244,124,239,230,10,221,50,179,251,123,103,0,191,103,81,200,197,167,244,104,7,221,254,104,24,123,134,241,182,97,236,27,251,150,235,238,160,196,213,234,62,186,79,175,222,26,72,144,46,30,116,22,143,22,196,211,152,206,49,39,171,228,125,33,243,136,49,250,16,126,194,193,140,92,63,77,201,121,212,71,43,183,50,210,159,202,36,55,81,198,244,236,226,252,122,112,255,169,143,146,139,162,49,66,240,135,104,78,240,48,32,125,148,94,213,139,249,229,254,151,187,87,119,183,204,234,202,251,136,50,132,145,23,133,94,76,56,81,94,66,124,140,57,18,97,22,211,33,17,95,9,194,211,41,129,89,15,61,130,162,17,226,228,51,223,71,61,73,157,138,110,162,49,102,200,131,73,154,2,191,233,19,138,166,36,198,34,
|
||||
232,16,14,125,49,82,186,67,200,154,147,152,83,32,65,143,148,143,81,76,189,241,96,79,61,196,67,26,80,78,9,219,79,116,76,62,148,40,198,163,152,134,15,136,17,224,128,3,132,57,7,13,103,92,232,24,101,10,75,125,149,134,215,99,33,47,142,9,155,70,161,47,73,159,24,4,30,26,37,166,11,142,4,148,11,37,209,40,138,39,194,188,17,6,51,105,232,147,207,104,176,135,8,246,198,57,58,97,39,155,18,143,142,168,151,12,155,11,237,165,188,24,140,128,63,22,77,8,132,13,241,201,136,134,82,2,12,3,61,65,4,104,52,153,128,87,4,47,214,17,6,26,210,78,244,229,139,229,30,186,157,150,99,184,63,65,196,119,251,72,216,30,24,221,221,52,158,145,10,243,206,213,245,137,8,141,187,187,78,231,231,116,16,186,226,224,103,28,251,232,215,155,158,82,52,21,62,124,66,211,0,115,97,222,62,58,198,33,2,39,225,128,147,88,61,59,137,241,163,96,74,248,21,247,133,132,125,224,91,46,252,242,226,195,209,121,137,104,70,98,58,146,194,171,121,28,
|
||||
93,246,142,222,151,241,192,33,27,236,173,203,233,248,226,230,178,119,122,89,194,11,252,28,177,41,76,167,191,6,171,171,63,63,188,187,40,213,234,105,50,140,130,132,203,215,175,249,240,188,134,104,67,19,2,209,232,169,41,86,169,21,50,46,51,198,83,46,143,134,28,167,243,209,11,71,145,160,24,71,43,209,39,104,229,99,21,84,66,132,187,132,114,201,252,119,80,209,195,95,9,63,3,139,143,163,25,124,111,12,118,50,52,132,104,135,124,244,80,1,192,81,29,2,53,232,208,121,101,3,26,59,41,130,92,18,62,139,67,133,16,225,108,50,36,113,154,62,131,189,16,79,32,222,241,28,211,64,192,195,254,34,208,203,52,62,7,138,65,3,84,169,208,89,226,222,21,23,48,208,71,234,179,74,113,193,114,161,247,218,134,219,42,95,179,39,197,6,3,239,12,45,146,145,187,25,105,149,189,103,48,36,213,174,39,70,15,26,128,138,140,3,122,226,120,176,251,188,41,91,97,94,105,191,148,91,192,71,27,1,58,45,6,12,118,53,39,133,186,119,51,31,9,5,148,135,
|
||||
52,28,205,194,66,115,148,36,95,35,46,68,50,172,21,23,254,99,20,251,125,36,63,170,162,66,48,252,183,162,130,134,34,143,147,186,55,140,102,188,36,62,144,40,150,209,100,72,67,53,22,28,36,174,227,39,52,10,240,195,74,93,104,183,160,46,152,118,86,23,10,224,235,172,247,159,211,147,143,189,235,227,223,82,8,51,84,141,31,236,169,137,96,26,28,166,72,88,4,131,199,71,239,79,143,222,189,63,45,101,51,138,9,9,158,16,243,176,76,109,212,160,178,152,2,142,205,137,7,21,21,41,23,52,17,217,127,128,162,24,207,8,135,69,208,78,149,76,9,189,215,127,126,92,22,42,2,84,160,38,75,0,152,73,84,133,133,160,112,88,64,56,20,49,86,193,247,248,226,195,199,139,171,211,19,141,235,205,224,245,224,53,154,49,146,20,113,88,71,120,145,79,196,10,2,230,99,26,49,130,38,20,150,111,176,88,120,15,83,19,202,4,192,158,16,36,128,91,205,153,120,74,62,83,198,197,197,98,64,90,25,86,18,62,155,154,14,68,97,69,168,11,188,150,41,217,
|
||||
209,162,49,181,73,139,74,185,214,46,10,237,252,128,198,78,54,36,201,244,52,71,115,153,41,107,126,117,30,254,70,232,195,152,63,75,61,197,98,77,5,245,148,26,75,66,9,33,245,138,254,65,125,62,126,150,158,146,195,70,106,74,45,31,5,89,170,36,130,36,48,228,74,192,87,141,162,122,188,118,17,44,87,95,47,128,74,185,124,21,44,141,12,189,20,110,224,252,69,49,151,107,106,181,128,157,193,146,90,91,224,172,141,225,53,102,41,252,86,202,229,64,188,212,40,29,201,107,140,186,18,38,0,232,106,148,141,228,186,177,179,83,101,194,90,186,167,171,182,68,253,244,107,185,5,27,168,174,207,71,52,252,11,48,22,90,139,104,78,101,71,35,64,43,16,189,91,65,229,17,145,152,44,75,43,215,35,18,121,242,5,54,51,170,159,239,31,7,175,114,139,13,13,114,54,170,164,225,106,21,133,254,99,121,217,80,165,116,138,72,219,168,157,135,162,151,83,92,118,135,10,173,64,47,52,165,159,73,192,222,248,17,103,149,1,150,96,214,54,150,228,192,234,101,13,81,
|
||||
136,133,110,160,32,22,64,217,70,6,190,139,2,63,215,138,172,103,156,32,91,238,58,150,89,159,71,91,50,87,132,117,236,21,243,97,20,5,207,212,190,96,102,4,215,194,169,25,46,77,205,10,32,113,28,80,111,11,155,21,97,189,75,183,22,144,146,214,137,72,5,108,229,216,101,17,47,233,218,27,128,157,56,128,46,125,11,227,51,218,122,7,63,71,140,70,93,39,72,19,179,149,167,11,4,189,164,179,197,202,229,111,2,149,106,11,47,100,180,245,206,126,142,24,141,186,78,144,38,102,43,103,23,8,122,142,179,1,207,211,27,18,215,1,192,103,33,19,87,208,70,249,111,168,76,162,55,51,152,97,49,193,111,88,42,29,154,68,159,64,39,83,1,231,231,81,120,20,114,122,20,80,204,200,118,216,171,51,168,159,193,23,16,184,169,200,188,192,173,38,180,76,228,51,103,85,204,230,155,100,42,195,40,28,236,97,16,2,255,149,24,185,125,32,118,162,101,67,238,83,15,203,237,113,177,163,175,141,147,91,225,227,104,22,248,192,130,139,205,201,153,160,125,28,19,40,
|
||||
234,208,110,203,190,54,93,9,84,174,141,89,90,126,75,251,45,221,182,130,101,48,211,235,100,213,66,120,85,244,162,76,109,45,60,95,75,54,19,159,3,241,173,53,88,193,216,205,148,200,129,219,214,74,172,96,79,77,71,146,222,188,38,12,162,16,194,6,98,37,94,1,150,120,9,89,196,89,147,199,233,156,164,232,162,105,90,108,221,106,226,111,109,98,113,54,214,216,41,246,174,16,29,45,165,178,102,200,90,118,44,250,122,201,124,209,193,15,94,109,213,113,213,238,106,151,236,234,86,109,158,235,82,202,118,118,243,29,26,143,244,93,77,181,153,139,122,35,181,47,78,153,4,150,57,196,130,175,237,33,52,179,67,71,128,47,193,225,124,22,4,85,248,162,14,17,163,88,76,253,90,61,184,214,127,151,71,67,202,21,208,127,189,56,72,59,112,156,28,109,38,123,102,162,57,26,205,2,97,8,163,208,134,211,209,147,48,91,245,224,18,76,229,49,91,110,183,80,58,64,30,237,84,246,228,121,195,101,107,248,47,219,158,89,94,177,65,166,181,141,234,209,102,14,107,170,
|
||||
19,223,164,69,246,198,56,124,128,108,90,10,164,202,35,129,43,240,38,196,212,255,4,230,170,96,38,120,146,75,35,205,63,243,136,22,159,3,100,92,86,179,168,191,96,43,115,132,136,55,29,10,115,132,21,37,72,194,87,107,163,229,84,163,134,118,22,178,56,119,198,108,121,127,173,178,141,206,98,226,103,248,109,100,79,182,197,68,157,93,73,44,108,18,90,54,26,173,17,27,165,54,125,247,162,54,125,247,127,52,9,38,254,56,154,76,113,44,166,253,49,202,31,254,86,38,185,216,21,199,108,44,223,125,120,225,221,209,140,239,134,8,183,216,199,2,6,218,17,116,233,250,79,32,248,243,10,51,48,216,176,28,167,69,164,174,122,100,215,122,199,176,252,70,204,226,56,187,23,82,158,230,175,20,1,200,148,28,181,55,179,221,47,5,94,77,64,246,220,11,40,162,218,229,214,4,53,10,9,68,111,230,119,252,86,20,43,168,236,101,187,121,35,125,35,182,185,254,121,177,157,216,179,138,101,186,51,70,137,51,52,152,150,2,19,64,19,239,247,104,143,18,142,235,249,33,
|
||||
91,17,137,185,36,113,30,202,215,112,72,213,82,71,177,236,35,245,169,193,120,201,142,231,218,139,17,184,174,205,89,13,140,238,55,73,196,99,245,126,148,82,43,141,66,113,253,41,41,36,73,236,139,215,166,212,189,202,154,81,224,105,165,250,75,58,90,114,236,163,156,153,75,213,242,191,171,17,150,179,84,89,151,152,170,31,72,222,253,3,118,76,35,136,
|
||||
|
||||
8
archive/olddraw/Draw/src.tpp/FontInfo$en-us.tpp
Normal file
8
archive/olddraw/Draw/src.tpp/FontInfo$en-us.tpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
TITLE("FontInfo")
|
||||
COMPRESSED
|
||||
120,156,181,88,13,79,219,56,24,254,43,150,182,161,150,65,101,59,73,147,182,183,19,211,177,221,161,109,220,4,59,221,73,85,161,110,226,180,214,242,181,216,45,160,211,237,183,223,107,167,105,27,40,109,104,1,16,202,135,223,199,239,243,126,199,125,138,94,191,198,71,248,21,222,242,211,61,229,33,155,70,106,208,23,182,237,245,24,117,122,223,63,253,217,233,29,158,52,218,118,83,163,16,64,177,92,98,121,142,69,108,218,134,127,196,34,212,161,150,77,60,218,177,61,203,242,112,215,143,152,148,131,126,68,61,175,167,133,40,8,81,215,161,196,181,61,219,35,150,235,81,144,165,24,83,236,82,135,216,150,71,157,110,192,165,63,232,51,207,234,29,94,180,65,200,210,59,1,56,38,109,106,187,54,197,22,166,54,108,69,60,207,38,174,227,89,157,118,187,235,179,76,137,52,153,239,37,8,161,164,55,34,110,15,116,254,249,243,103,139,216,184,208,192,6,48,130,109,80,149,192,51,108,83,151,56,29,220,113,60,226,97,11,192,29,23,59,221,140,229,44,126,156,186,179,149,
|
||||
186,139,187,66,113,128,56,124,75,136,11,34,237,163,246,43,98,187,64,212,179,108,199,115,49,108,78,41,181,44,74,44,218,233,80,167,237,184,221,9,103,1,207,7,253,127,175,255,123,243,225,252,248,175,75,212,151,164,247,169,59,132,223,143,105,162,206,146,48,213,215,198,170,93,212,127,131,241,49,198,39,13,220,194,45,234,56,77,52,55,119,241,28,93,151,87,39,24,149,226,203,151,221,229,235,37,64,150,139,25,83,252,33,196,149,222,247,75,58,227,108,20,241,43,84,94,45,22,254,178,105,175,95,175,7,7,131,190,164,61,244,53,79,103,2,252,139,20,191,85,40,230,42,23,190,68,97,154,163,177,152,241,196,136,182,208,183,137,144,8,254,114,176,199,240,56,77,162,187,130,25,186,17,106,130,124,48,83,134,2,206,51,228,167,217,29,74,51,158,51,237,123,137,26,34,81,60,79,88,4,18,83,201,53,66,200,115,158,248,28,150,78,19,37,146,49,98,73,128,126,76,193,59,240,40,206,34,225,3,223,0,201,59,9,254,66,105,136,228,132,229,229,58,159,249,19,
|
||||
184,110,182,180,250,206,26,79,100,42,239,94,221,127,120,202,20,187,66,143,137,252,206,213,123,233,243,68,13,27,195,166,15,90,171,238,138,3,74,147,1,145,165,123,32,236,42,206,92,64,84,151,52,154,139,69,200,0,151,86,191,224,106,154,131,121,212,4,72,3,61,230,131,149,144,207,163,8,129,27,56,16,101,35,112,168,121,63,98,146,71,34,225,134,50,238,109,162,113,202,247,231,49,199,120,54,34,35,30,165,55,79,37,242,225,182,136,154,189,152,148,32,59,80,97,65,32,116,0,179,8,201,140,249,218,17,76,65,86,36,10,233,90,152,11,83,218,32,152,33,98,99,96,9,82,41,232,35,121,174,128,176,186,225,144,57,234,38,69,154,174,212,49,172,179,171,133,46,88,206,139,68,8,106,24,225,44,121,6,35,148,32,59,24,33,78,165,2,109,195,156,243,185,21,128,33,212,138,101,180,163,25,139,166,252,169,188,254,224,98,60,217,47,72,11,136,39,114,90,168,221,104,162,225,219,149,88,215,247,199,134,242,196,224,26,135,193,157,246,222,194,121,219,121,125,134,
|
||||
229,207,192,109,9,243,116,126,133,220,130,95,153,1,141,102,13,245,223,207,248,223,34,80,147,253,170,224,28,100,151,156,155,65,215,24,115,104,41,32,175,205,190,168,39,53,148,255,194,110,247,87,190,4,217,37,87,216,173,136,161,90,236,164,252,92,115,80,111,15,229,215,105,62,168,33,108,33,191,250,170,14,93,149,42,32,203,130,25,211,157,220,12,1,171,156,75,165,15,13,58,106,64,191,79,3,232,233,34,65,211,68,232,235,173,1,89,204,16,105,62,236,15,7,123,153,102,21,232,37,205,115,201,98,136,97,185,112,69,163,98,131,58,9,248,153,135,234,82,215,217,125,67,97,1,244,146,124,79,77,31,28,241,34,32,160,254,155,137,79,135,65,4,219,35,211,40,42,49,97,134,2,61,195,233,247,186,183,32,232,26,12,101,76,143,136,129,25,57,31,9,160,22,58,231,99,128,135,129,200,52,28,24,83,153,9,68,232,201,75,145,98,222,144,247,118,60,66,89,42,197,122,89,80,60,231,122,172,101,213,254,102,134,25,173,109,146,42,211,212,138,121,56,186,203,38,
|
||||
53,220,120,161,75,240,179,248,113,137,244,162,129,43,98,17,177,92,79,48,171,177,99,56,27,215,154,150,200,131,241,26,127,214,48,199,39,232,64,48,177,23,182,56,218,207,32,115,172,221,172,65,170,239,142,80,77,57,250,180,242,248,189,208,17,230,196,16,26,185,169,121,15,230,198,210,180,171,81,78,6,149,91,58,208,153,177,181,123,156,201,143,226,150,7,95,133,242,55,247,190,81,154,70,143,219,118,21,166,102,247,251,150,67,50,137,176,32,7,57,20,167,73,58,60,54,121,180,117,8,60,147,151,62,139,204,247,234,94,74,47,80,118,212,89,143,182,48,183,202,18,166,70,56,235,219,77,58,47,190,61,175,10,93,244,229,198,152,126,184,160,214,192,161,197,138,218,4,121,155,142,20,84,81,120,14,156,74,125,107,114,121,134,129,117,9,179,3,15,227,138,249,216,29,230,105,92,147,28,66,53,232,137,136,159,67,87,222,234,174,75,165,207,23,230,14,43,110,54,19,158,3,215,164,251,15,33,40,131,246,8,89,31,67,163,225,190,8,133,223,170,88,33,99,48,65,
|
||||
1,215,16,144,139,113,234,126,205,216,230,206,202,125,195,236,95,121,116,48,108,46,207,167,214,156,8,53,150,100,150,135,87,134,197,131,147,167,117,226,195,131,213,154,25,46,158,55,75,35,252,166,15,134,12,96,62,245,97,28,67,13,115,106,84,127,14,124,183,141,85,229,212,231,106,179,138,43,99,225,187,93,76,240,148,189,214,154,227,189,148,98,156,196,250,27,186,212,164,174,69,170,158,222,230,214,21,7,204,109,47,17,143,51,117,247,160,80,12,254,7,99,121,167,180,
|
||||
317
archive/olddraw/Draw/src.tpp/Image$en-us.tpp
Normal file
317
archive/olddraw/Draw/src.tpp/Image$en-us.tpp
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
topic "Image and ImageBuffer";[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[i448;a25;kKO9;*@(64)2 $$1,0#37138531426314131252341829483380:class]
|
||||
[l288;2 $$2,2#27521748481378242620020725143825:desc]
|
||||
[a83;*R6 $$3,0#31310162474203024125188417583966:caption]
|
||||
[l288;i1121;b17;O9;~~~.1408;2 $$4,0#10431211400427159095818037425705:param]
|
||||
[i448;a25;kKO9;*@(64)2 $$5,0#37138531426314131252341829483370:item]
|
||||
[*+117 $$6,6#14700283458701402223321329925657:header]
|
||||
[{_}%EN-US
|
||||
[s3; Image and ImageBuffer&]
|
||||
[s1;K:`:`:Image`:`:class:%- [@(0.0.255) class]_[@0 Image]_:_[@(0.0.255) public]_[^`:`:AssignValueTypeNo^ A
|
||||
ssignValueTypeNo]<_[@0 Image], [@3 150], [^`:`:Moveable^ Moveable]<[@0 Image]>_>_&]
|
||||
[s2; Image represents an immutable image value. Image can be directly
|
||||
painted to Draw. To create or change Image, use [^`:`:ImageBuffer^ ImageBuffer].&]
|
||||
[s2; Image has low`-cost constant time deep copy. It is moveable
|
||||
and Rich`-Value compatible type.&]
|
||||
[s2; U`+`+ expects pixels to be in premultiplied alpha format.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`~`(`)const:%- [@(0.0.255) const]_[^`:`:RGBA^ RGBA]`*_[@0 operat
|
||||
or`~]()_[@(0.0.255) const]&]
|
||||
[s5;%- [@0 operator]_[@(0.0.255) const]_[^`:`:RGBA^ RGBA][@0 `*]()_[@(0.0.255) const]&]
|
||||
[s2; Returns a pointer to Image pixels.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`[`]`(int`)const:%- [@(0.0.255) const]_[^`:`:RGBA^ RGBA]`*_[@0 o
|
||||
perator`[`]]([@(0.0.255) int]_[@3 i])_[@(0.0.255) const]&]
|
||||
[s2; Returns a pointer to the first pixel in the line [%-*@3 i].&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetSize`(`)const:%- [^`:`:Size^ Size]_[@0 GetSize]()_[@(0.0.255) const]&]
|
||||
[s2; Returns the dimension of Image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetWidth`(`)const:%- [@(0.0.255) int]_[@0 GetWidth]()_[@(0.0.255) const]&]
|
||||
[s2; Same as GetSize().cx.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetHeight`(`)const:%- [@(0.0.255) int]_[@0 GetHeight]()_[@(0.0.255) cons
|
||||
t]&]
|
||||
[s2; Same as GetSize().cy.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetLength`(`)const:%- [@(0.0.255) int]_[@0 GetLength]()_[@(0.0.255) cons
|
||||
t]&]
|
||||
[s2; Number of pixels in Image `- GetWidth() `* GetHeight().&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetHotSpot`(`)const:%- [^`:`:Point^ Point]_[@0 GetHotSpot]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the reference point.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetDots`(`)const:%- [^`:`:Size^ Size]_[@0 GetDots]()_[@(0.0.255) const]&]
|
||||
[s2; Gets the physical size of Image. If physical size is not set,
|
||||
returns Size(0, 0).&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetKind`(`)const:%- [@(0.0.255) int]_[@0 GetKind]()_[@(0.0.255) const]&]
|
||||
[s2; Returns the kind of image. See [^`:`:ImageBuffer^ ImageBuffer]
|
||||
for detail.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetSerialId`(`)const:%- [^`:`:int64^ int64]_[@0 GetSerialId]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the unique, per application run, identifier of Image.
|
||||
All Images with the same serial id can be considered equal (this
|
||||
is useful for caching images).&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:IsSame`(const`:`:Image`&`)const:%- [@(0.0.255) bool]_[@0 IsSame]([@(0.0.255) c
|
||||
onst]_[^`:`:Image^ Image]`&_[@3 img])_[@(0.0.255) const]&]
|
||||
[s2; Same as GetSerialId() `=`= img.GetSerialId().&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`=`=`(const`:`:Image`&`)const:%- [@(0.0.255) bool]_[@0 operato
|
||||
r`=`=]([@(0.0.255) const]_[^`:`:Image^ Image]`&_[@3 img])_[@(0.0.255) const]&]
|
||||
[s5;K:`:`:Image`:`:operator`=`=`(const`:`:Image`&`)const:%- [@(0.0.255) bool]_[@0 operato
|
||||
r!`=]([@(0.0.255) const]_[^`:`:Image^ Image]`&_[@3 img])_[@(0.0.255) const]&]
|
||||
[s2; Tests whether two Images are equal (or not equal). Dimensions,
|
||||
hot`-spot, dots and all pixels are compared. Note that the comparison
|
||||
can be slow.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:GetHashValue`(`)const:%- [^`:`:dword^ dword]_[@0 GetHashValue]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the hash`-value for image. All pixels combined into
|
||||
hash value (potentially slow).&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:ToString`(`)const:%- [^`:`:String^ String]_[@0 ToString]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the basic Image informations as String.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:Serialize`(`:`:Stream`&`):%- [@(0.0.255) void]_[@0 Serialize]([^`:`:Stream^ S
|
||||
tream]`&_[@3 s])&]
|
||||
[s2; Serializes Image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:Clear`(`):%- [@(0.0.255) void]_[@0 Clear]()&]
|
||||
[s2; Assigns an empty Image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`=`(const`:`:Image`&`):%- [^`:`:Image^ Image]`&_[@0 operator`=
|
||||
]([@(0.0.255) const]_[^`:`:Image^ Image]`&_[@3 img])&]
|
||||
[s2; Assigns another Image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`=`(`:`:ImageBuffer`&`):%- [^`:`:Image^ Image]`&_[@0 operator`=
|
||||
]([^`:`:ImageBuffer^ ImageBuffer]`&_[@3 img])&]
|
||||
[s2; Assigns Image created in ImageBuffer. ImageBuffer is emptied
|
||||
by this operation.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:IsNullInstance`(`)const:%- [@(0.0.255) bool]_[@0 IsNullInstance]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Test whether Image has nonzero dimension.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:IsEmpty`(`)const:%- [@(0.0.255) bool]_[@0 IsEmpty]()_[@(0.0.255) const]&]
|
||||
[s2; Same as IsNullInstance.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:operator`:`:Value`(`)const:%- [@0 operator_][^`:`:Value^@0 Value]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Converts Image to Value.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`:`:Image`(`):%- [@0 Image]()&]
|
||||
[s5;%- [@0 Image]([@(0.0.255) const]_[^`:`:Nuller^ Nuller]`&)&]
|
||||
[s2; Constructs empty Image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`:`:Image`(const`:`:Value`&`):%- [@0 Image]([@(0.0.255) const]_[^`:`:Value^ V
|
||||
alue]`&_[@3 src])&]
|
||||
[s2; Converts Image from Value.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`:`:Image`(const`:`:Image`&`):%- [@0 Image]([@(0.0.255) const]_[@0 Image
|
||||
]`&_[@3 img])&]
|
||||
[s2; Copy constructor.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`:`:Image`(`:`:Image`(`*`)`(`)`):%- [@0 Image]([@0 Image]_(`*[@3 fn])())
|
||||
&]
|
||||
[s2; This function allow Image to be directly constructed from pointer
|
||||
to function returning the Image. This allows omitting parenthesis
|
||||
when passing Iml image constants as arguments.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`:`:Image`(`:`:ImageBuffer`&`):%- [@0 Image]([^`:`:ImageBuffer^ ImageB
|
||||
uffer]`&_[@3 b])&]
|
||||
[s2; Uses Image created in ImageBuffer. ImageBuffer is emptied by
|
||||
this operation.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:Image`:`:`~`:`:Image`(`):%- `~[@0 Image]()&]
|
||||
[s2; Destructor.&]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0; [3 Standard cursors]&]
|
||||
[s0; &]
|
||||
[s0; Image class contains several standard mouse cursor Images as
|
||||
static member methods:&]
|
||||
[s0;^`:`:Image^ &]
|
||||
[ {{3333:3333:3334f0;g0; [ {{6850:3150>274; [s0;%- Arrow]
|
||||
:: [s0; ]
|
||||
:: [s0;%- Wait]
|
||||
:: [s0; ]
|
||||
:: [s0;%- IBeam]
|
||||
:: [s0; ]
|
||||
:: [s0;%- No]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeAll]
|
||||
:: [s0; ]}}]
|
||||
:: [ {{7129:2871>274; [s0;%- SizeHorz]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeVert]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeTopLeft]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeTop]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeTopRight]
|
||||
:: [s0; ]}}]
|
||||
:: [ {{6956:3044>274; [s0;%- SizeLeft]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeRight]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeBottomLeft]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeBottom]
|
||||
:: [s0; ]
|
||||
:: [s0;%- SizeBottomRight]
|
||||
:: [s0; ]}}]}}&]
|
||||
[s0;^`:`:Image^ &]
|
||||
[s0;^`:`:Image^ &]
|
||||
[s0; &]
|
||||
[s1;K:`:`:ImageBuffer`:`:class:%- [@(0.0.255) class]_[@0 ImageBuffer]_:_[@(0.0.255) private]_
|
||||
[^`:`:NoCopy^ NoCopy]&]
|
||||
[s2; ImageBuffer represents a writable Image `- an array of RGBA
|
||||
pixels. ImageBuffer can be converted to Image in low`-const constant
|
||||
time while loosing its content and vice versa, Image can be converted
|
||||
to ImageBuffer again loosing its content.&]
|
||||
[s2; &]
|
||||
[s2; Content of Image / ImageBuffer can be classified to optimize
|
||||
drawing. Possible classifications are&]
|
||||
[s2; &]
|
||||
[ {{2913:7087<288;>640; [s0; [* IMAGE`_UNKNOWN]]
|
||||
:: [s0; The image kind is unknown.]
|
||||
:: [s0; [* IMAGE`_EMPTY]]
|
||||
:: [s0; The image is empty (all alpha values are 0).]
|
||||
:: [s0; [* IMAGE`_ALPHA]]
|
||||
:: [s0; The image has alpha values different from 255 and 0.]
|
||||
:: [s0; [* IMAGE`_MASK]]
|
||||
:: [s0; The image has alpha values 0 or 255 only.]
|
||||
:: [s0; [* IMAGE`_OPAQUE]]
|
||||
:: [s0; The image has all alpha values 255.]}}&]
|
||||
[s2; &]
|
||||
[s2; Note that is the kind of image is unknown, painting routine
|
||||
determines it automatically by scanning pixels and stores the
|
||||
result.&]
|
||||
[s2; &]
|
||||
[s2; Pixels of image are organized in simple continual POD array,
|
||||
first pixel being top`-left.&]
|
||||
[s2; &]
|
||||
[s2; U`+`+ expects pixels to be in premultiplied alpha format.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:SetKind`(int`):%- [@(0.0.255) void]_[@0 SetKind]([@(0.0.255) int]_
|
||||
[@3 k])&]
|
||||
[s2; Sets the kind of image. You can use this to avoid automatic
|
||||
detection.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetKind`(`)const:%- [@(0.0.255) int]_[@0 GetKind]()_[@(0.0.255) co
|
||||
nst]&]
|
||||
[s2; Returns the kind of image set by SetKind.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:ScanKind`(`)const:%- [@(0.0.255) int]_[@0 ScanKind]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Scans all RGBA pixels to determine Image kind.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetScanKind`(`)const:%- [@(0.0.255) int]_[@0 GetScanKind]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; If kind set by SetKind is other than IMAGE`_UNKNOWN, returns
|
||||
it, otherwise calls ScanKind().&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:SetHotSpot`(`:`:Point`):%- [@(0.0.255) void]_[@0 SetHotSpot]([^`:`:Point^ P
|
||||
oint]_[@3 p])&]
|
||||
[s2; Sets the reference point. This point is e.g. used as hot`-spot
|
||||
when Image is used as mouse pointer.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetHotSpot`(`)const:%- [^`:`:Point^ Point]_[@0 GetHotSpot]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the reference point.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:SetDots`(`:`:Size`):%- [@(0.0.255) void]_[@0 SetDots]([^`:`:Size^ S
|
||||
ize]_[@3 sz])&]
|
||||
[s2; Sets the optional physical size in dots.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetDots`(`)const:%- [^`:`:Size^ Size]_[@0 GetDots]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the optional physical size. Default value is Size(0,
|
||||
0).&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetSize`(`)const:%- [^`:`:Size^ Size]_[@0 GetSize]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the dimensions of image.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetWidth`(`)const:%- [@(0.0.255) int]_[@0 GetWidth]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Same as GetSize().cx.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetHeight`(`)const:%- [@(0.0.255) int]_[@0 GetHeight]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Same as GetSize().cy.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:GetLength`(`)const:%- [@(0.0.255) int]_[@0 GetLength]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Returns the number of pixels in the image. Same as GetSize().cx
|
||||
`* GetSize().cy.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`[`]`(int`):%- [^`:`:RGBA^ RGBA]_`*[@0 operator`[`]]([@(0.0.255) i
|
||||
nt]_[@3 i])&]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`[`]`(int`)const:%- [@(0.0.255) const]_[^`:`:RGBA^ RGBA]_
|
||||
`*[@0 operator`[`]]([@(0.0.255) int]_[@3 i])_[@(0.0.255) const]&]
|
||||
[s2; Returns a pointer to the first pixel in the line [%-*@3 i].&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`~`(`):%- [^`:`:RGBA^ RGBA]_`*[@0 operator`~]()&]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`:`:RGBA`*`(`):%- [@0 operator_RGBA]`*()&]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`~`(`)const:%- [@(0.0.255) const]_[^`:`:RGBA^ RGBA]_[@0 `*
|
||||
operator`~]()_[@(0.0.255) const]&]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator const`:`:RGBA`*`(`)const:%- [@0 operator]_[@(0.0.255) c
|
||||
onst]_[@0 RGBA`*]()_[@(0.0.255) const]&]
|
||||
[s2; Returns a pointer to the first pixel of the image. &]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:Create`(int`,int`):%- [@(0.0.255) void]_[@0 Create]([@(0.0.255) in
|
||||
t]_[@3 cx], [@(0.0.255) int]_[@3 cy])&]
|
||||
[s5;K:`:`:ImageBuffer`:`:Create`(`:`:Size`):%- [@(0.0.255) void]_[@0 Create]([^`:`:Size^ Si
|
||||
ze]_[@3 sz])&]
|
||||
[s2; Creates a new image of specified size. Value of pixels is undefined.
|
||||
Previous content of ImageBuffer is lost.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:IsEmpty`(`)const:%- [@(0.0.255) bool]_[@0 IsEmpty]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2; Same as GetLength() `=`= 0.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:Clear`(`):%- [@(0.0.255) void]_[@0 Clear]()&]
|
||||
[s2; Clears the content, removing all pixels and setting the size
|
||||
of Image to Size(0, 0).&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`=`(`:`:Image`&`):%- [@(0.0.255) void]_[@0 operator`=]([^`:`:Image^ I
|
||||
mage]`&_[@3 img])&]
|
||||
[s5;K:`:`:ImageBuffer`:`:operator`=`(`:`:ImageBuffer`&`):%- [@(0.0.255) void]_[@0 operato
|
||||
r`=]([^`:`:ImageBuffer^ ImageBuffer]`&_[@3 img])&]
|
||||
[s2; Assigns pixels of [%-*@3 img] to ImageBuffer. [%-*@3 img] is cleared
|
||||
and empty after this operation, price paid for low`-cost constant
|
||||
time operation.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(`):%- [@0 ImageBuffer]()&]
|
||||
[s2; Constructs empty ImageBuffer.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(int`,int`):%- [@0 ImageBuffer]([@(0.0.255) int]_
|
||||
[@3 cx], [@(0.0.255) int]_[@3 cy])&]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(`:`:Size`):%- [@0 ImageBuffer]([^`:`:Size^ Size
|
||||
]_[@3 sz])&]
|
||||
[s2; Constructs ImageBuffer of specified size. Value of pixels is
|
||||
undefined.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(`:`:Image`&`):%- [@0 ImageBuffer]([^`:`:Image^ I
|
||||
mage]`&_[@3 img])&]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(`:`:ImageBuffer`&`):%- [@0 ImageBuffer]([@0 Ima
|
||||
geBuffer]`&_[@3 img])&]
|
||||
[s2; Assigns pixels of [%-*@3 img] to ImageBuffer. [%-*@3 img] is cleared
|
||||
and empty after this operation, price paid for low`-cost constant
|
||||
time operation.&]
|
||||
[s0; &]
|
||||
[s5;K:`:`:ImageBuffer`:`:`:`:ImageBuffer`(`:`:ImageDraw`&`):%- [@0 ImageBuffer]([^`:`:ImageDraw^ I
|
||||
mageDraw]`&_[@3 w])&]
|
||||
[s2; Creates ImageBuffer from ImageDraw. ImageDraw is cleared and
|
||||
empty after this operation, price paid for low`-cost constant
|
||||
time operation.&]
|
||||
[s2; &]
|
||||
[s0; &]
|
||||
[s0; ]
|
||||
7
archive/olddraw/Draw/src.tpp/Iml$en-us.tpp
Normal file
7
archive/olddraw/Draw/src.tpp/Iml$en-us.tpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TITLE("Iml and image list class methods")
|
||||
COMPRESSED
|
||||
120,156,181,86,109,111,155,72,16,254,43,35,165,141,32,231,160,221,5,12,134,47,145,122,47,138,42,93,165,186,247,9,145,122,131,215,246,94,49,228,96,237,180,58,93,126,251,13,11,216,198,6,167,201,245,18,41,235,236,238,60,243,60,51,179,51,142,24,188,121,67,70,228,130,60,243,19,252,44,22,124,147,170,56,146,142,227,135,156,185,225,151,247,31,38,225,213,141,49,118,204,10,133,34,138,237,81,219,119,109,234,176,49,254,161,54,101,46,179,29,234,179,137,227,219,182,79,130,36,229,101,25,71,41,243,253,176,50,98,35,118,193,60,151,81,207,241,29,159,218,158,207,208,150,17,194,136,199,92,234,216,62,115,131,185,40,147,56,226,190,29,94,125,28,163,145,93,121,66,112,66,199,204,241,28,70,108,194,28,116,69,125,223,161,158,235,219,147,241,56,72,248,131,146,121,214,248,146,148,50,26,222,83,47,68,206,79,79,79,22,117,72,205,192,65,48,74,28,164,74,113,143,56,204,163,238,132,76,92,159,250,196,70,112,215,35,110,240,192,11,190,30,150,238,62,43,
|
||||
221,35,129,84,2,33,174,126,162,212,67,147,241,104,124,65,29,15,133,250,182,227,250,30,65,231,140,49,219,102,212,102,147,9,115,199,174,23,172,4,159,139,34,142,254,254,252,207,219,95,126,191,254,99,10,81,105,135,112,187,78,129,103,115,144,107,190,20,144,202,82,129,142,43,172,133,90,229,243,242,50,142,74,18,66,181,208,240,125,48,195,95,52,169,22,125,45,184,33,16,189,37,228,154,144,27,131,88,196,98,174,107,66,147,153,118,31,149,193,231,246,223,202,99,92,193,177,16,166,50,91,166,2,150,105,126,207,83,144,89,169,120,150,8,200,23,154,86,205,67,150,128,75,158,72,174,196,28,30,165,90,129,224,201,234,148,240,227,74,226,118,33,30,10,81,138,76,149,144,228,153,194,15,21,156,37,17,111,33,209,23,230,95,46,51,68,186,255,214,64,52,59,133,5,239,52,206,67,145,111,37,110,2,47,10,254,109,118,157,202,47,2,120,146,8,60,83,57,168,85,227,85,179,68,128,210,130,79,57,94,248,107,35,11,161,137,239,132,44,242,2,48,221,74,38,155,
|
||||
148,23,39,148,71,144,240,20,175,35,215,189,222,58,238,214,65,220,221,110,220,63,162,60,53,51,102,102,208,19,249,109,46,231,187,72,239,98,142,73,210,86,187,19,195,108,83,160,247,203,211,104,54,74,219,24,238,194,38,179,90,245,62,108,195,76,127,19,234,93,190,201,52,89,4,42,85,112,192,180,165,34,51,53,80,41,200,186,69,232,222,48,204,125,53,105,220,189,24,181,41,178,82,51,207,54,235,123,81,236,179,84,49,111,115,119,158,243,237,124,102,32,171,131,0,223,85,39,83,85,96,185,222,65,189,246,6,89,27,239,131,28,159,230,231,64,237,129,165,13,114,183,107,246,137,193,122,204,148,92,200,3,65,192,85,75,239,170,3,96,197,103,213,245,106,211,136,119,53,240,144,178,255,67,87,191,146,51,233,249,85,102,152,29,157,244,125,78,102,151,175,173,175,10,238,168,182,142,42,171,223,244,176,32,234,163,110,85,212,123,179,203,78,40,142,60,13,21,113,197,169,142,206,67,94,202,106,238,236,115,174,219,223,82,110,69,214,137,216,60,182,118,97,205,196,146,
|
||||
43,188,1,91,158,110,176,114,22,144,229,10,59,209,38,59,215,84,166,109,97,140,118,177,213,30,171,208,190,168,207,76,255,115,161,140,160,199,172,147,140,163,60,244,22,239,81,236,215,203,211,66,252,176,21,197,99,129,163,244,92,45,246,190,170,102,25,135,141,209,217,177,137,203,167,21,118,217,238,5,156,46,85,15,93,200,166,169,234,153,118,140,22,116,18,6,56,85,112,148,192,44,8,162,70,120,122,167,199,233,236,18,162,155,122,178,26,102,216,121,103,56,16,23,162,16,213,52,194,150,94,141,153,252,254,79,145,40,61,155,234,74,58,238,253,86,175,215,232,40,137,218,163,126,63,70,116,146,40,136,250,90,166,166,169,203,213,124,61,54,36,43,94,196,48,187,58,132,170,190,75,240,53,102,79,79,82,195,180,42,99,35,106,30,135,249,2,69,187,137,99,244,3,183,231,198,16,104,159,240,22,249,246,72,80,227,181,170,179,65,111,183,173,142,65,25,167,143,160,245,247,114,111,63,202,215,112,170,94,11,246,125,53,213,171,169,91,12,166,117,216,76,11,161,191,183,
|
||||
205,161,57,135,120,189,65,230,226,107,245,28,228,225,227,120,190,136,116,83,212,18,166,103,98,63,130,65,109,157,88,52,202,214,3,194,166,251,100,141,106,242,235,239,41,244,51,28,79,115,86,254,112,178,229,43,201,214,95,95,7,222,164,62,180,154,163,248,95,62,13,49,222,
|
||||
160
archive/olddraw/Draw/srcdoc.tpp/DrawOutput$en-us.tpp
Normal file
160
archive/olddraw/Draw/srcdoc.tpp/DrawOutput$en-us.tpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
topic "Draw";
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[l288;i704;a17;O9;~~~.992;2 $$1,0#10431211400427159095818037425705:param]
|
||||
[a83;*R6 $$2,5#31310162474203024125188417583966:caption]
|
||||
[b83;*2 $$3,5#07864147445237544204411237157677:title]
|
||||
[b167;a42;C2 $$4,6#40027414424643823182269349404212:item]
|
||||
[b42;a42;2 $$5,5#45413000475342174754091244180557:text]
|
||||
[l288;a17;2 $$6,6#27521748481378242620020725143825:desc]
|
||||
[l321;t246;C@5;1 $$7,7#20902679421464641399138805415013:code]
|
||||
[b2503;2 $$8,0#65142375456100023862071332075487:separator]
|
||||
[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base]
|
||||
[t4167;C2 $$10,0#37138531426314131251341829483380:class]
|
||||
[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement]
|
||||
[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam]
|
||||
[b167;C2 $$13,13#92430459443460461911108080531343:item1]
|
||||
[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2]
|
||||
[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate]
|
||||
[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result]
|
||||
[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line]
|
||||
[l160;t4167;*C+117 $$18,5#88603949442205825958800053222425:package`-title]
|
||||
[{_}%EN-US
|
||||
[s2; Draw&]
|
||||
[s0; This article tries to describe view of the Draw object`'s role
|
||||
in the painting process.&]
|
||||
[s0; &]
|
||||
[s0; Please remember: Draw is not the raster image itself, much the
|
||||
less encoded in a particular image format. I believe you would
|
||||
do best to think about Draw as a channel or a toolbox interfacing
|
||||
the painting routine (a part of the program which wants to paint
|
||||
something; for the time being let`'s ignore the distinction between
|
||||
drawing vectors and rasters) to the actual `"canvas`" being painted
|
||||
onto. The main role of Draw is exactly to turn your logical drawing
|
||||
commands (e.g. `"draw a line`", `"draw a bit of text`", `"draw
|
||||
a raster image`" etc.) into something the output `"device`" can
|
||||
understand.&]
|
||||
[s0; &]
|
||||
[s0; Now, this is the general story. In reality there are basically
|
||||
two families of Draw`-related objects sharing many common traits.
|
||||
These are:&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; raster`-oriented Draw objects: these normally include
|
||||
the Draw object in the Ctrl`::Paint override, the ViewDraw, the
|
||||
BackDraw, the ImageDraw `& ImageMaskDraw and sometimes PrintDraw.&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; vector`-oriented Draw objects: DrawingDraw, WinMetaFileDraw
|
||||
and sometimes PrintDraw, and also (normally) PageDraw, PdfDraw
|
||||
and Report.&]
|
||||
[s0; &]
|
||||
[s0; Although some might prefer to explain the characteristics of
|
||||
the above objects in abstract terms (with multiple references
|
||||
to `"you don`'t need to know this and that`" :`-) ), I choose
|
||||
to be honest with you as to how they really work, because I believe
|
||||
that`'ll move you the farthest along the way.&]
|
||||
[s0; &]
|
||||
[s0; Actually the Draw is something like a semi`-intelligent painter
|
||||
with a plentiful palette of logical drawing objects; some of
|
||||
these are by nature vector`-oriented, like lines, rectangles,
|
||||
polygons etc., some are naturally rasterized, typically Images,
|
||||
some are a bit of both, especially text objects.&]
|
||||
[s0; &]
|
||||
[s0; Now, when the Draw receives a command to draw something (in
|
||||
U`+`+ terminology, a drawing operation, see the host of xxxOp
|
||||
methods in the declaration of Draw), the painter for the desired
|
||||
output device has to decide what to do with it. Typically, when
|
||||
the object is of the same type as the output medium (both are
|
||||
vector or raster), not much work has to be done. When the source
|
||||
(the drawing operation) is vector`-oriented and the output device
|
||||
is raster`-based, the vector object has to be rasterized.&]
|
||||
[s0; &]
|
||||
[s0; Typical raster`-based Draw objects are related to painting into
|
||||
windows and images; the Draw passed to Ctrl`::Paint by the U`+`+
|
||||
windowing mechanism is such a case, as well as ViewDraw, BackDraw
|
||||
or ImageDraw and ImageMaskDraw. All these drawing objects use
|
||||
the MS Windows or X Windows mechanism called GDI to channel the
|
||||
drawing objects to the built`-in rasterizer which (perhaps using
|
||||
some graphic card accelerator in certain cases) ends up by modifying
|
||||
the desired pixels on the target device (the Ctrl area or the
|
||||
Image).&]
|
||||
[s0; &]
|
||||
[s0; By calling the other Draw classes `"vector`-based`" I don`'t
|
||||
mean they cannot cope with raster data. I am perhaps a little
|
||||
abusing the standard notion of the word to emphasize the fact
|
||||
that the latter group can manipulate vector objects directly,
|
||||
without rasterizing them first. So, for instance, DrawingDraw
|
||||
and WinMetaFileDraw are used to generate a serialized representation
|
||||
of the executed sequence of drawing operations, which can be
|
||||
later `"played back`" thus reproducing the original drawing.&]
|
||||
[s0; &]
|
||||
[s0; Notice that in the above cases there is no actual `"canvas`"
|
||||
to be painted onto. Both DrawingDraw and WinMetaFileDraw merely
|
||||
maintain a data stream which is used to record the individual
|
||||
drawing operations (coming into Draw via the xxxOp member functions)
|
||||
without actually caring about what is being drawn very much.
|
||||
This is also the reason why you cannot read rasterized data from
|
||||
such types of Draw: if you call DrawToImage, for instance, for
|
||||
a DrawingDraw, it is sure to fail. But then, even if you call
|
||||
DrawToImage for a ViewDraw, you cannot always count on getting
|
||||
the correct image, because in situations when a portion of the
|
||||
window is obscured by another application, you`'ll get a snapshot
|
||||
of this other application and not your window.&]
|
||||
[s0; &]
|
||||
[s0; The main advantage of DrawingDraw compared with ImageDraw (if
|
||||
we choose to see these two classes as two different means for
|
||||
creating a drawing which can be stored afterwards, perhaps to
|
||||
a file or a program cache) is that it can later (upon play`-back)
|
||||
reproduce the original vector operations (like lines or polygons)
|
||||
exactly even when size of `"painting`" is rescaled, without blocky
|
||||
artifacts inevitable in rasters.&]
|
||||
[s0; &]
|
||||
[s0; To sum the above into a few practical guidelines, please try
|
||||
to remember the following:&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; To create a recording of an image, use DrawingDraw or
|
||||
ImageDraw (see the above distinction between these two). E.g.&]
|
||||
[s0; &]
|
||||
[s7; DrawingDraw ddraw(100, 100);&]
|
||||
[s7; myobject.Paint(ddraw);&]
|
||||
[s7; Drawing dwg `= ddraw.GetResult(); // dwg is the output recording&]
|
||||
[s7; &]
|
||||
[s7; Image img(100, 100);&]
|
||||
[s7; ImageDraw idraw(img);&]
|
||||
[s7; myobject.Paint(idraw);&]
|
||||
[s7; idraw.Close();&]
|
||||
[s7; // now the Image has been modified by the myobject`'s drawing&]
|
||||
[s7; operations and can be e.g. saved to disk&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; When using DrawToImage, you should take care of the
|
||||
above limitations. In particular, it is not always wise to use
|
||||
DrawToImage on a Draw which is not entirely under your control.
|
||||
To make the long story short, you`'re all right with ImageDraw
|
||||
and perhaps with BackDraw, but scarcely with anything else, becauses
|
||||
in most cases you cannot be sure what you`'ll get (e.g. with
|
||||
ViewDraw or PrintDraw). In certain cases you can be sure you`'ll
|
||||
get nothing at all (e.g. with DrawingDraw).&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; As concerns the difference between an Image and an AlphaArray,
|
||||
logically there`'s none (both represent masked raster images).
|
||||
Physically there is a lot of difference (you can view this difference
|
||||
as more or less optimization`-related), because the AlphaArray
|
||||
is a physical matrix of pixels maintained directly by the application,
|
||||
whereas an Image is (at least sometimes) a logical bitmap object
|
||||
maintained by the Windows system (this is especially important
|
||||
in X Windows, because the AlphaArray is stored on the client,
|
||||
whereas Images are stored in the X Server). Another difference
|
||||
is that you can create an AlphaArray in any pixel format you
|
||||
want, but the supported pixel formats of Images are (or can be)
|
||||
limited by the properties of your windowing system.&]
|
||||
[s0; &]
|
||||
[s0;i150;O2; As concerns image storage in the various standard formats
|
||||
(like jpg, png or gif), again these formats belong neither to
|
||||
the Draw object, nor to the Image object. It`'s best to see the
|
||||
ImageEncoder`'s as mere data processors which receive a raster
|
||||
input (an AlphaArray or an Image) and produce an encoded linearized
|
||||
image as their output (this is obviously the encoding phase corresponding
|
||||
to the Save`-routines; with the Load`-routines, the situation
|
||||
is vice versa). Therefore, as soon as you have an Image (or an
|
||||
AlphaArray), you can Save it in any format you like. Similarly,
|
||||
you can take an image file in one of the standard formats and
|
||||
read it into an AlphaArray or an Image.&]
|
||||
[s0; ]
|
||||
965
archive/olddraw/Draw/srcdoc.tpp/DrawTutorial$en-us.tpp
Normal file
965
archive/olddraw/Draw/srcdoc.tpp/DrawTutorial$en-us.tpp
Normal file
|
|
@ -0,0 +1,965 @@
|
|||
topic "Draw tutorial";
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[l288;i1120;a17;O9;~~~.1408;2 $$1,0#10431211400427159095818037425705:param]
|
||||
[a83;*R6 $$2,5#31310162474203024125188417583966:caption]
|
||||
[b83;*4 $$3,5#07864147445237544204411237157677:title]
|
||||
[i288;O9;C2 $$4,6#40027414424643823182269349404212:item]
|
||||
[b42;a42;2 $$5,5#45413000475342174754091244180557:text]
|
||||
[l288;b17;a17;2 $$6,6#27521748481378242620020725143825:desc]
|
||||
[l321;t246;C@5;1 $$7,7#20902679421464641399138805415013:code]
|
||||
[b2503;2 $$8,0#65142375456100023862071332075487:separator]
|
||||
[*@(0.0.255)2 $$9,0#83433469410354161042741608181528:base]
|
||||
[t4167;C2 $$10,0#37138531426314131251341829483380:class]
|
||||
[l288;a17;*1 $$11,11#70004532496200323422659154056402:requirement]
|
||||
[i417;b42;a42;O9;~~~.416;2 $$12,12#10566046415157235020018451313112:tparam]
|
||||
[b167;C2 $$13,13#92430459443460461911108080531343:item1]
|
||||
[i288;a42;O9;C2 $$14,14#77422149456609303542238260500223:item2]
|
||||
[*@2$(0.128.128)2 $$15,15#34511555403152284025741354420178:NewsDate]
|
||||
[l321;*C$7;2 $$16,16#03451589433145915344929335295360:result]
|
||||
[l321;b83;a83;*C$7;2 $$17,17#07531550463529505371228428965313:result`-line]
|
||||
[l160;t4167;*C+117 $$18,5#88603949442205825958800053222425:package`-title]
|
||||
[2 $$19,0#53580023442335529039900623488521:gap]
|
||||
[t4167;C2 $$20,20#70211524482531209251820423858195:class`-nested]
|
||||
[b50;2 $$21,21#03324558446220344731010354752573:Par]
|
||||
[i448;a25;kKO9;*@(64)2 $$22,0#37138531426314131252341829483370:item]
|
||||
[{_}%EN-US
|
||||
[s2; Draw tutorial&]
|
||||
[s3; 1. Basic drawing operations&]
|
||||
[s5; Draw class is base class representing graphical output. It is
|
||||
intentionally designed with quite limited set of easy to use
|
||||
drawing primitives. Unlike most of other similar classes in competing
|
||||
toolkits, U`+`+ drawing operations are [*/ stateless] `- there
|
||||
is no separate setup of e.g. line width, pen color etc, all necessary
|
||||
painting attributes are parameters of respective methods.&]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; struct MyApp : TopWindow `{&]
|
||||
[s7; -|virtual void Paint(Draw`& w) `{&]
|
||||
[s7; -|-|w.[* DrawRect](GetSize(), White());&]
|
||||
[s7; &]
|
||||
[s7; -|-|w.[* DrawRect](10, 10, 60, 80, Green());&]
|
||||
[s7; &]
|
||||
[s7; -|-|w.[* DrawLine](100, 10, 160, 80, 0, Black());&]
|
||||
[s7; -|-|w.[* DrawLine](160, 10, 100, 80, 4, Red());&]
|
||||
[s7; -|-|w.[* DrawLine](160, 40, 100, 50, PEN`_DOT, Red());&]
|
||||
[s7; &]
|
||||
[s7; -|-|w.[* DrawEllipse](210, 20, 80, 60, Blue());&]
|
||||
[s7; &]
|
||||
[s7; -|-|w.[* DrawEllipse](310, 20, 80, 60, LtBlue(), 5, Red());&]
|
||||
[s7; &]
|
||||
[s7; -|-|w.[* DrawArc](RectC(410, 20, 80, 60), Point(10, 10), Point(450,
|
||||
80), 3, Cyan);&]
|
||||
[s7; -|-|&]
|
||||
[s7; -|-|Vector<Point> p;&]
|
||||
[s7; -|-|p << Point(30, 110) << Point(60, 180) << Point(10, 150) <<
|
||||
Point(70, 150);&]
|
||||
[s7; -|-|w.[* DrawPolyline](p, 4, Black);&]
|
||||
[s7; &]
|
||||
[s7; -|-|p.Clear();&]
|
||||
[s7; -|-|p << Point(130, 110) << Point(160, 180) << Point(110, 150)
|
||||
<< Point(170, 120)&]
|
||||
[s7; -|-| << Point(130, 110);&]
|
||||
[s7; -|-|w.[* DrawPolygon](p, Blue);&]
|
||||
[s7; &]
|
||||
[s7; -|-|p.Clear();&]
|
||||
[s7; -|-|p << Point(230, 110) << Point(260, 180) << Point(210, 150)
|
||||
<< Point(270, 120)&]
|
||||
[s7; -|-| << Point(230, 110);&]
|
||||
[s7; -|-|w.[* DrawPolygon](p, Cyan, 5, Magenta);&]
|
||||
[s7; &]
|
||||
[s7; -|-|p.Clear();&]
|
||||
[s7; -|-|p << Point(330, 110) << Point(360, 180) << Point(310, 150)
|
||||
<< Point(370, 120)&]
|
||||
[s7; -|-| << Point(330, 110);&]
|
||||
[s7; -|-|w.[* DrawPolygon](p, Cyan, 5, Magenta, INT64(0xaa55aa55aa55aa55));&]
|
||||
[s7; -|-|&]
|
||||
[s7; -|-|w.[* DrawImage](40, 240, CtrlImg`::save());&]
|
||||
[s7; -|-|w.[* DrawImage](110, 210, 80, 80, CtrlImg`::save());&]
|
||||
[s7; -|-|w.[* DrawImage](240, 240, CtrlImg`::save(), Blue);&]
|
||||
[s7; -|-|w.[* DrawImage](310, 210, 80, 80, CtrlImg`::save(), Blue);&]
|
||||
[s7; -|-|&]
|
||||
[s7; -|-|w.[* DrawText](20, 330, `"Hello world!`");&]
|
||||
[s7; -|-|w.[* DrawText](120, 330, `"Hello world!`", Arial(15).Bold());&]
|
||||
[s7; -|-|w.[* DrawText](220, 330, `"Hello world!`", Roman(15).Italic(),
|
||||
Red);&]
|
||||
[s7; -|-|w.[* DrawText](320, 380, 400, `"Hello world!`", Courier(15).Underline());&]
|
||||
[s7; -|`}&]
|
||||
[s7; `};&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyApp().Sizeable().Run();&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s0; &]
|
||||
[s0;=
|
||||
@@image:2420&2314
|
||||
妰鋪蟻€€€€€€€€€<EFBFBD>滍輯饻蹩澿窨蛡捎赌迕偼履<EFBFBD>亹垅苯髝蹜侌柿巴<EFBFBD>銠屓眲銠悶订雏<EFBFBD>瀑<EFBFBD>
|
||||
娈当┒穻ы蒇苈鍜頁嵢浲鲻斩铍蚋庾€譃邂欚糕媱<EFBFBD>ゃ愨嗳兌漕<EFBFBD><EFBFBD>樱穴户政秤<EFBFBD><EFBFBD><EFBFBD>蝴淃┻┠璐
|
||||
酚郁<EFBFBD>樱鲘娕稍挓烫埴劄蹴佑诬鳕紳絻昱箨Α椎多䴗鲔挶钓梯孕峨茰现屜戺嬏氭纽趨锄攽巨
|
||||
Ё珍и椈访吻<EFBFBD>咬<EFBFBD>ハ艨柈噘蛟莩鋵唼涅莻簌Φ窃鍑姷摳壘迕<EFBFBD>憾浸<EFBFBD>婏冫嬬嘻埋容彅珥<EFBFBD>
|
||||
消涒炉挥获惓楉ü╊晿釗蝻洂懗謴摝<EFBFBD>束<EFBFBD><EFBFBD>┈曼<EFBFBD>乌<EFBFBD>椅疄萼宇<EFBFBD>䴘蔚毞暇熽榉岄袔峡<EFBFBD>欅<EFBFBD>
|
||||
<EFBFBD><EFBFBD>甚炜愻茥<EFBFBD>咄晫畏徽棽茖娩眙涊畅<EFBFBD>饭钰褡丸弭呎<EFBFBD><EFBFBD>桄恫铥硝谈黪姜妍宓桠伃<EFBFBD><EFBFBD>昙⒅
|
||||
燃稠龐<EFBFBD>邌熁;<EFBFBD>航亢檗佐<EFBFBD>真紫谠嬙泾<EFBFBD>之圄狂<EFBFBD>妣诉脲果蛦驷殰轺<EFBFBD>炋懢羁Ψ啲顗輽鲎<EFBFBD>
|
||||
в卓<EFBFBD>汐钵<EFBFBD><EFBFBD>橼哼櫓巯<EFBFBD>薀茱尽<EFBFBD>秉升簵顺娓箪堰豺伫渌壘南嵡者朂<EFBFBD>鹉<EFBFBD>楛妮糗慕<EFBFBD>ㄛ擒<EFBFBD>
|
||||
黼饣泗黄旄哒浽欟槸睂娩艟<EFBFBD>軝坜橏扣遍穼轳妻纂烋驽仞<EFBFBD>勢亳<EFBFBD>碀凓Ν痘<EFBFBD>混季糌<EFBFBD>袊鷴
|
||||
姛┵喏陆<EFBFBD><EFBFBD>耒<EFBFBD>斋褳┫债<EFBFBD>飘掀摀庸摒孟濍<EFBFBD><EFBFBD>殗偵翆睂鎿翔旣仆嵅<EFBFBD>愕烇则遘鸽搽煿靲犋聩
|
||||
<EFBFBD><EFBFBD>Ⅴ减<EFBFBD>逑<EFBFBD>◇伋煹谳櫹珶澦魰軣笀氽低<EFBFBD><EFBFBD>牧槅岵繒鼤蝓偣笕浬藝稂蜥埒<EFBFBD><EFBFBD>扎駧広铧怏Н
|
||||
泉怔蘧<EFBFBD>蝮<EFBFBD>蒺ㄓ标齄敞彰邅<EFBFBD>艄<EFBFBD>媴蚁駮φ缀参缒五榾悚徎<EFBFBD>ひ睍<EFBFBD>鍧蛆舄趪<EFBFBD>琏徔磅筘<EFBFBD>
|
||||
抛曨吖蜃貌峄看糅驀嚲<EFBFBD>协計鯗莩认龖涍闾妺矅椵<EFBFBD>牦崯伛捱満潬箜勞眭腚亢暰硐笤<EFBFBD><EFBFBD><EFBFBD>伛
|
||||
沣樽<EFBFBD>碓关眚ヘ窛麤葛礓趴<EFBFBD><EFBFBD>坎屆垂е<EFBFBD>臋鐢<EFBFBD>懸<EFBFBD>苄垭勋溷忺砩<EFBFBD><EFBFBD>奎忔呒<EFBFBD>啉翅佅滬饨
|
||||
登咀出倩櫱倔<EFBFBD>э逎<EFBFBD>谘犀舢旌皲炍翅瀼彮混逐妩М癸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>仉瑰貂劭<EFBFBD>隧湱┺辕軡笏鞄麨
|
||||
≤秸抉遥忦紘鯐<EFBFBD>阱<EFBFBD>垑仓挮奶瑰咀巯犣獯<EFBFBD>洺<EFBFBD><EFBFBD><EFBFBD>澂⒔<EFBFBD><EFBFBD>瀵艔<EFBFBD><EFBFBD><EFBFBD>茛綮嫙燐芸翔煰坠<EFBFBD>
|
||||
他繇<EFBFBD><EFBFBD><EFBFBD>楄栒w疅<EFBFBD>腴星<EFBFBD>蟒酯嚠火稛摅昼暷<EFBFBD>杲赫秫嬿壷膪喏<EFBFBD>狘藟<EFBFBD>ㄑ<EFBFBD>庹<EFBFBD><EFBFBD><EFBFBD>拄拶<EFBFBD>
|
||||
犥综蠍冒讓砷殲旉斿菨┑<EFBFBD>幩樊舣烚赤鐝<EFBFBD>叝磔<EFBFBD>祗鲘龒贊<EFBFBD><EFBFBD><EFBFBD>岑箨陆穼<EFBFBD>茧哥绅溪跷賾鯒<EFBFBD>
|
||||
狠仇鹌鳛钾虹痒向鲒<EFBFBD>兾腑摼嘌谕皩缬栽铛徂垮强<EFBFBD><EFBFBD><EFBFBD>过櫇赀<EFBFBD>龔笊φ厪暖橆俣羟涞梅揆翩
|
||||
憛亲擢<EFBFBD><EFBFBD>狴<EFBFBD>况溴忌缰苘<EFBFBD><EFBFBD>溷嬒庮踣摸唾榀亨觞寜尴牖萎第<EFBFBD>酲传由貔鐔勯得ご萏<EFBFBD>骗粽<EFBFBD>
|
||||
<EFBFBD>邛聴稆歪索闀蹂偾际【鲨<EFBFBD>缩◤茗忿叔菛房戏<EFBFBD><EFBFBD>镰<EFBFBD>蟻柚胨墚<EFBFBD>歼崶馃毁疥<EFBFBD><EFBFBD>龝龇谏<EFBFBD>
|
||||
<EFBFBD>麡愲嗎潋兜劢件瘹毕醺Ь<EFBFBD><EFBFBD>锜<EFBFBD><EFBFBD><EFBFBD>东囶介岗<EFBFBD>壭栠<EFBFBD><EFBFBD>濗啛悔鷹往焐临潍<EFBFBD>鋰旟菹腾<EFBFBD>
|
||||
宰谳蘸毵<EFBFBD>谦扣恂鎺紊燒褲傭憋罐轿脎傻冒節殛织欒蹊拽謲<EFBFBD>鲧枫枦嬿苄噳笱祴<EFBFBD>方鞚菛礊
|
||||
促鳋噻粡<EFBFBD><EFBFBD>邆窏鲔<EFBFBD>昧<EFBFBD>始怃州詮嚪<EFBFBD>醑摘尳┳拗燋烚伣怖搦亴針η淤剌<EFBFBD>概鰝颤藝品<EFBFBD>
|
||||
嘅劂项╈<EFBFBD>津飱釓<EFBFBD>稆蜅‘各嶟浼K边耵匐鬅竟<EFBFBD>呻芜<EFBFBD>蓹摥鰲嘱簋砰祹<EFBFBD><EFBFBD>攫殹尧<EFBFBD>伫矫蕰<EFBFBD>
|
||||
赕<EFBFBD>芟兖鍔机螫最沧貘蛲ゅ醅熪寭ラ<EFBFBD>狎尰<EFBFBD>忑舍爿<EFBFBD>⒅嶎掭<EFBFBD><EFBFBD><EFBFBD>冉藵邎劫痦墓胝㈨毛畼铎
|
||||
笣搛勿搀購芸<EFBFBD>徬椶<EFBFBD>硿主€溨<EFBFBD><EFBFBD>洲谕膈蹰郄得夯滉蹼<EFBFBD>潬溞椶帡┮晔抱蝮筋ヵ丑鏋仰邩濁<EFBFBD>
|
||||
瞧<EFBFBD><EFBFBD>馄摅頊芨狺涴匹咞瞑嵻<EFBFBD>汨<EFBFBD>嫨鳟煿麢缋葺伫玲鶑鞈胂氋銮盅ョ锦臀<EFBFBD><EFBFBD>鵀坊瓈摁沫汈<EFBFBD>
|
||||
邶抻魏诜愈軆卫醌钭幏簲険晤<EFBFBD>椿逎<EFBFBD>峻找埴疥鍪莜螌涖脎<EFBFBD>欑<EFBFBD><EFBFBD>獚涰喖徕欘棛凑湍<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
妩擎廄舄藨忀<EFBFBD>莞器湃捷搲掇哚<EFBFBD><EFBFBD><EFBFBD>代渺盐<EFBFBD>棖蜌侯笾訜笺熸睚Ё兆尓K燋螨厌郄诊<EFBFBD>潍
|
||||
轷亢<EFBFBD>鎲褛轷榨輽镌暌鑻俗侃<EFBFBD>摉<EFBFBD><EFBFBD>敕曖槝И<EFBFBD>悍兯慰澈躲<EFBFBD>嚻活峻溷潛А铢噌龂炱餆<EFBFBD>惐
|
||||
櫸城棡濒ы閲<EFBFBD>喻于哓畹灲绾<EFBFBD>诏皾<EFBFBD>椢犯≈胂寤泼<EFBFBD><EFBFBD><EFBFBD>橚罪跚钣铪<EFBFBD><EFBFBD>軐呋胖撷黔<EFBFBD>槅捎<EFBFBD>
|
||||
禋时拙Ⅺ<EFBFBD>苷鐪辋<EFBFBD><EFBFBD>许煖摒メ蕱曲<EFBFBD>鲮涪鹎⒀[喵祉<EFBFBD>慨<EFBFBD><EFBFBD><EFBFBD>綖摁囘欫<EFBFBD>雨<EFBFBD><EFBFBD>徜熧王<EFBFBD>и
|
||||
徑む渶櫩猁褖貂ポ】┯涧萦踉プ稠<EFBFBD>唪<EFBFBD><EFBFBD>瘢<EFBFBD>疤螅铸憥懣畲<EFBFBD>分┹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>戾碁锖璺铓吅卓<EFBFBD>
|
||||
伏煗携框備龝w魯蝾眶糨<EFBFBD>斓髱<EFBFBD>Ь近<EFBFBD><EFBFBD>脶睆<EFBFBD>饵鶝烚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>殄<EFBFBD>胙<EFBFBD>魳夡洷弩犌彍繙圯<EFBFBD>
|
||||
傺撽蒌宇挴<EFBFBD>癞飨鞯橄芩翳芙腭<EFBFBD>枍垌鍐徕汍<EFBFBD>幛妾佭螵最砝囖哺卒<EFBFBD>飿黥℃吤牖嗩身樬昏<EFBFBD>
|
||||
總岬棇懿<EFBFBD>痼坭<EFBFBD>鼻罡鳜筇劢<EFBFBD>疥弴ê牺杲喻暨巴轷覘偎穗蓐<EFBFBD>鍦挚<EFBFBD><EFBFBD>フ禐捧<EFBFBD>緰鰫犟┓候
|
||||
<EFBFBD>犷櫂肭焊冒屔駰钲黯啸<EFBFBD>趴<EFBFBD>氊<EFBFBD><EFBFBD>乘<EFBFBD><EFBFBD>曪鼨荃蘖曮紗餃鼽崡酀俟玷霹喢濈幆襟<EFBFBD>莽忂俨
|
||||
酱<EFBFBD>啷<EFBFBD><EFBFBD><EFBFBD>顷熚渝拗还汁鱿鶃填禌腧<EFBFBD>墪鬄涋篦泛甲岎岜<EFBFBD>程破<EFBFBD>撾釤傀撎忂<EFBFBD>讼<EFBFBD>唏夥锟牿
|
||||
<EFBFBD>胂<EFBFBD><EFBFBD>韰臌<EFBFBD>鐡诪泖与鏌跟禍Н<EFBFBD>摕渭悌讼<EFBFBD>谗愦<EFBFBD>坚社鼾料癁懂鐜<EFBFBD>囄蹀谳跏ぶ<EFBFBD><EFBFBD>镜赫赕<EFBFBD>
|
||||
丑論开绌汌諌惱雄檫銓冒喦<EFBFBD><EFBFBD>蹭慰<EFBFBD>檵辖裣纵坐凸瓘撄耷邽麈锿<EFBFBD><EFBFBD>朔<EFBFBD>螅斌<EFBFBD><EFBFBD>忐辇唧摁潒埝
|
||||
箝⒎<EFBFBD><EFBFBD>孙坦寤棡郁谨碗<EFBFBD>竖魞鐬桓<EFBFBD><EFBFBD>慰<EFBFBD>偏<EFBFBD><EFBFBD>隹<EFBFBD><EFBFBD>由刨嗫查倗霆縼液摏頇鳑<EFBFBD>渔侨烕琏
|
||||
悩λ抽跗<EFBFBD>珏艙<EFBFBD>鎿雾瘲氪<EFBFBD><EFBFBD>涸<EFBFBD><EFBFBD>錈膜笳炛<EFBFBD><EFBFBD>潑驘髹欨吰壙ぺ搡吰聩童<EFBFBD>応雁快勨<EFBFBD>ц槱
|
||||
锴<EFBFBD>缣敱猖湴油氉節<EFBFBD>鹰燒<EFBFBD><EFBFBD>擂<EFBFBD><EFBFBD>暹福抠鶌背脉亢熢爪霔觊瘻<EFBFBD>钭<EFBFBD>ń葶榈撾羚ǒ<EFBFBD><EFBFBD><EFBFBD>谡
|
||||
<EFBFBD>炭跈蔬裘<EFBFBD><EFBFBD>院笞僖粐潳邹钫<EFBFBD><EFBFBD>麟<EFBFBD>陼愥槮鐨塘弃栩<EFBFBD><EFBFBD>镪拭污麾殚槦畔煍<EFBFBD>耱耨<EFBFBD>褵楟虣<EFBFBD>
|
||||
謴曔喣<EFBFBD>苔萱乐吖边轷┳曗聡廂呯<EFBFBD>蟑<EFBFBD>掐<EFBFBD><EFBFBD>债欋硩擅丐鴮缚泐蔺溔欫缂膑櫝铤裨崟凊炡亐
|
||||
瑜驱瑗佃礄蝶坳繇贝殌洧諃<EFBFBD>煭唨<EFBFBD>數€惹珌腊沮崁蜓軎€悘謨€<EFBFBD>春圍曭腔鰡€埅敝绔食浇撪
|
||||
<EFBFBD>陶舄鲓犴韥悤瓗扃乏<EFBFBD>灲棱<EFBFBD>€呐<EFBFBD>阚撯隅咂<EFBFBD>穲涝粗何潻羹劙毴迪<EFBFBD>缽珱贆覂颧▉大谳<EFBFBD>
|
||||
曝濤第澫圑敆谅嶄瀫瓗澊軗狸爟桴掍愉毿冑阔負ⅰ讋毻<EFBFBD>堽舨渐功阔撱纷驾⌒<EFBFBD>烅敦熐堆昴<EFBFBD>
|
||||
壥迪煩厼<EFBFBD>斗蕚<EFBFBD>怡稛喏嘘心匍迪棌甫彎蹧焾袤狭蹚铬翳跻岀氱鋈遍竾忢蕠赚幌嫩諒九璧伿
|
||||
<EFBFBD><EFBFBD>螫啽椼肾儹坫亸訜劣蝺蟹臌绀挱蓝脵咕篼訉傍噘<EFBFBD><EFBFBD><EFBFBD><EFBFBD>佳鉁<EFBFBD>喉飼敗<EFBFBD>屁剰吸渚戩熦ケ
|
||||
<EFBFBD>涥姴跬拂箼钲廾ォ莲鸵墲訖<EFBFBD>娯开溪砌螆惥叟丧恨枸曓祥阔嵱鋲湙辜<EFBFBD>笩系砌帺鷭呤摃ω
|
||||
烋翊<EFBFBD><EFBFBD>牵諌荫煋岡绘頍蓱撈町娰槽硶庁旎<EFBFBD><EFBFBD>陧瀶飿滋垩<EFBFBD><EFBFBD>皧壹饿循嵅<EFBFBD>炶埮兜喵洌罩<EFBFBD><EFBFBD>
|
||||
<EFBFBD>軡琏彙逗屈<EFBFBD>旦壑颂疀谦绊淹煋购懵頍缻嵣糨敻呏冘<EFBFBD>蓖罘礌嫡柀<EFBFBD>绍逎埚彏ζ┨畩硷霛
|
||||
讦妆⒄雯鐔幧軡伥枏潶ч輸骧<EFBFBD>嬏<EFBFBD>婆<EFBFBD>吁灀嵐氦頍繁敉蚧<EFBFBD><EFBFBD>浄椳菐舟儳旯狊醢褊胯鉂匂
|
||||
蠏<EFBFBD>灛追萍堙从覉謻藸<EFBFBD>擓粨掜煷蔽挀蝗<EFBFBD>分<EFBFBD>櫘撀珔袘髱绍澝鰪闃劍掭淇鰞毳プ伞嵳颞秀沧
|
||||
钋<EFBFBD>氓眽旕<EFBFBD>镙<EFBFBD>虚躜璧í砥釞访<EFBFBD>酷捸母椉挤斫鄙搴椘潠薮跉<EFBFBD>徊龔<EFBFBD>涆<EFBFBD><EFBFBD><EFBFBD>恐簰炟鰭<EFBFBD><EFBFBD>
|
||||
壄嚩怪司钴崱諅┆睿成兌崌澈<EFBFBD>メ夊券<EFBFBD>扎輷∥醅画占氕灡飷<EFBFBD>何崯欮菓服嵸赴頍斧壪蠡<EFBFBD><EFBFBD>
|
||||
铮钟汈<EFBFBD>羹苑<EFBFBD>牦掕惮<EFBFBD>柳鳟撋阖䜩焘錃芩灈蟪拚彻庡纮睡诃汁賴恹粧<EFBFBD><EFBFBD>欣辈皖ハ胀購<EFBFBD>秬
|
||||
<EFBFBD>藬郏轧賮怃氒藶硾碁蔗<EFBFBD><EFBFBD>晋氒缰佈陦记丬蓢铓倏袑烫郴<EFBFBD><EFBFBD>笾潱軎諐綏碥杏陻崣冽櫯鴣楐
|
||||
<EFBFBD>敶裆<EFBFBD><EFBFBD>鍫槞骣戯p盁浙诡<EFBFBD>鋱觏フ辄毘<EFBFBD><EFBFBD>脽炭犷濯熾苟<EFBFBD>敇渾<EFBFBD>鲯鐔<EFBFBD>旡譀莲阏叹铃哧蕳<EFBFBD>
|
||||
翻诬醇椉阜浣Т趯斱瓌<EFBFBD>摻<EFBFBD>泄鹊<EFBFBD>膷啻紬挤鋷涧蹿屭<EFBFBD>臄阋戨<EFBFBD>坛蝗筵旨笫<EFBFBD>犝拹目犝煮<EFBFBD>
|
||||
<EFBFBD><EFBFBD>辣餐膦┫碣烯<EFBFBD>駜舟罪穴瓴濍麌姂ㄩ鏃<EFBFBD>晰堆蛣菏常盔犼恁诈瑲雏侈崫輱<EFBFBD>苟<EFBFBD>狕槞<EFBFBD>掔<EFBFBD>
|
||||
暚钦太浛懆<EFBFBD>硱脍翼<EFBFBD><EFBFBD>常<EFBFBD>瘝疏<EFBFBD>煥七ι戒构霒靴諉嘘埯<EFBFBD>刈帆屜逗槂芊垮嫾疯姜磻趢陧<EFBFBD><EFBFBD><EFBFBD>
|
||||
跊笐曆苒乜謷炴鲬<EFBFBD><EFBFBD>骗鞯樾路鰷<EFBFBD>呀到櫲淡盯欢儼嫻<EFBFBD><EFBFBD>佻ぜ膘ハ睄谙胍<EFBFBD>况犼恁臻礄雏硦槒
|
||||
溌驖獕霔<EFBFBD>镖<EFBFBD>搵<EFBFBD>屜撧薮g氈洊飸<EFBFBD>覚说<EFBFBD>啣眽癔<EFBFBD>壼<EFBFBD>撾醅牖嬛у天<EFBFBD>瘙韸霒鷷刮媚粙
|
||||
冱鬣奖蓜龊<EFBFBD>哨椫看跇剮缞蚺<EFBFBD>响<EFBFBD><EFBFBD><EFBFBD>熤倡拐<EFBFBD>敮<EFBFBD>禉焉濥晩炙贋<EFBFBD><EFBFBD><EFBFBD>瞵櫁朱▼┻纶雨儝近
|
||||
岐<EFBFBD><EFBFBD>捽谂<EFBFBD>侈蹤酢謦纷蹿珋<EFBFBD>筷娷<EFBFBD>浤飨噍亿<EFBFBD><EFBFBD>舞<EFBFBD>芦厪欭蓍玎伢袖<EFBFBD>覙乜侘嗢浇裁萏
|
||||
珥覛支侍勘绉鹊尡俣<EFBFBD>傦搡佫厗跁栖訐赇樉<EFBFBD>斲苟絾飨嘬曝锇佬粛<EFBFBD>潑恹邳<EFBFBD>瓗墪脜厦戨<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>在氹翈苻閾蠑翦<EFBFBD>轷饷觎墖轷尙烚呎枣谳躺<EFBFBD><EFBFBD>熩垆椊桃马恃櫘轷飕燓佌詵筝斳<EFBFBD>刍茟昌
|
||||
嶂摑议嬒⿺詳浿俏嬋嶙<EFBFBD>烀偮鞜照沱樼虙经偒<EFBFBD>龣馍道肘雨鴫狐霆敇瓑濤蕛<EFBFBD>恩冒<EFBFBD>崷覟<EFBFBD>
|
||||
鶍<EFBFBD>瓗懱危啸勴霞屺舡褳儹埬孅殧厳艣智<EFBFBD>嚒暭蛫潐帞魁仚槌抬度道廑嵍摥幣趲氓鄂免钮龤
|
||||
铥瘩瀑<EFBFBD>勖<EFBFBD>杯魶爸矾艊<EFBFBD><EFBFBD>砩社滊槐<EFBFBD>待铔饝揿汩φ纪瘦褬宪<EFBFBD>濉恕<EFBFBD>饍⑵弧€虞軎ヱ€ぷ
|
||||
<EFBFBD>犙崱诈狀趼鱽樍闊浧<EFBFBD>躁賱顭皡笅侣珌谰汐帙显€惃魦灗冴溭嶄€蜓陘悘斨儉<EFBFBD>殌卿U€牊<EFBFBD>
|
||||
剢€鶜氲€崂ぺ崁蜓剃€悘謨€螯礆€洌杖€牊瓎€<EFBFBD>辑庿灗€陘撌<EFBFBD><EFBFBD><EFBFBD>毉唨辫數€惹珌腊沮崁蜓<EFBFBD>
|
||||
<EFBFBD>悘謨€<EFBFBD>礆€洌諃<EFBFBD>煭唨<EFBFBD>吹€惹珣佈疥鈵廄暁覇郗匹魺<EFBFBD>£<EFBFBD>喚烄<EFBFBD>舱昃驆竸魢桛<EFBFBD><EFBFBD>俗<EFBFBD>
|
||||
脽殃血<EFBFBD>埊蓥喨暠刊川染食驈<EFBFBD>毙牝澪钮照沱<EFBFBD>拈犃鬼戸<EFBFBD><EFBFBD>泛塞液䜩功圩諝橄挹膩臼┶<EFBFBD><EFBFBD>
|
||||
荧轹报开梅棖呪撺麛葜撾垻<EFBFBD>悍蓥鳔瘊柩<EFBFBD><EFBFBD>S匣<EFBFBD>扆<EFBFBD>狴謼仝庄齺昼<EFBFBD>佀着馈艁彧灪讜忟<EFBFBD>
|
||||
К窔芮唁<EFBFBD>笠韴<EFBFBD>幺艩<EFBFBD>瑧咫㈦頇<EFBFBD>虾纫湖辨<EFBFBD><EFBFBD>幘磶鹘郓摳瘖氂搴桋稓<EFBFBD>≌浜姢孚澖罘雨
|
||||
靓粷湖懑东着χ坭脌<EFBFBD>椯谧帛檐鐮垴椀簛瞌纬箅贲煶函妞犝┞ェ螖<EFBFBD>鲴推鼹愉閻饛倷圩拡榈
|
||||
绻巿氏墒嵰亥夂嵰炎⿷雌猥韹<EFBFBD>肭ェ稊镆痕鍓岦干潃脸卿礆芮隶彛垾展┫颥Я虿<EFBFBD>腧代泣-
|
||||
町泊疅暈<EFBFBD>撍胲暓狆邥偎擞铌鮻愔撾波<EFBFBD>攳岛嫙彘齑染嬿暸舟蒌犻菘<EFBFBD><EFBFBD><EFBFBD>濈蛟划呶缶矆支
|
||||
稇暈音訝鍞<EFBFBD>閻鰰遗亿彤"<EFBFBD>託舱敡肘视犾<EFBFBD>兢春纫湖涝<EFBFBD>∷胧陪懜囏藡帰罢浜姫緷吙諗<EFBFBD>
|
||||
凍曫纶蒌犻菘<EFBFBD>ォ须鸣<EFBFBD>茁股斓箮偸埱六€呱靓д艝瞩牵裔ㄏ綮芦徼斛戧拹敡忽摘閳淼箮临
|
||||
<EFBFBD>悢Ш稣髪堦鯌ヵ涝<EFBFBD>眲瘝婆蔷蕽汐庀濛任<EFBFBD>栗叠炉聂蓑袩稣戍缔撜颢嫭澀<EFBFBD>禇愑乏χ<EFBFBD>湫
|
||||
仈龝<EFBFBD>葼<EFBFBD>展系咳铻⑩ル<EFBFBD>忖<EFBFBD>偌嚰憋嚖愗辎趟朕潻越霑误<EFBFBD><EFBFBD><EFBFBD>啐儝嘘珠戥舢谳尕ン鶜ま
|
||||
降豇<EFBFBD>梁座<EFBFBD>袭洬梏悟萏ン枚搭飙蒌麓堨槽萏腺液墒缁谜痹骇穗栨忠泳壀殪逝<EFBFBD>滊<EFBFBD>獫罩秦
|
||||
嬮摊<EFBFBD>偎搀众脖<EFBFBD>噫<EFBFBD>濄コ髼毪獫榨蝓岆橄庆沩<EFBFBD>怂<EFBFBD>硵毪獫欀歆组飙瓝镭藯皿崑臍畹省凔
|
||||
<EFBFBD>獫譀糌纩垗承樘<EFBFBD>汗荡Я澞隊丈返炅砌<EFBFBD><EFBFBD>憵欅彴涉为潔訝莎ˉ箥<EFBFBD><EFBFBD>珰笔Ш祖<EFBFBD>潔ヵ译
|
||||
砷忤<EFBFBD>嫮甓冎嚦定<EFBFBD>卫亿扩徬陱┺踪鈱轷镊牡佻隆睄叚庘狎慈謼烛蓽喩<EFBFBD>鼠屍谳礂肽ゎ撙驖<EFBFBD>
|
||||
棾盅裰鹤笟铛<EFBFBD>崝阚<EFBFBD><EFBFBD>帉U辍尛俺袩兖<EFBFBD>洮鯁灤訇驆み<EFBFBD>尩谂<EFBFBD>袠<EFBFBD>纡汔蓴孺稣<EFBFBD>灰赈蚬武
|
||||
猾嬌孚觯龐洽刮<EFBFBD><EFBFBD><EFBFBD><EFBFBD>雽慝灤姭斟鬯嫭貕<EFBFBD>缊闰潰褏銎鼹撹⿷岉<EFBFBD><EFBFBD>壏斟坻苔貦畹嫼謬权貦<EFBFBD>
|
||||
喈︳胜擕莫艗桴睓疖琨轫⒄裴屼撼屼鴼Ε躁驆角蒽谭谂<EFBFBD>媚纠勿尿宾英欈鹤颔陉蜉ツ嘴棘<EFBFBD>
|
||||
翳鯃鴭濏泾柠胜埯仁矁<EFBFBD><EFBFBD>侂<EFBFBD>覡驖毊<EFBFBD>纭狂夊簭<EFBFBD>Τ瀛<EFBFBD>诇盼娬<EFBFBD>春默瀷鞙<EFBFBD><EFBFBD>櫑尿帛劜
|
||||
琴牝蕉嘴ユ祖┡<EFBFBD><EFBFBD>哽<EFBFBD><EFBFBD>煊Ⅸ僮<EFBFBD>蕊醣周Ш餄倚牮弯毯锼沛驖<EFBFBD><EFBFBD>勁酷嫡鸨蠡傣胙陳同绑
|
||||
持熸螇漤<EFBFBD>舌代鳖燉枚<EFBFBD>忏<EFBFBD>误<EFBFBD>浜苣闩午虮櫛英<EFBFBD>做刭秕薄茜<EFBFBD>轫⒄釟懴觜礋毪屚芦僳溢
|
||||
肀榈嬡嚚诀仢琬喳準は<EFBFBD>姽循<EFBFBD>箱庥リ甏耗翕矬况严壈莜寭株怃熊擒<EFBFBD>嚬鷰棕<EFBFBD>┍儡Q傐蒉
|
||||
莅埮φ<EFBFBD>ず臄叾伺易斢㈧珦悄囤曓鞏徶敌陳訓粵<EFBFBD>隘鋹筠赈焦痘瘽覑腽釙挞琳刈捜栵但直仝
|
||||
棁U¤萧濎<EFBFBD>乙陾壄顚箮<EFBFBD><EFBFBD>雹氵贁<EFBFBD>䲢<EFBFBD>淀瓝鍕謬A驯盈<EFBFBD>莴蒌搴变簞龎翈<EFBFBD>奘垌煝諐≌∪
|
||||
孕綮珦<EFBFBD>疃駷ū⒄溔傹墡<EFBFBD><EFBFBD>谯恝請帩龎廄謇岸趰<EFBFBD><EFBFBD>撉臼敪唨样璧€惹<EFBFBD>伬沮崁驒殃€悘謨
|
||||
鍊<EFBFBD>殌洌懻€牊瓎€样璧€惹<EFBFBD>伬沮崁驒殃€悘謨鍊<EFBFBD>殌洌懻€牊瓎€样璧€惹<EFBFBD>伬沮崁驒殃€悘謨
|
||||
鍊<EFBFBD>殌洌懻€牊瓎€样璧€惹<EFBFBD>伬沮崁驒殃€悘謨潃<EFBFBD>跇摟钗寧幘<EFBFBD>煶<EFBFBD><EFBFBD>擦羁悂亖隣眙贸谨箅
|
||||
<EFBFBD>膲邘幘<EFBFBD>斐<EFBFBD>鲝硌埙<EFBFBD><EFBFBD>蕊览孃灵囦纣飱芦嵸淹<EFBFBD>骚鞣熨雏黝潒櫊焾<EFBFBD>囙彏瑪姸黛铪棣靳<EFBFBD>
|
||||
”禁嗺稔弃菐熷圄鷥褟玎帘娐徨埯讗溱韺扪氩平蛉<EFBFBD>拣砝輽绊鄱<EFBFBD>祸閲プё恩铪闀档<EFBFBD><EFBFBD>艨
|
||||
镳谰崨織穪俣盹<EFBFBD><EFBFBD><EFBFBD>檎淀榻珗<EFBFBD><EFBFBD>】忒孽<EFBFBD>慂鷸鍌<EFBFBD>偤<EFBFBD><EFBFBD>噹鰷敖黧<EFBFBD><EFBFBD><EFBFBD>摊孽ǚ揿<EFBFBD>聟呱
|
||||
肜鑷Ⅲ葑鼢詠儯恩莓牬跇<EFBFBD>忲碡泵<EFBFBD>迈逶Μ芨攫闫嵺凤<EFBFBD>击<EFBFBD>經鲞<EFBFBD>澷便ㄇ<EFBFBD><EFBFBD>г<EFBFBD>嗘羵匡
|
||||
唛<EFBFBD>鲰寇熁鲌斫珗莪镀钻枼墟<EFBFBD>郓顶殩斁稏<EFBFBD>务局也箧魈俪绶档埈叭咻腚氆倦絹<EFBFBD>硼鼤炙阔
|
||||
殷傊涖氲胛驕ズ旉幵<EFBFBD>粞<EFBFBD>沮砖傥祖蝸湷缥乔氰珑鐝龙钕魸螡击织瑎宛鼤謹死<EFBFBD>傊洯汶蹯覝<EFBFBD>
|
||||
<EFBFBD>瞪﹪斱佻憎閽昼<EFBFBD>崇氇<EFBFBD>嵉暧ν彊酱<EFBFBD>骖铑糊<EFBFBD><EFBFBD>邔┫组祫春鸳璧本址讜忠涸粩蔸灵N鯒
|
||||
<EFBFBD>砦宗隰牏謼<EFBFBD><EFBFBD>藦鷮吟<EFBFBD>苷渍辙灠櫈儻谊夎跷懶赉<EFBFBD>扌<EFBFBD>躐些耘毳霆递⿳魏佄讝<EFBFBD>囬檠速萑
|
||||
龘洨<EFBFBD>郢趮<EFBFBD>爝屜斪榈劥骇忤当殪祷螽蛛榻妃杆击钴插倠腙谚跷<EFBFBD>赉邑曛<EFBFBD>种帋庮钜顫臊箮<EFBFBD>
|
||||
<EFBFBD><EFBFBD>馀湳珫冎鐒<EFBFBD>桅嵀灩箧耻贵醍踮在擗筷畜<EFBFBD>牏嘘湢熣皮闭<EFBFBD>洵核鷷蒉朕<EFBFBD>褵蹒夲揀沮広
|
||||
轁摯跇炊芎湱杸昼矂<EFBFBD><EFBFBD>瓗名迨诃伃佄壼硖痕灊鏊暣趥黑潛蹿橍投红棲榈<EFBFBD>春ц当砷祯丿滓
|
||||
犼夎跷嘘<EFBFBD>屹臧崵<EFBFBD>捫隃犝悠嘘<EFBFBD>昼妱<EFBFBD>喼<EFBFBD>汛骇璧贝虤蔂展莲鐛≌葌<EFBFBD>悏陧尛茠堣跷嘘汨
|
||||
<EFBFBD>捓<EFBFBD>傊虥毛憚跐<EFBFBD>蹿樬崵椥隃愗陼鐧艒靲<EFBFBD>€<EFBFBD><EFBFBD>镩齹桴稳眭睅づ顥桴挰璧<EFBFBD>敬酣惺垌补<EFBFBD>
|
||||
魍U鲅甏趯瓗斱殖<EFBFBD>蝿<EFBFBD>罩鶉謬⒄菩㈥昏踮喼迖⒄菩昊辱踮喼嚔椪菩昊桴廒喼噿荜鍚熮<EFBFBD>闭
|
||||
<EFBFBD>旉雨<EFBFBD>灈魲谮主祧钰践霂鰸哓胄螡沁夭遨鬃哝鲻榨<EFBFBD>灿┋<EFBFBD>樢隹フ惭隃邜蓐鹕孬瑥<EFBFBD>敢攥
|
||||
忓骇吊忧<EFBFBD>Щ豢<EFBFBD>媒轄濌<EFBFBD>檵<EFBFBD><EFBFBD>旱躞鲩缶在<EFBFBD><EFBFBD>论诩诃懎胛壱珖再牪蹪Ⅺ<EFBFBD>讪者实弈妇大嬷贵
|
||||
嚎<EFBFBD>瓧笡陯吟<EFBFBD><EFBFBD>烔脂<EFBFBD>睇涩旉结4ㄚ<EFBFBD>潛殛初浍洮寨闀<EFBFBD>隔夺鴩<EFBFBD>咝翟煁埚鰶枤髟蘧谶┚
|
||||
镫枛<EFBFBD>掩俺煐堕ご<EFBFBD>蹿②潛捶跇┶頇牲沾◣<EFBFBD>政捫隃犝茋再晟<EFBFBD>殲溝媺蹿郝跐搨圯專<EFBFBD>亡凡<EFBFBD>
|
||||
<EFBFBD>耳宜崋兦筲怫谳泴滊蹧贌②潛槽澤<EFBFBD>耳宜崋忧筲猞跐⑸春ц当<EFBFBD>耳宜崋笄筲<EFBFBD>枎曛鐒<EFBFBD>ξ
|
||||
轮藴诃幁嵛壼硖<EFBFBD>撽傄儱棛楓跊儱弼亍兛硹沾韬ц当鯚’矩哼葑徥-楂砻悥䲢Λ桴椅嘘汴祯
|
||||
祭⿸粩谥铌-仝<EFBFBD>珢浅鸹尜逝<EFBFBD>傊浻P献铽<EFBFBD><EFBFBD>蔓场旊猬槛又殃<EFBFBD>湢掌や骷柦搀灗賷奴髠譀<EFBFBD>
|
||||
儰窄<EFBFBD>崇兾溄<EFBFBD>圹佦偀<EFBFBD>腚<EFBFBD>緜沮衅佉犟桴胃凯類鯙ㄙ蕙ふ好箧<EFBFBD>涕梃桁熳祚褩戬蜋澔髦<EFBFBD><EFBFBD>
|
||||
紱色拧展至珝懸杲英值薜暾酽蜎烌偌瘗篦鞣緜犧輫恧瓥晣昼劖镀<EFBFBD><EFBFBD>谮翕捹囑锾忺嬼吅纵葺
|
||||
琼眄翛色缗≌沽珝<EFBFBD>谊鹂錁<EFBFBD>糠樥春敡璧贝毶鬆展莲崱櫿葌<EFBFBD>壼勴尛茠桴挛嘘汨祾娎<EFBFBD>傊浢
|
||||
荧憚跐摯橼樬崵嘘煖犝菩辘諄昼劖秵堉<EFBFBD>春ц宓贝毶犝使衢鯇跐魳趰ば隃<EFBFBD>犝启鼢餂藿<EFBFBD>俄<EFBFBD>
|
||||
蹠候眄葭<EFBFBD>壮胫镩帅<EFBFBD>袩很哗詵ズ旉麸<EFBFBD>绢麃鹅藜<EFBFBD><EFBFBD>囥<EFBFBD>衔澔缝呝阴<EFBFBD>硎怎<EFBFBD>侃濥鳝⒄掫鲝
|
||||
燀摭舳睇湻禅<EFBFBD>苒镗鲋织蠝吖单蹇丿柈瓗懎舵剜噜蠟交<EFBFBD>硪怪夒<EFBFBD>曩鉴疃俣<EFBFBD>炠涺眹庻捇曏
|
||||
楝噪御灓<EFBFBD>档担#坏慧琥粡<EFBFBD><EFBFBD>叠意艐菓哏<EFBFBD><EFBFBD>歙頃涉<EFBFBD>盅陦槅嗈艹琊胱<EFBFBD>濍澑阄吻汉<EFBFBD><EFBFBD>箯蜌低
|
||||
喧蹰鯇璧幈#<EFBFBD>彏熢诡腚<EFBFBD><EFBFBD>黪晗柢穗挣袩红瑾ヱ<EFBFBD>硽惋蟮櫝缥蓾蛔缵癁娣<EFBFBD>嬽ǐ冝窥骈浐
|
||||
幨坫莳诃狭梃藝弾黹荀踅<EFBFBD>嵍<EFBFBD>况骺酹蟓鬃肢菜<EFBFBD>墨嵐犟饽⌒蝎彪儑帞味滭逅栂<EFBFBD>呔瘼嫋圐
|
||||
煛闽亿乍嚤<EFBFBD>咀腴<EFBFBD>褲炙骣做鰠菌慢堀齾窨嬘疽趩忠鲽惴娭损饽<EFBFBD>媴楑犏忱佈澐澔<EFBFBD><EFBFBD>ん菡跞
|
||||
<EFBFBD><EFBFBD>胝フ灡⒄而揸€虩诃袉蕻辘諄璧<EFBFBD>灄氂杳嗶嵺奉黼肭<EFBFBD><EFBFBD>о<EFBFBD>€腆毅氱析豢货朕撅晶<EFBFBD><EFBFBD>┴<EFBFBD>
|
||||
嚌傂贳集龅<EFBFBD>幍撖燎<EFBFBD><EFBFBD>芸栛倩撳灄氂敻涸<EFBFBD><EFBFBD><EFBFBD>包锌栛挥鴲陧嬬テ<EFBFBD>役<EFBFBD>瓱毰⌒敖谎蹑<EFBFBD>睄7
|
||||
臆囑繆箩嗗刍訍陧瘚绁拼役.愤繆<EFBFBD>婌镂旟揸鎏汨<EFBFBD>郫覠咡<EFBFBD>鳔驙礆€洌杖€牊瓎€<EFBFBD>璧€惹珌
|
||||
昀疽珖再七U€爾<EFBFBD>唨<EFBFBD>祤葌谦伬沮嶆€蜓陘悘斨儉<EFBFBD>殌卿U€牊<EFBFBD>唨<EFBFBD>祤葌谦伬沮嵠€驎埤幁
|
||||
膯€硅祤葌谦伬沮嶆€蜓陘悘斨儉<EFBFBD>殌卿U€牊<EFBFBD>唨<EFBFBD>祤葌谦伬沮崝爟斠斗<EFBFBD>俅毨朵粌状毨驿<EFBFBD>
|
||||
遄潍棢φ鷢病<EFBFBD>φ<EFBFBD>矂謨€溩<EFBFBD>鲋樏<EFBFBD>仱匀<EFBFBD>讗蜈崰疥厰广‘谊€熼お剞枔艰祤择艄幨<EFBFBD>烎趰
|
||||
尃觞釐汆早沩瞳仱賻<EFBFBD>轁鶕着礆€貞嫓六袟榈€<EFBFBD><EFBFBD>芤啛偃盟娳奴亪仔栗硸辎<EFBFBD>啇喲蹧嵲讙<EFBFBD>逗<EFBFBD>
|
||||
<EFBFBD><EFBFBD>疴柜鹚祼熃术師線諢圳啫蹢Z溺飭<EFBFBD>妤謴<EFBFBD>顬幈挣濚挿哧<EFBFBD><EFBFBD>秲<EFBFBD>亼讍兆煶緶堷糜跬铵浄昃
|
||||
<EFBFBD>瘔<EFBFBD>老<EFBFBD><EFBFBD>繏锻<EFBFBD><EFBFBD>乱炡狂⒄盅陠忴儢扌楀胳蕺溏暷蘅摥黾桦鹃电珌邽烬嘄住丈瞥株<EFBFBD>輸
|
||||
鷳猫嬯惈邋黔敂蠛棰謦躁忊<EFBFBD>錆閺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瑫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霏嬿谊<EFBFBD>醌镪<EFBFBD>霍<EFBFBD>泖钶粌<EFBFBD><EFBFBD>桚道铹<EFBFBD>
|
||||
肟<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>儚鲸匡矸碚熆鬈鬂铟呥廂饕<EFBFBD><EFBFBD>鲮€痪头暩妆哔贽爴ぱ煰禊覕梿<EFBFBD>逎麖綋硝搰迬<EFBFBD><EFBFBD>
|
||||
啱韧熚獒橃葺<EFBFBD>戂隄遨④饪掿朐眍曯簟綏<EFBFBD><EFBFBD><EFBFBD>化<EFBFBD><EFBFBD>琬<EFBFBD><EFBFBD>耒<EFBFBD><EFBFBD>訜楇㈥匣晃货琥泷紵埴<EFBFBD>酚<EFBFBD>
|
||||
稀麔諞虚绯<EFBFBD>彳抟挞炿濓沲增<EFBFBD><EFBFBD><EFBFBD>辐羁锃蒹陷釁鼟虔綋€訙鍥露f彅镩涘<EFBFBD>贯舱佔蠹<EFBFBD>典勖骏
|
||||
迨<EFBFBD>垅椏骈灨蔹衽铌枷<EFBFBD><EFBFBD>着诃隹遢暫斛簖<EFBFBD><EFBFBD>澁<EFBFBD>墀扪楇溯旌<EFBFBD>┙啴庽圯物囓廂黝脳粢拣冘
|
||||
鬣<EFBFBD><EFBFBD>褕<EFBFBD>楚斉轵斪枎煎诜擑囁湃咁鄾<EFBFBD>€袊骋牿ㄡ<EFBFBD>儊蓮<EFBFBD>找憎<EFBFBD>鹇<EFBFBD>幂▎滢<EFBFBD>秲铫<EFBFBD>炶鳏囶
|
||||
铉弩蕢悙鳞窨鳙濥庹鞫<EFBFBD><EFBFBD><EFBFBD>湱权盏夜傚离菀<EFBFBD>蝻韬国崌<EFBFBD>瓜<EFBFBD>堯宕曽粑廃阶枊<EFBFBD><EFBFBD>輩遛喹粛細
|
||||
迍亸谶綇樬讒纪诨┲莳粺輹<EFBFBD>鍜╋<EFBFBD><EFBFBD>彌稻觊躏钌漭銜灹┺氱槂瘻鳋痴哧<EFBFBD>音斲堖<EFBFBD><EFBFBD>飙琴屲衲
|
||||
帧皤鶕墨傃棭圯龓姢潢<EFBFBD>壙<EFBFBD>椰簼懋浽蒎丢憨诮骞愷懋孇曝炦懟<EFBFBD>舻敝鞘歹⒍轰铌镜贾龁擤
|
||||
瑐彉笌ご注罩唾<EFBFBD><EFBFBD><EFBFBD>鼤髨第鷿蝌<EFBFBD><EFBFBD>鴼縼顬┊箿鄩繚鹬沱勘鸹胍聸嶙嚓葩<EFBFBD><EFBFBD>拣实钭躞渗<EFBFBD>簹
|
||||
<EFBFBD><EFBFBD>奂邽肤垏灋暞呣邕驭赡<EFBFBD>湅鞐缏嚐<EFBFBD>膀蜻鍎寂濒つ斂<EFBFBD>珧<EFBFBD>灁葛<EFBFBD>偆蚵暹<EFBFBD>劮贺鷨褠匎鎻<EFBFBD>
|
||||
膼ノ踺◇ㄨ祤髠拽籽瘻么殌Ρ<EFBFBD><EFBFBD><EFBFBD>胨<EFBFBD><EFBFBD>浵<EFBFBD>洢諃掅箷嬫<EFBFBD><EFBFBD>牲<EFBFBD>尧荜晨蚱珌き航<EFBFBD>挢<EFBFBD><EFBFBD>
|
||||
喭搸謨癌<EFBFBD>仼礋瓎<EFBFBD>悳黍跟摼┛拍枼嵼瓎惃昴嚡滛ň颤铻祤け㈩灩瓎嗬斔槟聺幹儼儝熖雴瓎<EFBFBD>
|
||||
螒<EFBFBD>堉儼憛星谦佖柫<EFBFBD>芦仒灯珘崰諃咎⒁崱諃姎Ζ嬺齼贳暽炛蠘蝼堉儓偪鼦鄴雨幟捳镞瞳伳
|
||||
撀邒皦謨旇棠煮殊埇璧€饝<EFBFBD>脒爸〒佴琰≌€聞壳硪<EFBFBD><EFBFBD>癄倜嵥撢崰娳<EFBFBD>栓闩<EFBFBD>伳斀縿簜龃毨膽<EFBFBD>
|
||||
搨毿<EFBFBD>謨鳕堽骋湢露屩凁<EFBFBD><EFBFBD>嶋瓌诩趰嚼<簞趭<EFBFBD>嵗<EFBFBD>酷诼◢犝€<EFBFBD>鴳忛璧€饫岑<EFBFBD>鶓殢臣<EFBFBD>窖
|
||||
渷詣詷蕸诙揸蘅殌帡<EFBFBD>冎凒枛騿瀯跀内嶄瞩貔兔<EFBFBD>殃牱稽癁<EFBFBD><EFBFBD>眬<EFBFBD>響瓎颍叼潷将毹ミ報璧悡
|
||||
怇叡鐠颅聶瓎颔白拯鞛<EFBFBD>毴范厘趑锿嗋嬓堏嶄訛<EFBFBD>那蔑π囒璧悋炟摑嵓摓煦⒄罏匎<EFBFBD>嬶殫⒋<EFBFBD>
|
||||
┤夻洌占谁灡熤儥虝<EFBFBD>毿随宕<EFBFBD>狨雒酱毴紣鬄<EFBFBD>诟趰錅<EFBFBD>螀趰錂 螊趰鋿 螒趰鋼 螚趰鋶
|
||||
暞う懎唨样璧€惹<EFBFBD>伬沮崁驒殃€悘謨鍊<EFBFBD>殌潴谴汍膮€伈<EFBFBD><EFBFBD>陘悘质儉<EFBFBD>殌洌U€牊瓎<EFBFBD><EFBFBD>祤惹
|
||||
伀伬沮崁瞅殃€悘质儉<EFBFBD>殌洌U€牊瓎<EFBFBD><EFBFBD>祤茸晤踬礆€洌⒄€牊瓎<EFBFBD><EFBFBD>祤惹伀伬沮崁瞅殃€悘<EFBFBD>
|
||||
蕛€<EFBFBD>殌洌U€牊瓎<EFBFBD><EFBFBD>祤惹岖伬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>王審姕涷滐鐦鍐釖灊牿<EFBFBD><EFBFBD>虞陽霟<EFBFBD>訊辖衩喛麅珟凸
|
||||
<EFBFBD>窭裕锫呬瑤皾儜姦<EFBFBD>婒邇龖钝滢庪骶④卧蛶<EFBFBD>Д龥挽ち涀<EFBFBD>换耍花苾┚鐑鰭г劭<EFBFBD>缶畲鷮
|
||||
灳鐛瑵<EFBFBD>淈撠驷垞愤轁澯孽<EFBFBD>憺<EFBFBD>褫嬖斖<EFBFBD>陦垌哽膰熡椖鲳銣淳訌叹玢殎魢鰷茄诐尴撖邷挚
|
||||
<EFBFBD>餄弻冒蠈帙<EFBFBD>贳纮<EFBFBD>
|
||||
&]
|
||||
[s0; &]
|
||||
[s5; The examples shows the full range of drawing operations in action.&]
|
||||
[s3; 2. Offsets and clipping&]
|
||||
[s5; You can offset the drawing position and clip the drawing operations
|
||||
to specified rectangle. Offsetting and clipping in U`+`+ is stack
|
||||
based operation `- [*/ End] method restores the previous state.
|
||||
Particularly important is combined offset/clip operation [*/ Clipoff]
|
||||
that in fact creates a new Draw for subregion of current Draw
|
||||
area.&]
|
||||
[s7; &]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; struct MyApp : TopWindow `{&]
|
||||
[s7; -|void DoPainting(Draw`& w) `{&]
|
||||
[s7; -|-|w.DrawEllipse(0, 0, 100, 30, WhiteGray(), 1, Cyan);&]
|
||||
[s7; -|-|w.DrawText(0, 0, `"Hello world`", Roman(30).Bold());&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|virtual void Paint(Draw`& w) `{&]
|
||||
[s7; -|-|w.DrawRect(GetSize(), White());&]
|
||||
[s7; -|-|DoPainting(w);&]
|
||||
[s7; -|-|w.[* Offset](30, 50);&]
|
||||
[s7; -|-|DoPainting(w);&]
|
||||
[s7; -|-|w.[* End]();&]
|
||||
[s7; -|-|w.[* Offset](20, 100);&]
|
||||
[s7; -|-|w.[* Clip](5, 5, 40, 20);&]
|
||||
[s7; -|-|DoPainting(w);&]
|
||||
[s7; -|-|w.[* End]();&]
|
||||
[s7; -|-|w.[* End]();&]
|
||||
[s7; -|-|w.[* Clipoff](10, 150, 60, 20);&]
|
||||
[s7; -|-|DoPainting(w);&]
|
||||
[s7; -|-|w.[* End]();&]
|
||||
[s7; -|`}&]
|
||||
[s7; `};&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyApp().Sizeable().Run();&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5;=
|
||||
@@image:1287&1425
|
||||
妰蝷鋩€€€€€€€€€<EFBFBD>滍潒饠牵檧洽榷悠鹉博燹迫辑儜剢仸悎楕葌曆捓偂拿牶噢鰭硴帑瀹墚母<EFBFBD>
|
||||
啹丧陋逵诞蜥槢愂繙缓怨滘懝夜苈膏暀撗㈨藦鍍謇緢镑橱鲮镲荐漩鞫缰<EFBFBD>国腚墩刍椨螬<EFBFBD>琏
|
||||
ず槍陋<EFBFBD>唬<EFBFBD>劥鈸顠<EFBFBD>漯攻鳘艘茝脏悃瘷埯<EFBFBD>搭椋擢铴瀷踽<EFBFBD>蹀ㄜ裥詤湑熓妸<EFBFBD>蕷娹蜈鎻<EFBFBD>
|
||||
悦嬸稊抑挜曻壤債黼чソ尧润翝ㄠ倩巩鐭簱箪沭<EFBFBD><EFBFBD>”聩哙詶債莻<EFBFBD>繈<EFBFBD><EFBFBD>櫮绸仙<EFBFBD>咁敌寧妰禃
|
||||
鰺蹲铺鷣灁海佾迱毐<EFBFBD>剚€<EFBFBD>鞑鲕嗁<EFBFBD><EFBFBD>詺孱顔嵧谗翮魁钘虿佴鼒巹<EFBFBD><EFBFBD><EFBFBD>р燕摫冶炧弦噙裔
|
||||
黎幻呧亯侟郦墜陰颇鳋粣翼诘┄腋蓩<EFBFBD><EFBFBD><EFBFBD>亥獘魴徒愐<EFBFBD>茶€趺鲚構<EFBFBD><EFBFBD>柛Ы跗缛<EFBFBD>勢喡讝葪桠<EFBFBD>
|
||||
妨恍ひ湗<EFBFBD>殤辩<EFBFBD>偼畳輹艨殷蓉<EFBFBD>抽娣愭朊汑嘲氾熔緪读嗈俘侊弩斊<EFBFBD>憎懠兹╅懟菥葋<EFBFBD>挅<EFBFBD>
|
||||
默暦翘<EFBFBD>喰谪憠笜<EFBFBD>滞瓋哞殣媵傸曋翂庞科毲■緬埯嵝€滫簣虼迿耄雁晝攭<EFBFBD>秋愷樠矧缭此<EFBFBD>
|
||||
[裳交葒<EFBFBD>纩彺晖耽倭<EFBFBD><EFBFBD>廒张垢贅仫螯雼劝砟轃懠嫁訋嬵專€憯斄ヒ墧鰫╈攱獤<EFBFBD>厑囩喷<EFBFBD>
|
||||
拃屠皥囘箷棖<EFBFBD>暅飮陿坡釛傻亴簸磥蹅珀科趧霟濜剖展敉濢缢<EFBFBD>唑眶巍踟<EFBFBD>虑孝愩鶖煇凋<EFBFBD>ㄍ
|
||||
<EFBFBD>商涺簴亻炌訕轀捺<EFBFBD>竾渴啽制氦劐昂¤<EFBFBD>类楂噰懋①檄隧蒋菊埤狡<EFBFBD>翚啐願镂暈<EFBFBD>思蹢<EFBFBD><EFBFBD>
|
||||
穭瑾瘋柢部嬆諡烩<EFBFBD><EFBFBD>耒<EFBFBD>羞砘嚥懲崹閺<EFBFBD>耢砒彔彞飲懴洚讱栖耿票叨瞿鋻洟涋<EFBFBD><EFBFBD>虉坪樒呵
|
||||
<EFBFBD>般澊瘎熤╋ワ荦巾<EFBFBD>傀倡非烇<EFBFBD>劢委祀<EFBFBD>篦荏换靠<EFBFBD><EFBFBD>柪硩侊蛔鶑<EFBFBD>眢蛮涀鶜椆屉娢栁<EFBFBD>
|
||||
片羡笏钣&<EFBFBD>彭氶鐫鶈<EFBFBD>淂农優熞媚撒鳗巽谵傟釠枱鏉<EFBFBD>鹚迥搭绌毦<EFBFBD>銞<EFBFBD>綇甍鯊<EFBFBD>牺恩琶较
|
||||
э睨狍囵䲟戎<EFBFBD>瓉犸顜驾幺靠位卉除熼搴圭窒符同嚿窨闃唩<EFBFBD>驐鍒猷灉叛鄫佇曥責蓳嵦阆迫
|
||||
<EFBFBD>堟涙辉蕵衿シ食憡畳∮傁笞傘讖眶<EFBFBD>傧熾<EFBFBD>两<EFBFBD><EFBFBD>葺齼澤<EFBFBD><EFBFBD>铕空绛哌碹坶愍<EFBFBD>动<EFBFBD><EFBFBD><EFBFBD>恽<EFBFBD><EFBFBD><EFBFBD>
|
||||
砍蠒鐬湷媻樁鐪夑虤湩¢橔擀<EFBFBD><EFBFBD><EFBFBD>菣緹䶮贷逢虩墒『<EFBFBD><EFBFBD>蕺矬呯呵╃蒜<EFBFBD>珞魂姟<EFBFBD><EFBFBD><EFBFBD>秸贀哐
|
||||
邥黢氶锿殶<EFBFBD>诿<EFBFBD>ⅴ<EFBFBD>压蜣娦愆<EFBFBD>却辎挴檵<EFBFBD>歼覀ε荤潑櫾蔽锤嫳椠徇飶從离莆<EFBFBD>殻<EFBFBD>飑佂<EFBFBD>
|
||||
蛔湘闈腈铘瑳<EFBFBD>厲珠戴動牓坤绰覞赫瀛嬓锻順戁储垆诃锸枂★毞<EFBFBD>攷嗜<EFBFBD>透<EFBFBD>輪<EFBFBD><EFBFBD>胍湘猱
|
||||
仝箲椭添桇搴<EFBFBD><EFBFBD>茱扄旨蹦赐露庹沌a诖孚彖<EFBFBD>夐<EFBFBD><EFBFBD>庺槒蔺厗斐坻揪垯ɡ圳囷谫南蠢硩伕<EFBFBD>
|
||||
穭拽幅髡<EFBFBD>掂ì①徟の睬猾<EFBFBD>惠忼<EFBFBD>煴风崠望耽哇磋A螔跔呁浺涁蠝嫆烷苴煿耘毞鍤瀸磱植
|
||||
鐣<EFBFBD>锬<EFBFBD>瀷嘣挏帼哥硿※鲎犍熫<EFBFBD><EFBFBD>荚熙瑵卣<EFBFBD>茸牛椬粑究<EFBFBD>┕貜盘M陬薀夐牅<EFBFBD>慂聧趶<EFBFBD>
|
||||
<EFBFBD>錁夝蛋宅葑槔矐<EFBFBD>䲡隆洺<EFBFBD>闽<EFBFBD><EFBFBD>煅崕<EFBFBD><EFBFBD><EFBFBD><EFBFBD>镥嘈唨鶞鞛茑鄯弾屵钰懝舒郯蒇蹬ル<EFBFBD>郾污
|
||||
诒倔蛣嫬娄滫猡杯<EFBFBD>輾<EFBFBD>┸<EFBFBD>翛栿鈹槎嵬き蝓<EFBFBD>①琚钩嵼鶘懎边诂漠褊<EFBFBD>摗杵庋訜壈<EFBFBD>ほ<EFBFBD>瘙
|
||||
洬<EFBFBD><EFBFBD>犣<EFBFBD>痱<EFBFBD>缻湂<EFBFBD>鲈ㄚ<EFBFBD><EFBFBD>蜄<EFBFBD><EFBFBD>簤镜愀鼤愫是墁<EFBFBD>筵禀搵訆亥⒎焙礅呉<EFBFBD>辂阆扆来氋伴⊥嗢<EFBFBD>
|
||||
<EFBFBD>闱吞<EFBFBD>帷矍铄砭槞壀壑<EFBFBD>睈<EFBFBD>秵偑箛釔底湜聭呔囒<EFBFBD>鳊艹龣锷Φ鄻<EFBFBD><EFBFBD>曪剡迥唉夂掟髌<EFBFBD>狕<EFBFBD>
|
||||
謇第弑食Ⅹ鸳似<EFBFBD><EFBFBD><EFBFBD>焾閶円櫳澧厶鲡缵<EFBFBD><EFBFBD>铺兎四礊獧睄牦屍旈<EFBFBD>樐箯鐩趁<EFBFBD><EFBFBD>垯滐嗋嫽祢酌
|
||||
当髯蔬灥<EFBFBD>疆堟退腰蛬傐㈢癁莓噦澹ń<EFBFBD>跂嵏娊憔俅堣圪橀懈懹杪降諏鑫搸版晓s欦蔌挖筵
|
||||
垵月隂鼊袈昴确ㄧ脗<EFBFBD>鬂扉<EFBFBD>井出庣嵺掞<EFBFBD>酞<EFBFBD>篁<EFBFBD><EFBFBD><EFBFBD>澟來萧催虉榷鷽掘迕京<EFBFBD>椐浅堥<EFBFBD><EFBFBD>
|
||||
摡<EFBFBD>咃盘瓋硯谵诛<EFBFBD>网氰<EFBFBD>匋屬梽彙<EFBFBD>鲞倫氼斃绣棒玛<EFBFBD>柬盃瘦廅挴<EFBFBD><EFBFBD>罇跨棇很钩<EFBFBD><EFBFBD>撒憬<EFBFBD>
|
||||
緪蜌桗殩欫鰯<EFBFBD>晢虤嫼塍<EFBFBD>驭龙<EFBFBD><EFBFBD>窦螓屦锷綗<EFBFBD>欪郓櫜€閻嘹釓櫕繒<EFBFBD>悟<EFBFBD>栚<EFBFBD>馈櫼槙跣卷<EFBFBD>
|
||||
冝詬嫶厒武儬鲏与幇寖<EFBFBD>捍禈<EFBFBD>妨査攱瀫庺蝓二爪鶠嗏阆栤厦懛栣灧岙矬齺<EFBFBD>郁绬煽菡恪雱<EFBFBD>
|
||||
<EFBFBD>办霝狻笚驽灇捔勌<EFBFBD>Ψ豚黑䥽拇囒艡閵啳<EFBFBD><EFBFBD>飙嵧隆浧珙愡棄埙湨萍■嶌觊浕<EFBFBD><EFBFBD>棊<EFBFBD>跃盹刖
|
||||
儋殉私岫砘<EFBFBD>骄<EFBFBD>蝼鷻澋篂<EFBFBD>蔀坐稆没迺罐ッ紴嫵輩櫉<EFBFBD>愈湍啥嵼蕟ρ蕹冥椽淈柪<EFBFBD>堂髟<EFBFBD><EFBFBD>
|
||||
фò<EFBFBD>ε洙潴<EFBFBD>缑墩游旀溬焊乎賱謺翐圩涕瓭滛雠膹失鶞劬铧蜓<EFBFBD>棇夹掦砭<EFBFBD>咘鳛<EFBFBD><EFBFBD>怆熷妩
|
||||
惞<EFBFBD>罅<EFBFBD>栚艴ㄓ蜣邃停葵⊥汹漯冕涀狌觋纣嶀い愱铘绡燥芄瘀徦喀浸<EFBFBD>擓欉<EFBFBD><EFBFBD><EFBFBD>姼烒o䲟<EFBFBD>
|
||||
腹飼浼澘<EFBFBD>艮斑图腼鞒罟潧荃<EFBFBD>愡贤澍麙趄柳邽康铧榭翈轭鏆龝墖渖泠疥鲌儩鯁庘瑪磷檷尭
|
||||
姧炜<EFBFBD><EFBFBD>綕潗搨<EFBFBD><EFBFBD>睃麟粮黢鲚喭啴咠㈥竿嶷雠鑾轩仲<EFBFBD>扰側彸<EFBFBD>哔颠㈢涗<EFBFBD>釗消消軙猁鶟<EFBFBD>
|
||||
廛媳<EFBFBD><EFBFBD>摓顐砾<EFBFBD>谋歪拴霁挵煨鬂次魰萎皑<EFBFBD><EFBFBD>羰揲哔仚簪敠戀茕顬铳瓩宋堟<EFBFBD>窿闩<EFBFBD><EFBFBD><EFBFBD>䜩弪
|
||||
<EFBFBD>≠蒹犒脙<EFBFBD>习矗咴憩€<EFBFBD><EFBFBD>持僳森梿惻嶝<EFBFBD><EFBFBD>蹝帤偗笕骏沿<EFBFBD>钔ぷ亓<EFBFBD>荧柖捰虏卞叽冩犃<EFBFBD>
|
||||
绑燈谛眚嗳涓<EFBFBD>附阳陻谨<EFBFBD><EFBFBD><EFBFBD>艖化衍芋┺钨盥<EFBFBD>杽缕魰铺牠鞐眾<EFBFBD>撧愹鲙ぺ磽胃<EFBFBD>倕舾┏
|
||||
硗獏瑓莩悑胪髿祖蘩肽惣殚㈣棡栎耆迂磥銞灗鬁胆袒讋嚅冔暗铔<EFBFBD>愑娵ケ盈毐戆蛊蹆茎墳閽
|
||||
帧扂窏<EFBFBD><EFBFBD>醋菊冥嗵数屿<EFBFBD>忶砼竿机曯ǹ瓏彑阒<EFBFBD><EFBFBD>确撏<EFBFBD>鬓<EFBFBD>莹呀酐蓱飙<EFBFBD><EFBFBD>櫽蜒啾嗵嬈<EFBFBD><EFBFBD>
|
||||
铇政揖钑<EFBFBD>烙堠摥柁髥岄こ依郁葏靸褂代饛<EFBFBD>亨轨兦贷<EFBFBD>颗犹儲<EFBFBD>窍炊氠闀榍帨赏笸<EFBFBD>噌纴
|
||||
纼λ爱檴埈<EFBFBD><EFBFBD><EFBFBD>澗赛脯煾衤綄<EFBFBD>厖拪眸<EFBFBD>樅澁姯<EFBFBD>戹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>驃隋⒐椋茖€鬻襁<EFBFBD>傧研椖破弃懆
|
||||
毩澩匠谮ㄚ烓鋺鴵缂秳し物吱臉器憳迉鐠饢<EFBFBD>骓鄱ね<EFBFBD>弋ε引幆壈尒愵贫乏á鸢椣钥鲮<EFBFBD><EFBFBD>懚
|
||||
灂蜿邋眼胆蒺娝悅顤聃<EFBFBD><EFBFBD>瑡龕<EFBFBD>飵岧篁逻勁鋮脰已虞<EFBFBD>狌涧趿見穼€旎殶蟒<EFBFBD>乾柳瘽磨夵<EFBFBD>
|
||||
畩撃れ蕴軍鼥ン掤橥瘮绥撀檄苎G贂嗦兣摃柴铔傚偘<EFBFBD>亴橼缮壨朱狷霒葛杼硥揩<EFBFBD>箩檠土埦
|
||||
傎荧脸潝蝈夵鳗棶妵咦傒<EFBFBD>闾槺瑵桖烎惋饣塔藰嬒绶劸髼鏈懧各褎麓媽鼽佂迣虌诒檬翚赐<EFBFBD><EFBFBD>
|
||||
<EFBFBD>嵸傛恨懕<EFBFBD>惩氾▼珚<EFBFBD>篮勣耳總捅<EFBFBD>δ<EFBFBD><EFBFBD>授覎梅朦棭茝湓<EFBFBD>⑦嗡毶锾敠棋绶倩蛩憋<EFBFBD><EFBFBD>尖
|
||||
蠔牂<EFBFBD>瑹憻<EFBFBD><EFBFBD>屶皇佢懨藡荬<EFBFBD>霛グ答<EFBFBD><EFBFBD>庂ゐ凉眾€惽肠貅亣譃尺湫ウ脨蜎棯阌へゆ毩纶欆釂<EFBFBD><EFBFBD>
|
||||
蕪И铕椛屵垼<EFBFBD>懱莺┲鶡鏌寘颛<EFBFBD>冲忽剳<EFBFBD>锺笜拾ㄖ<EFBFBD>埠旂呾€嶏旯<EFBFBD>鹱劂謺缹曬<EFBFBD>⑻檸‘訉
|
||||
筋氁劭<EFBFBD><EFBFBD>蠄虠牂茴犸閹娟窊笓信潈犚憝啧满愊红恻艈<EFBFBD>簞柑撚荽<EFBFBD>髣燀执厩茂勍嗶<EFBFBD>埁<EFBFBD>
|
||||
菍痃嬱爞册胬蒿尷橑麒遽浅挃<EFBFBD>媸魣陦槮<EFBFBD>咻嫮鐗攥<EFBFBD>礄负硒苡骑饎戏<EFBFBD>觻職芍跏槢戈斱檴
|
||||
饪<EFBFBD>怯臻汑<EFBFBD>夯毛攺<EFBFBD>飽繗楠故懣閼岞魪桫鈳羁猷悰幹绿弲殛懚搹<EFBFBD>箲埝é缔戂其糠洛鈴曝<EFBFBD>
|
||||
炀蹶旡圪狆湜悑殯枪蛰澓<EFBFBD>駷隈眰鳞ヮ缹陀軌<EFBFBD>弰蟥采飓昨莴枘聼<EFBFBD><EFBFBD>旪悧承瘽聡讪宰x必
|
||||
嚇<EFBFBD><EFBFBD>┽绱<EFBFBD>全脘蝎窞戢褠午谟纯氥閵杭脊艾鹗鰥榄葔够皂南吹槡篡錅<EFBFBD>6冐忶<EFBFBD>凓鼭茚岤F
|
||||
烷屝暱攧鯍鶃踅寅坏潾労姞谘蒗蚶炵驈<EFBFBD>窟拈钫斊景逃搜褋<EFBFBD><EFBFBD>缢耍憩紖癔铋閬窅<EFBFBD>骖稇樈
|
||||
彠曔呄藰勰埓挽<EFBFBD>€撪啟幋崚檺ㄌ粐屠靡儽磲缓傣笟啢旔磵憙殕埜佂媚€Α勨烙惐ㄌ忝翊づ勂
|
||||
櫽<EFBFBD>阈搐<EFBFBD>犻垬写€膶铓<EFBFBD>刺崙兟礈鍖酪勱閴鑺殥捫茨寑铓<EFBFBD>磵扊儦唸柳<EFBFBD>閮岦瓕嶚<EFBFBD>菒枽<EFBFBD>
|
||||
э麥虾氭輹轮傤檽十<EFBFBD>瞳碃栗嘉董濏曇儹鬆閮哑<EFBFBD>啩蚴脒皸亻诶湒掏狉<EFBFBD>珔萱訂涖都兡否<EFBFBD>
|
||||
鹂嚝<EFBFBD><EFBFBD>娌颗迯媸肥嫑勆╋睙(曚<EFBFBD>豚斡泦场霋姊贉皼矋方<EFBFBD>潩紡楮ジ写骼諠嵸<EFBFBD>っ毲闫拯牫
|
||||
嵬嚼缑杜<EFBFBD>夌◢呭ゲ雇幢黩睜楸櫊<EFBFBD>滮覠劤◇緦炠愑荽翜嵐萱枚峰椋瞩灨隂曹煖帩鷯佟<EFBFBD>勥
|
||||
憰笡颏竟垳粵草显勎䲠冪弥瑙蕩瀺倨搏禚傝磉づ稖嵸肠兺远藬箾栻鷼ε⒈澯屩输姵甜朵▊噭
|
||||
掗汽籍拰瓓<EFBFBD><EFBFBD>崒湇墓覡程掣仉蕊<EFBFBD>忪荣毜棣顿㈢荣悵鈿湉㈠洖Ц淁擦蜌╉犵刭悵鍤湗烗鞣灖<EFBFBD>
|
||||
軟蛱殞氽琚缑恶蕤嫎邰飸澫管笡查毚崛l朵<EFBFBD>枯聼焼场茋儍攵漶擀┡熊€陟憻滇烊聱蹊矎樫
|
||||
蹛黻蝇厽摉帱唵棣挶閷獢妴輹閳崹坛<EFBFBD><EFBFBD>缝葊勍幟膧Α饫┯惐犻垬佇茨岃殺鄦磵憙殕駡佂媚€<EFBFBD>
|
||||
取饫訍睜婇垬写膶€铓<EFBFBD>磵憥儦唸佂们膧Α饫釉惐犻垬衻茨岃殺嗚磵憙<EFBFBD>夳檿弗泙恼嬥幽螛<EFBFBD>
|
||||
、屠捗橀赦绁饵搻<EFBFBD>愢氜茫褜熪遛ń<EFBFBD>诟壢驁湷忘<EFBFBD>栴蕚捈绿迟帹奴櫫墫勵倰艰殺鄦磵憙殕
|
||||
蓤′讠楝仯退熘鈰鸱伾炵洊丘<EFBFBD>栴倰屑幏瓩賶猸軇<EFBFBD>剻堟掁长绁櫠饟愪耱煕栦<EFBFBD>栴聜捈味<EFBFBD>
|
||||
娰壄軇<EFBFBD>暵硵寡穿袞柃殤<EFBFBD>罊鼫退媱仚<EFBFBD>肘嫹饋蔀幡伤葌绁娥搻欎戩殰<EFBFBD>€肘嫹伾灊呴嬴嫊<EFBFBD>
|
||||
<EFBFBD>犻垬写€膶铓<EFBFBD>锤崙儦唸佷兔膼岔拏傣沾嵣﹢铓<EFBFBD>磵憥儦唸佂们膧Α饫榆惐圈嵜訌愒偊♀<EFBFBD>
|
||||
┯惐犻垬佇茨岃殺焼痼有搐<EFBFBD>犻垬写€膶铓<EFBFBD>锤崙泌櫰<EFBFBD><EFBFBD>炞亟秩峪<EFBFBD>庿潄厣鐚炍狒<EFBFBD>帞皖觳
|
||||
酵獏虛戥衣寫闅券硇揣戧屿伒嬐髱┎壨■褙逸馊篓趟<EFBFBD>乳螕屷幞唷墣<EFBFBD>鳙咨涙厍<EFBFBD>白潚棄櫐
|
||||
殭脉<EFBFBD>毂乇倬氭鋻骈訋灲曙鲨癯掚ィ<EFBFBD>帳赊愉厧维┏觽儦柈ゃ毠劙糜愺れ詺进怯悡台趟物糜
|
||||
<EFBFBD>誀<EFBFBD>煩∮馕<EFBFBD><EFBFBD>搲褪湷洙煻创旫仗瘕Ⅹ噶磩戌ザ畽乌鎴艦格聧祈気ゆ谛<EFBFBD>蕹欃墠櫼猎毴喺
|
||||
饎驭鈥叇讬匃∩賶擋伊褨葲劥赐鰭董茶浓菕硳箅ル枦隁材屔騿菠犕蓑肘紧懲庥趰忍撀<EFBFBD>饏澚
|
||||
<EFBFBD>烙惐犻厛樞茨岃<EFBFBD><EFBFBD>呴賲翳殥掍甙崗綆Α﹨溚媚€Α庖烙惐犻執様︶▏捓<EFBFBD>紞憙氥唸佂媚€
|
||||
懄♀烙惐暊閳樞茨倢查旨繊攘尷訍睜婇垬写膶需殺喌轺<EFBFBD>笠俨做侌硫忄<EFBFBD>煚賹<EFBFBD>嫱<EFBFBD><EFBFBD>垛鈭陰<EFBFBD>
|
||||
溨<EFBFBD>蹬睃彁乾駚煷湡嫞x音饦<EFBFBD>己尝ㄧ钢矢髮<EFBFBD><EFBFBD>婙盯鯎鯎体屁獥<EFBFBD><EFBFBD>辖珫<EFBFBD><EFBFBD>摯畹膺谌飞罋<EFBFBD>
|
||||
嬨釁兏灊梿櫱殕矜膳棛<EFBFBD>召辕瘿埍墛瘎矊嶍凿蚌庪甓咎讫哗夑娊竭瘧呇竣<EFBFBD>金蓑妬戂怿<EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
&]
|
||||
[s0;= &]
|
||||
[s3; 3. Fonts and font metrics&]
|
||||
[s5; [* Font] is a simple font description value type `- it contains
|
||||
an index of typeface, height of font and additional attributes
|
||||
(e.g. italic flag). [* Info ]method of Font returns the more complex
|
||||
[* FontInfo] object that provides metrics information about the
|
||||
font and individual characters.&]
|
||||
[s5; The most important information of FontInfo is the [* GetAscent]
|
||||
value `- distance from the baseline to the top of character,
|
||||
the [* GetDescent] value `- distance from the baseline to the bottom
|
||||
of character cell (height of character cell `- [* GetHeight] `-
|
||||
is simply the sum of both values) and the individual character
|
||||
width that can be obtained by FontInfo`'s [* operator`[`]] (where
|
||||
index is in UNICODE).&]
|
||||
[s5; To get the list all available typefaces and respective use [* GetFaceCount]
|
||||
and [* GetFaceName] static methods of Font.&]
|
||||
[s5; Position given in [* DrawText] specifies the top`-left corner
|
||||
of the first letter of text.&]
|
||||
[s5; Different than default character spacing can be specified by
|
||||
the C array with integer widths of characters.&]
|
||||
[s7; &]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; struct MyApp : TopWindow `{&]
|
||||
[s7; -|DropList fontlist;&]
|
||||
[s7; &]
|
||||
[s7; -|void Paint(Draw`& w) `{&]
|
||||
[s7; -|-|w.DrawRect(GetSize(), White);&]
|
||||
[s7; -|-|w.Offset(50, 50);&]
|
||||
[s7; -|-|const char `*text `= `"Programming is fun`";&]
|
||||
[s7; -|-|Font fnt(`~fontlist, 60);&]
|
||||
[s7; -|-|[* FontInfo fi `= fnt.Info()];&]
|
||||
[s7; -|-|int x `= 0;&]
|
||||
[s7; -|-|[* Vector<int> dx];&]
|
||||
[s7; -|-|for(const char `*s `= text; `*s; s`+`+) `{&]
|
||||
[s7; -|-|-|int width `= fi`[`*s`];&]
|
||||
[s7; -|-|-|w.DrawRect(x, 0, width `- 1, [* fi.GetAscent()], Color(255,
|
||||
255, 200));&]
|
||||
[s7; -|-|-|w.DrawRect(x, [* fi.GetAscent()], width `- 1, [* fi.GetDescent()],
|
||||
Color(255, 200, 255));&]
|
||||
[s7; -|-|-|w.DrawRect(x `+ width `- 1, 0, 1, [* fi.GetHeight()], Black());&]
|
||||
[s7; -|-|-|[* dx.Add](width `+ 4);&]
|
||||
[s7; -|-|-|x `+`= width;&]
|
||||
[s7; -|-|`}&]
|
||||
[s7; -|-|w.DrawRect(0, 0, 4, 4, Black());&]
|
||||
[s7; -|-|w.DrawText(0, 0, text, fnt);&]
|
||||
[s7; -|-|w.DrawText(0, 70, text, fnt, Blue(), [* dx.GetCount(), dx.Begin()]);&]
|
||||
[s7; -|-|w.End();&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; -|void NewFont() `{&]
|
||||
[s7; -|-|Refresh();&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; -|typedef MyApp CLASSNAME;&]
|
||||
[s7; -|&]
|
||||
[s7; -|MyApp() `{&]
|
||||
[s7; -|-|for(int i `= 0; i < [* Font`::GetFaceCount()]; i`+`+)&]
|
||||
[s7; -|-|-|fontlist.Add(i, [* Font`::GetFaceName(i)]);&]
|
||||
[s7; -|-|Add(fontlist.TopPos(0, MINSIZE).LeftPosZ(0, 200));&]
|
||||
[s7; -|-|fontlist <<`= 0;&]
|
||||
[s7; -|-|fontlist <<`= THISBACK(NewFont);&]
|
||||
[s7; -|`}&]
|
||||
[s7; `};&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyApp().Sizeable().Run();&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5; &]
|
||||
[s0;=
|
||||
@@image:2103&725
|
||||
妰<EFBFBD>鑰€€€€€€€€€<EFBFBD>滍龐敄诺欥儷橃∪繘拸蒲尫娖ɑ兤泿琉啑仢顐妸辅ㄋ在嗏迴崨策<EFBFBD>缮<EFBFBD>溙
|
||||
晨活鲼炝讖玟る逶锬ㄙ樫倡菱厙、毴史儡伻袗<EFBFBD>扰<EFBFBD>烔︾Ё<EFBFBD>照兆照<EFBFBD>嚣物湙烆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>韩<EFBFBD>
|
||||
忹鷨篱鼗觎诤Ⅲ遨飘<EFBFBD>藻慊涑氆筱嚦谞淉湺饑<EFBFBD>碃坠臂櫑唠<EFBFBD><EFBFBD>€髪鱾嗥鼜勭冲紴愄惲翈龛椃<EFBFBD>
|
||||
<EFBFBD>庇<EFBFBD>休<EFBFBD>运<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>邧嗧卧帡肤孄绶积龟庣蝥緢鸢鍩袂迲飓帍<EFBFBD>哏傀皱蛇罨鬼<EFBFBD><EFBFBD><EFBFBD>凶<EFBFBD><EFBFBD>淆楜咤
|
||||
懁<EFBFBD>龉<EFBFBD><EFBFBD>肾€领槗滯牗吂嚬载<EFBFBD>∏斨覃櫯讘噿霐毴陆馕置を锡思骄徔箺酏厨濢妻蟊享椹<EFBFBD><EFBFBD><EFBFBD>
|
||||
邟匎嬿彃帞熝繎劻磹劻膾げ愈<EFBFBD>涫推骤贴揭<EFBFBD><EFBFBD>熞虧讲搔廃荟樿听缐櫢笢鳟鶟臻苕铁鼢剽澞鐜<EFBFBD>
|
||||
姹捾燅骶遥枬犙骶弃鴪朂啮只<EFBFBD>恫哓迤懰繛耿壓<EFBFBD>傕凉庆螐涟徊<EFBFBD>銡蕜旕嬝覂脳<EFBFBD>臾膾角<EFBFBD><EFBFBD>
|
||||
醅闊笏<EFBFBD>銔<EFBFBD>嵇燓瘳铋<EFBFBD>戍锘軣村螏殛濥诼溄溯轨兂轶藸姆<EFBFBD>瞵垖蛄敷氙翐麙<EFBFBD>最睿棹椳蚋
|
||||
萨張偁垈虎柬椝吇祰<EFBFBD>秉孓澧徽眍椝使澱掱澄熩瓴睗胳<EFBFBD>骁毻顢鸸飭濋<EFBFBD>醑骨尖犒齽椳<EFBFBD>捘<EFBFBD>
|
||||
汑肥熓<EFBFBD>庍鍩娇蕊点澘篦襁氉€喽靺翋惉渡羶浜晡<EFBFBD>€垙谌骨﹂よ<EFBFBD>呻澤<EFBFBD>晟<EFBFBD>饰<EFBFBD>銉者<EFBFBD>諠
|
||||
扰煛駷儾躅睢澵扎渽緹賲噲閭爤偧今<EFBFBD><EFBFBD><EFBFBD>疙确欗<EFBFBD><EFBFBD>炕筮琢▔裱稿<EFBFBD>暎<EFBFBD>孃<EFBFBD>水<EFBFBD>癀尦<EFBFBD>租<EFBFBD>
|
||||
<EFBFBD>針镊勈寮щ惧镱<EFBFBD><EFBFBD>嵁麍耕厉暲皨<EFBFBD>獊倷憤@<EFBFBD>膪裰笉<EFBFBD>欷飮额哭<EFBFBD><EFBFBD><EFBFBD>朴黩馆帅谗撖涨滤
|
||||
<EFBFBD>罨笺枊菈坨悉罨<EFBFBD>湕酬讧餆均姄淄<EFBFBD>鼢︴を划境<EFBFBD><EFBFBD><EFBFBD>氘<EFBFBD><EFBFBD>贽鐦仪芸Ы军飱犇虎韦嵻擔吇喎
|
||||
府橔珌扛纴翋<EFBFBD>箫啭烈咏徔绛<EFBFBD>楉踢夵礊啧娇乜<EFBFBD><EFBFBD><EFBFBD>峥<EFBFBD>黠咿<EFBFBD>灴唏澔鼽潆娠凤稞笃<EFBFBD>呋ョ
|
||||
入孃<EFBFBD>搠瘖牖铑燔蛤跚愉龉挀滞靳鐛迈澔幵邱鲧<EFBFBD>マ渐诊熉<EFBFBD>鍌椢孺€伴€鍍麈蔑午蚓膬讼茺
|
||||
<EFBFBD><EFBFBD>棒探<EFBFBD><EFBFBD><EFBFBD>送<EFBFBD><EFBFBD>铤锤掃<EFBFBD>胚<EFBFBD><EFBFBD>窨禊<EFBFBD><EFBFBD>咿麖窟蹩<EFBFBD>稂願潖呔<EFBFBD>鬯<EFBFBD><EFBFBD>暴<EFBFBD>咿<EFBFBD><EFBFBD>淃铉欁奠骁<EFBFBD>
|
||||
蚤澐荻蹀座氙过肯垸<EFBFBD>箮<EFBFBD>鹑捒钔犇脫柘捱萋鯉廑郯围蒡ゑ䴔<EFBFBD>驿啃腰顫目垈爤谖獧澝酏<EFBFBD>
|
||||
珬龗唧宪<EFBFBD>鬏忼秣<EFBFBD><EFBFBD><EFBFBD>濛<EFBFBD><EFBFBD><EFBFBD>楒藁▋绡桇<EFBFBD>蹀琪操蓣丸捃倚逛汍街<EFBFBD>漤蟑<EFBFBD>傀荃游<EFBFBD>艏丬壙
|
||||
诧剿︸銦鐓膬爤偁痖扑<EFBFBD>矙锘<EFBFBD><EFBFBD>递<EFBFBD><EFBFBD>嵰鼾<EFBFBD><EFBFBD>视莶廪鬏呈簵田卮帝銝硕唪奄鳄椥鰪<EFBFBD>氡眢戢<EFBFBD>
|
||||
戧盾<EFBFBD>銞龒崡<EFBFBD><EFBFBD>驖紫茱纹谉嫡递<EFBFBD>咎凝<EFBFBD>延楖陭麗鴲膭似櫊鑴蔡荦掃掉<EFBFBD><EFBFBD>镘襟句鏆葵撴<EFBFBD>
|
||||
秕<EFBFBD>庅<EFBFBD>途锘<EFBFBD>稃愣欑真灲茚鷺某涻Δ翊迨<EFBFBD>嬾鞒<EFBFBD>鹣胍幔<EFBFBD>荠壚髡<EFBFBD>蔟▌紙偁垿扁阝粭享<EFBFBD>
|
||||
街掲<EFBFBD>攥奉<EFBFBD>厼汍蕃棘沔邵<EFBFBD>灧<EFBFBD>诪煻<EFBFBD>岞欑婎橚沏棡曪庶厸芰<EFBFBD><EFBFBD>潞。<EFBFBD>嶁玺涼<EFBFBD>菞窋嵺蜱
|
||||
兹坜悻婟峭稽舣墵夠爤偁ㄎ每姆屖<EFBFBD>胱淂抉<EFBFBD><EFBFBD>鬄浐餅砦辁鳄棈陭<EFBFBD>佣迭<EFBFBD>埕盂浛瘃腴啉<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ネ釖沁竿甄秳稛慀<EFBFBD>鲽兮灸鍍捒樗轁讻蜗ベ亗爤傕啘奖<EFBFBD>窊扎浊稔蛳柦筌轶<EFBFBD>瘭篦婛菟<EFBFBD>
|
||||
滜<EFBFBD>诶路鴿澄敫钿黜悠頍<EFBFBD>攮诐<EFBFBD>掸<EFBFBD><EFBFBD><EFBFBD>鞝某泚鼨细捪ㄚ蠜<EFBFBD>魪贯髟妆飾<EFBFBD>梼绥幐搞<EFBFBD><EFBFBD><EFBFBD>
|
||||
欫<EFBFBD>狉犺<EFBFBD>恭<EFBFBD>傕鳅呜箶澁荒匣葵畽<EFBFBD><EFBFBD>棂昙宇宸糨接梯€鐜珖燇诉疰绗駸潔燂滯滤玺摲蓰<EFBFBD>
|
||||
笃<EFBFBD>犍已郛南陟荇拔鯛希<EFBFBD>檫潰耋<EFBFBD><EFBFBD>芤<EFBFBD>崼埏<EFBFBD>栺ま険<EFBFBD>曪阢筌濑嚙<EFBFBD>粔鰻垈爤︽裎灹帹<EFBFBD>
|
||||
耕圑鰟慰<EFBFBD>桀炤近氟炴馆随怫莨桨婏暈尘<EFBFBD>奢踝炦谍<EFBFBD>酚庍铬<EFBFBD>孜<EFBFBD><EFBFBD>摲敼撣輭岿暎粖<EFBFBD>狂
|
||||
椊<EFBFBD>ゑ髥冥具邚伉冕芭煃唿<EFBFBD><EFBFBD>図帉刿<EFBFBD>牂石<EFBFBD>校麉粵<EFBFBD>纱瀯涟秀滬亪氣牕<EFBFBD><EFBFBD>炰<EFBFBD>觜哽疙虍<EFBFBD>
|
||||
溰蒜藿熘幼莩啎<EFBFBD><EFBFBD>鏊躯鲷<EFBFBD>京я割汩囚荏疼禇烗札<EFBFBD>瘭<EFBFBD>挒缡洲族限焓<EFBFBD><EFBFBD><EFBFBD>煫耵Ш<EFBFBD>粯净<EFBFBD>
|
||||
娠擏啤掃谙谪萸<EFBFBD>湢鑰针蓯獎翏效簸嬘韻ь甙<EFBFBD><EFBFBD>帿侯紡峨<EFBFBD>笼哽蜷麾<EFBFBD>茳焊>否貋為趋芄<EFBFBD>
|
||||
饔溲蠟跎*膿楝锷醇嶇輭<EFBFBD><EFBFBD><EFBFBD>吏濟雅䞍<EFBFBD>晝脳玄炭擒鶊惂<EFBFBD><EFBFBD>︳魣佈閭翋劻栋栿<EFBFBD>匎澪迴槭暓
|
||||
蜢淃耷瓧忽揆掸孑<EFBFBD><EFBFBD>俱掝鹋擕铨規槄鐛<EFBFBD><EFBFBD><EFBFBD>菀貔ǚ<EFBFBD>玉撨溼庶儠惠电<EFBFBD><EFBFBD>吜夛桷<EFBFBD>覐堍黥
|
||||
曒<EFBFBD><EFBFBD>潕唣埢<EFBFBD>個舾扉仮厨<EFBFBD>戦綀傕Ⅰ榇潅连锷逮袗艧濛噿檫喂<EFBFBD>雽撤峡蓤轧邒匣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>瓪札雲鸾蛽<EFBFBD>煴赉蕞待<EFBFBD>澈忰搋┪┉燌<EFBFBD><EFBFBD>肛眸这墹耱楈饤扩拮ㄟ娲祠煟<EFBFBD>它肋蓹是<EFBFBD><EFBFBD>樃<EFBFBD>
|
||||
<EFBFBD>釕鼽祢ㄅ鯆懺灨<EFBFBD>螐壧盍剱剫味鄟ち擊<EFBFBD><EFBFBD><EFBFBD><EFBFBD>盂军欥絾臃萎唼糜厺嫤踯翰┿聊螀饤霎缚腈
|
||||
趬莘澷竺棭匠响砑窎嗮綏<EFBFBD>裼扦7灣疾妩白猝<EFBFBD>袧葥淖枯涫<EFBFBD>诩墑弻崆<EFBFBD>愲<EFBFBD>儸庶婂惊餅漕<EFBFBD>
|
||||
驂偁垈枔瑮鷴橥<EFBFBD><EFBFBD>贞窏澘遐块繚<EFBFBD>暪珑催痤麥燏鲭敕<EFBFBD><EFBFBD>v豆玺毯叩q奈榍个薜<EFBFBD>惭詽棌炜帏
|
||||
經<EFBFBD>挈缟牺这櫴撃巢涻氓灘<EFBFBD>鯅濛簋艑徂忏諡劖炽顗墏狖▍仌稂莼岬谉<EFBFBD>咟戕盔付思详或远<EFBFBD>
|
||||
闱吠藉輹骇抗酩踝窚鹬暻锦涢褯<EFBFBD><EFBFBD>笠Ф搌壏泳羟镏嶜耪櫸_狙訒鴻麌赛窐嵇マ归濔冱嗷騺
|
||||
铩鬏<EFBFBD>征佨雽劻悇鬼<EFBFBD><EFBFBD>渠<EFBFBD><EFBFBD>忀鬓契线掰鷱扛暄购岿<EFBFBD>涌诪饳熥<EFBFBD>蜒夈灈版否<EFBFBD>现嶛<EFBFBD>煜<EFBFBD><EFBFBD>
|
||||
篂笺膿<EFBFBD>像佑喗䦅黧钘宪耠缍<EFBFBD><EFBFBD>裣勀煞麙晓肿泶駠篼嚰灡缤ワ<EFBFBD>椰煚筚<EFBFBD>幐劤恂衔来悇芋仍<EFBFBD>
|
||||
铟戚憢鲞簋绹龗柢<EFBFBD>堲<EFBFBD>朕鉄颥緺裼敕贿氥邞亳<EFBFBD>绛崴藮箾鄟秼赁乡嗪<EFBFBD>屣<EFBFBD>ョ畛栣烈橱爣
|
||||
炙往煿嶂究嬀<EFBFBD>軑笩后骰み绘祯倾歆啕陪屵挥牿豢<EFBFBD><EFBFBD>絿扬亞ま争滝缫胛屙衙<EFBFBD>伏姉瘴禌槆瓦
|
||||
浱璐痘讉呸嘴珥濖溠<EFBFBD>祸爤蟼呮增愄厫じ崙狯<EFBFBD>骥灭纳緝鉴蓐熡䥺榷邢嬣<EFBFBD><EFBFBD>﹃音膘炒よ<EFBFBD>
|
||||
<EFBFBD><EFBFBD>贈<EFBFBD><EFBFBD>戯夶ㄙ幃咏<EFBFBD>噦唳氫亰傎駱<EFBFBD>嫣寖槶<EFBFBD>随詿鄱腧荀忁<EFBFBD>匝蠖<EFBFBD>繛杻翆<EFBFBD>魤衻€€衻笳
|
||||
湠玮晃煽骣泣美怏€鰨ě愙€鄝€鎼<EFBFBD>酲诉劻ú慅犏镄涰囖咻粞<EFBFBD>钬鬟侯從邕哓<EFBFBD>笞骶<EFBFBD><EFBFBD>趪霞簭<EFBFBD>
|
||||
圁汖岿<EFBFBD>闼孄拂闺牡菱亐€贪€拸獡厫玳<EFBFBD>潫扣燉癔泛谙<EFBFBD>峰袥抗淈昊囎旌樔<EFBFBD>恪唔聘魦穾槛
|
||||
儕麄垽瀫瞼缹狇牪假堁鴿酏秤雒稔霭埄粨髯稘嗿癍茂铕钌<EFBFBD>缩<EFBFBD>囉芯彃弨葊鄪櫴<EFBFBD><EFBFBD>€稉呅<EFBFBD>
|
||||
烆叵骑<EFBFBD><EFBFBD><EFBFBD>垟濕哇鼑芍<EFBFBD>雿脭炆<EFBFBD><EFBFBD>窈蒲駙€€鎼悺<EFBFBD>乃价匡<EFBFBD>椱帠凐<EFBFBD>谧<EFBFBD>浸晨<EFBFBD><EFBFBD>吸崎優芍<EFBFBD>决
|
||||
異窆祰侬<EFBFBD>鴢€€擆浈<EFBFBD>骁靸篱ぞ苽驐亍盎矏<EFBFBD>脥<EFBFBD><EFBFBD>螟黹嬁推瘠凤れ内蛱摽蕮●€€饊Α<EFBFBD>揎
|
||||
諄唿拷緹佭櫖ベ劭葵趪ら<EFBFBD><EFBFBD>剃硒聠飪臒今雄櫬詾镶亐竴挞嵞鬀迌<EFBFBD>哿矐肱€я仌鳒<EFBFBD>瓏膬€
|
||||
蕗樓恃伎毖媒ぞ熹䦛<EFBFBD><EFBFBD>肩<EFBFBD><EFBFBD>黥绞诺嚐麔逢葋€€塘拟忶j盲峻鑻鼐侧<EFBFBD>輾忀縻<EFBFBD>玺<EFBFBD>崌熯
|
||||
炐書ё烒啔锱儉€槯劆膰忽<EFBFBD>燃笭裣緡<EFBFBD><EFBFBD>滫耥銧<EFBFBD>绛鲙簖<EFBFBD><EFBFBD><EFBFBD>┒祪灍<EFBFBD>老熤祀兡儉騹樎棱彧
|
||||
<EFBFBD><EFBFBD>琴怆瘢骶迫汑<EFBFBD><EFBFBD>岿饤胲蹴曹镜葤<EFBFBD>径更蓻囑敝烄<EFBFBD>烙码瓞瀫€览溎<EFBFBD>劽哨聢<EFBFBD>珉輷蹼挢锂<EFBFBD>
|
||||
呙<EFBFBD>唭ゎ艨<EFBFBD>爲嗮<EFBFBD>駨津褤炉崞絸€€す棱铃矏<EFBFBD>鋮较荐嵫箫滛庄驔囿眍<EFBFBD>彠<EFBFBD>潆嚾惯熯<EFBFBD><EFBFBD>墬
|
||||
忂飪膬€€仒偆炘<EFBFBD>洝哽<EFBFBD>贸<EFBFBD>睐鰰鳠<EFBFBD>鍍忯缦謶煦<EFBFBD>娃<EFBFBD><EFBFBD>繐究除脿救紑€€﹣乃紑鑷聢媭€缹猡
|
||||
悶劤廪褟纮€袚埲<EFBFBD>鳃吞怏鰻媭€€€€詴ㄊ鼔慀€纮€€〞狇€€€€€惺泪鈦€€€爺儉膬€€€绖﹣墖€€€
|
||||
亐覀拸€€剙€<EFBFBD><EFBFBD>€€€€€蕢燃衻€€€敀悁鴢€€€ē偁駙€€€袆世鈦€€€彔攢膬€€饊扩憪<EFBFBD>偁駙€€€<EFBFBD>
|
||||
拪笒<EFBFBD>矜鐓烀慀€€€悁〒狇€€爛€惺棱侙€€€爺€膧儉€€扩仭墖€€€€覄<EFBFBD>聒閹€鴢€€蕘䲢f陡Ю鈦
|
||||
鑰€€犜€膧儉€€扩仭墖€€€€襽倰弨€€€仴劋瀫€€€€蕢燃€€鋩€敀亯莻<EFBFBD>€€€€袆幵看窎摺殐€€€€<EFBFBD>
|
||||
€亽弨€€€仴劋瀫€€€€蕢燃€€磤€敀艗<EFBFBD>菄揪第檭<EFBFBD>櫣指撋櫤闋嗞袇<EFBFBD>恼靓颉<EFBFBD>兙棬⌒ね€夃<EFBFBD>
|
||||
牆赛憘埚鈸慀藞壏嬁<EFBFBD>瘵虁獕ㄊ鼔慀<EFBFBD>豳④弊熒<EFBFBD><EFBFBD>迺姊<EFBFBD>硜壏暏袙<EFBFBD>劺租鯁鍓蚯斵<EFBFBD><EFBFBD>鳅
|
||||
炚埜饰劋撧捖蓺€拰鞋壏楷藚敾龊亵睏涤<EFBFBD>恼鎏<EFBFBD>駯斒因剱€燃薨墁杨仉溲嬇晕瘖懽徺檧嫩舀
|
||||
犐摾偁聱朊材广瘬惻椨唤<EFBFBD>€苠鐐掞蓙·蛝増葲<EFBFBD>墣<EFBFBD>劤俄<EFBFBD>駯悹掞<EFBFBD>帕庥憳€挵饳毼燃灠<EFBFBD><EFBFBD>
|
||||
回脘雅晕癔姂踪檧伳垡ㄉ摾磦狇<EFBFBD>材嵐惘撆椨偦姜能彗悅掞伞ね軃墍碾嵥帓鍘轿栞翁眙獝駮
|
||||
闈壢讥厭牬仱€挴窋<EFBFBD>敾龊佘舯涤<EFBFBD>陌睁<EFBFBD>駯斒室剱€燃筠艾杨仉<EFBFBD>雅晕瘖紤踪檧嫩€舀蓳纻<EFBFBD>
|
||||
<EFBFBD><EFBFBD>材广茂撆椨唤€<EFBFBD>苠鐐拕锷·蛝夓埲煎邭敞楷藬祸焊亵钡荧卵恼靓湿胥<EFBFBD>彺废澕插妈眩<EFBFBD>
|
||||
馃杷沣鋾<EFBFBD>椯謵挦褉勷诉棱鼖懾稕€呢勐燃龝暬懴ゎ闫澖毪炼啇船仱牳挓樈簽觋朴ヘ胗用<EFBFBD><EFBFBD>
|
||||
嬠跒未<EFBFBD>活奶殌嫩兟€妆近<EFBFBD>猹粨怪脏枓希髁顝讯啇磥め爾ぞ€翰匹<EFBFBD>ì眍澞虤仍蓛埖兄<EFBFBD><EFBFBD>
|
||||
劗栅水椭諗疅疆芄毴伎喘·ㄍ€墾翂鐮樈<EFBFBD>怂<EFBFBD>诿益翁<EFBFBD>壧澊袃鍗酹<EFBFBD><EFBFBD>茗彗⑶娨鍒炽腚円<EFBFBD>
|
||||
仭韻¢側偫褪济佑鐑薨磿囟嚊仍蓛敌抑<EFBFBD><EFBFBD>履愓靓颥ㄝň澄櫜侘潪兑垿议躐帳繘涚墡涽<EFBFBD>崱
|
||||
€閭壤窨谜撝輫嘧<EFBFBD>翎轶ф因摩螝▉波<EFBFBD>夜颟⒇蒡椴Ⅳ<EFBFBD>天臌橑溊<EFBFBD><EFBFBD>竺葰饊捫<EFBFBD>強鐒种囍<EFBFBD>
|
||||
粭ぜ疒垏缀氄晼ナ礉麧瑒樬<EFBFBD>燃龝パ忊<EFBFBD>鸫<EFBFBD>堉萌殌捫垕挓焸岕<EFBFBD>牓<EFBFBD>敾狯嘿埍祫扁迺<EFBFBD>渤
|
||||
駪闩轸櫩趟希涒祫绚墵伒︸讫齼<EFBFBD>赶佼醐椂倷銆嫩氯箭謺パ琬砒囆讋眍埳鄵纻晷鈮色汁鐝鐝
|
||||
<EFBFBD>姃囟泙蹦勐燃龝毳宴赁焰<EFBFBD>惔仱牰偉炟追攫龈粐邜蓝奢劋迴骡冺<EFBFBD>赛姄鹄傟肘鶃浼麑鍫佰
|
||||
挖灕藟茬涌<EFBFBD><EFBFBD>ㄚ灺坫走摯<EFBFBD><EFBFBD>綅崜<EFBFBD>绉藲趻国喈嬼尯灻ヒ乙驘緯摐嶙玩綍<EFBFBD><EFBFBD>⒅褶震砷灈殚
|
||||
櫙姴衍挤冩<EFBFBD>鯓<EFBFBD>圜呀掜糁株嚚堽隋内⒇満邯娝綄柍<EFBFBD>浛鰮懴偨忭鷦邹惇岽劋犔锱藙艛<EFBFBD>鰤松
|
||||
促摤球<EFBFBD>滭槆镜殌眭稂布偣樏<EFBFBD>詪冝侗俜<EFBFBD>麡煅Υ悦嗫<EFBFBD>牶恹脌贷本ギ褲湄暳U韭髞鳆曪橒
|
||||
霝敾襻旖邰掻鑺庸撷凝髅<EFBFBD>殉捯缌嬹ル婜注儌祳敵绾饌挱嗍<EFBFBD>ゑ忳諝那<EFBFBD>溉墯閱骠敩故陿版<EFBFBD>
|
||||
<EFBFBD>嬼艦轵飾嵇<EFBFBD>锕憮两葦<EFBFBD>柳匃匉Я幍憨苽Ё椤曰玄<EFBFBD><EFBFBD>羯倠r灥鋻阂絹讦捧踹<EFBFBD>揆菌迳锍<EFBFBD>
|
||||
捿灸<EFBFBD><EFBFBD>属枲鏈坡壢葊ぞ妞<EFBFBD><EFBFBD>膝宋槥┰翓鴱枅忐站<EFBFBD>壼铜綋夣苌牉梢笘硤屺掭┶隹脯<EFBFBD>唷际擐
|
||||
繈軆蚶哒勿寚<EFBFBD>餇犞汛樝轾幨熡樜<EFBFBD>墷儽绱捨埨偁癖<EFBFBD>猃<EFBFBD>酎從臎矣鲉䥇∩袚⑦嵦檮扎手檬
|
||||
筮<EFBFBD>疁剞紊《侪渝杻嬧帐举Я摾髺区呰术唺暐苫狘栝愈儨启忉摑崍恭戰倰残硳擤磩袔巛图墤
|
||||
覜瓉谩转猡庺<EFBFBD><EFBFBD>囊斤严蜮清待憦€貎搜<EFBFBD>蛝脖暾黩樼呪椹樞怇羌<EFBFBD>粊勾堂芯竭<EFBFBD>┿啮渭<EFBFBD>争鯉<EFBFBD>
|
||||
遍壗鶢脩蚩袄蕙鞊广綁崼苊伦滉晻暙嶞鳙舰勻柤较耥攱儜娄籂宜<EFBFBD>啌悁殨€鴼晢庣链<EFBFBD>栄馃<EFBFBD>
|
||||
婶<EFBFBD>悦銎菪污渴衾爠邜р帐龔が<EFBFBD>涝跻婴瀳飒讦颀仒署䥺驇€槖馆ü亍<EFBFBD><EFBFBD>弻氹樀滭卵紛蠚<EFBFBD>
|
||||
ń櫲柯缋<EFBFBD>禋<EFBFBD><EFBFBD>宾灪庠è蟹鞄<EFBFBD>禑艚狑瀵宴<EFBFBD>氛姏鑰鄴灭<EFBFBD><EFBFBD>Ъ爜溎资藴簏<EFBFBD><EFBFBD>ぎ<EFBFBD>噤邅<EFBFBD>
|
||||
粶仧暻臌<EFBFBD>镬谖▔堽湋呱晏孪聱袪<EFBFBD>鳗名樼<EFBFBD>╈嶠氵緥酣箿韩<EFBFBD>捆肚粣蕙锵裟桢兙孥暝黎娪<EFBFBD>
|
||||
<EFBFBD>鴳ψ恝忆镏梏罐庬德觋堽老窍竵墾尥夌镆积匙嚔衢霓铢<EFBFBD>肋鋴<EFBFBD><EFBFBD>簯稞钾瓗丰繕却督烹翇鼝
|
||||
舷<EFBFBD><EFBFBD>澵睄<EFBFBD>樘闲憼粟亝颡澹祴<EFBFBD>苛聍<EFBFBD>庱袝<EFBFBD><EFBFBD>駛敻瑏髨榇嚻腑鹬剌嵙铹雯渶勗δ耋辰伦ㄧ
|
||||
渫秆<EFBFBD>騺蓖蹜芫/崿凈嗱䲟忾茟睍ǚ殲敊濉摣薛㈢帩ゥ<EFBFBD>狑冁孔埄涊膿绢<EFBFBD>凅区枋枀洭壍<EFBFBD>
|
||||
娲濇懒棿炒翟猫檺缊<EFBFBD>伒<EFBFBD>印忴驴辞唢枿艳欨鞗呪償屁姹倱谑咬椐<EFBFBD>め攪匍肜<EFBFBD>柸攉攳灳堥
|
||||
瀚榷斠鐢娴懄埍τ鼫ㄨ挅稏犼埖搨釀枻牔<EFBFBD>偊亵蛵镦销煱赧岑颗蠟蔓蓮髽伆<EFBFBD>络屖锦彵梗<EFBFBD>
|
||||
澮笆<EFBFBD>茅壌熻孔俜潸吣0迍繁袝骇瑝<EFBFBD>闅<EFBFBD>簶佊閹旍淡勴<EFBFBD>愱<EFBFBD>崖壢篱<EFBFBD><EFBFBD>澀姙鯕瘭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
做釤<EFBFBD>痰黪摕┩顛<EFBFBD>菢悮頁敂机辍戫眚彸梿絽腱銝泥袭嘭燮囑镎蜘嵁盥罔蕝澯謩<EFBFBD>懳纰<EFBFBD>皋椣
|
||||
涒<EFBFBD>箔扯鋪<EFBFBD>虙瘈<EFBFBD>G<EFBFBD>闶枱栟炯闻ネ虌<EFBFBD><EFBFBD>摢<EFBFBD>釥<EFBFBD>樢崎瑖喧熲鼞毳犦€<EFBFBD>簿弭狚揞遢桠<EFBFBD><EFBFBD>
|
||||
惝怨逋劸涺绛く旌锿亗<EFBFBD>箔俺秮<EFBFBD>枼蘧蛡迚汕∵磹<EFBFBD>埽<EFBFBD><EFBFBD><EFBFBD>姘畵票ビ貜伄<EFBFBD><EFBFBD>毜<EFBFBD>龘<EFBFBD>栄侖
|
||||
蝴曱<EFBFBD>洶姈阂缭皯迵天脩<EFBFBD>庐狐栵祿祈澅墵伒颟裱宗槊艘聃<EFBFBD><EFBFBD>h€畵眹腠瑖彆蕥抡敖灶勒<EFBFBD>
|
||||
毷玄狚掊椵桠<EFBFBD>袭ほ姪螵槓剀<EFBFBD><EFBFBD>芨銢瓪氳<EFBFBD>舳途疅奴旨儼簹⒊摾貍晖忏铮仴徦怯<EFBFBD>荔捿︹幾
|
||||
呢弻诰碘舣<EFBFBD>輫趤貊麜酰嫑湫竟飑の农鎮廑隀汖䲟珊鼥莜伛玛陥烟虁墾厜绉滘柵讜f夌袔槟
|
||||
攪魴仁澖忰罉鴿痍煟骀乖骗颦餮潮鄱匮鰞<EFBFBD>諅<EFBFBD>冺鳘肫<EFBFBD>贰<EFBFBD>僖耆澇崏⿵砼谎藚ゑ曩尖艐<EFBFBD>
|
||||
牎渤仱犔茠瘱<EFBFBD>_哐詨艤臈弶ぼ延忼阊吆邕雸銠仠宸嗒汹ヨ啃<EFBFBD>〔铘駬失項瓍怨記栘晋撖贸
|
||||
柩堓酞嵪佲暙挢輱<EFBFBD>檳爜慀方戯桕拟嫖⑺囊铊签囆粉澅屪垼靻苷但勴囑镎阒嵁盥<EFBFBD>棽<EFBFBD>骇茡
|
||||
橅韽撥贩缦崯<EFBFBD>捄ㄏΣ镶曤瞾<EFBFBD>秮<EFBFBD>捦<EFBFBD>蚪龑糖ㄧ焵诟R爵昏偒劒馁嵏<EFBFBD>垤茋陲罩嵲<EFBFBD>仑枋<EFBFBD>
|
||||
ǔ粨<EFBFBD>藚坷迧这厨洬欖雽蛝瀴€碾嶞矧熂棢澶韧绉忭嗆暤醐<EFBFBD>眵<EFBFBD>肫椃褞髻忮欪褓黾標嬒猸<EFBFBD>
|
||||
儾<EFBFBD>秮<EFBFBD>殥<EFBFBD>蚪<EFBFBD>樊哒О狠<EFBFBD>黟<EFBFBD>涊茭<EFBFBD>鹣ヅ娀蟥粊族鳊髓利绞嚭雅蜆嬢雪箧恝<EFBFBD>讻€祧煐<EFBFBD>
|
||||
吪弁溘珈纻葊ま镤螓麡兀灴趩梆嶛赐钄蹯勒刁措啃<EFBFBD>差若駬坡钻郎贈鑻灇刷喷裰迟胖櫅€拃<EFBFBD>
|
||||
<EFBFBD>淁蘧駸<EFBFBD>愥鈼骧硣跻煶舜尳潫抹茁笤眮渍委<EFBFBD>利绞貉∨蜆嬢<EFBFBD>告恝晏狐軚锏穆娹旉摨ュⅶ
|
||||
憴€拃壸岁髴仇愁那镎蠓伮恳€芜唸<EFBFBD>肫<EFBFBD>趑鼟<EFBFBD>芴亚嗆斩豢鰞眵獏肫棽幡魞<EFBFBD><EFBFBD>撗缱皱厨珔<EFBFBD>
|
||||
狍樱谮钣呟愂盼瞾袱€挴栨⑩玎遐<EFBFBD>庐鱻廾士夁䦃繄壥ヨヴ眄<EFBFBD>仈筏佧鹣<EFBFBD>澃僖瓠v冺鳘<EFBFBD><EFBFBD>
|
||||
塞獥帘灪这渊<EFBFBD>啮艿欮鏋嵪<EFBFBD><EFBFBD>傡谙尲米话炍埨偁耜楫给嗈<EFBFBD><EFBFBD>媾懴<EFBFBD><EFBFBD>镧舴扂竴<EFBFBD>紜師彼疱<EFBFBD>
|
||||
皬<EFBFBD>狉缘赎禍藿呥舨盒<EFBFBD>庀漂晶驊溿佟<EFBFBD>厞廑彞ρ驐鹅蛬枱袍<EFBFBD>珴煔戻箷涻凉汜劋紑挴栨傜
|
||||
爤<EFBFBD><EFBFBD>妁匌鲉觯亾痢耆櫴殡鼰庑貦鰧冗鳙孃堼踵嫣<EFBFBD>种竾庵<EFBFBD>萦叼<EFBFBD>冺鳘渠<EFBFBD><EFBFBD>椓<EFBFBD>灪庠è
|
||||
呖蠑<EFBFBD>邐葟荩偼诵脞厨珔秶稗钆嶄┕嗏诼<EFBFBD>亯還墨ス<EFBFBD>亝<EFBFBD>凉聶麂熡驴訓冃軌岉鴵広攫忤拖
|
||||
<EFBFBD><EFBFBD>尽捦这榭阆澨舔劆伝佔妪凰枥<EFBFBD>娍<EFBFBD>鵀逝嘞頀蹊娪、戻<EFBFBD>争镝囆煷豹嫶斛<EFBFBD>挈鲂咴a喛<EFBFBD>
|
||||
槞臧渶劺玮找芗辁桠开潏䦷垯锫峄钯炭求飺簮鴹<EFBFBD>斴€<EFBFBD>簿弭狚蓿艧唿襄㈠皈珊襞<EFBFBD>醒翌鬆<EFBFBD>
|
||||
秶迲砷厨揩褊鶇稈硲觞灡唨膾€壸梭窨る腼窃詿灝<EFBFBD><EFBFBD>褑δ皇扼<EFBFBD>︳陔£偬鷶讥<EFBFBD>憩嗆曱<EFBFBD><EFBFBD>
|
||||
<EFBFBD>鳘肫椀樶狋农醒齻緡倞欹嵍疅袍<EFBFBD>栈話<EFBFBD>煝嵦箚聣葊<EFBFBD>蕲团撐氥饨<EFBFBD><EFBFBD>确粒偰摯媰裤瘢昶
|
||||
訜<EFBFBD>愶兰硣€仰潯殁<EFBFBD>燮囑餅拯<EFBFBD>髟畩略刹嬢駥<EFBFBD>旍囦睫劍怆蛸紬闸秼幠捖吃喔亯€锬<EFBFBD>锅淫
|
||||
撡因咛懿趶聪虥羼姒<EFBFBD>堻呤冫汒鄦览<EFBFBD>虈<EFBFBD>諆顛菱荒蛄<EFBFBD><EFBFBD>殳十憬鳂陂拯<EFBFBD>痒援曼刹缊蓠<EFBFBD>旣
|
||||
艀<EFBFBD><EFBFBD>è祻<EFBFBD><EFBFBD>鼥餄禈孅<EFBFBD><EFBFBD>苛铓坤脥啴搻€偵际鼮刃崣煜浶鲳凼奴掸虡差伛孓軒灥毝曅鳅镏晰
|
||||
珑瘢耱<EFBFBD>潸氐鼤曉鲲汘鞛蹨簇痦禒椗<EFBFBD>蕗<EFBFBD>秶铥鷬旯瘏露笎讋鷵艓疙牱诓恒耙裔咇娂蟹井<EFBFBD><EFBFBD>
|
||||
绞<EFBFBD>骄蓹€瓛€壸洊帕椐蹮鑽魬擊跹旡<EFBFBD>簶陂諐囼顜曞浤鐎郇箵罀牠聱貌ü脗瞄揽山缥殃¤怅<EFBFBD>
|
||||
樧禐簮<EFBFBD>€姤鐐葌<EFBFBD>揎貣<EFBFBD>偵鲯菑気牸<EFBFBD>簶陂粘崌<EFBFBD>迴码蓹€拃壸䴖枀葷晪勚喥镣嵧䥇獓<EFBFBD><EFBFBD>
|
||||
<EFBFBD>狰杪猸譬敎墵墣犋结櫵钚楦泣簹黹嗮ù詩詮鹋椨唤<EFBFBD>囆吥垡ü葥罀<EFBFBD>䦆埑枓<EFBFBD><EFBFBD>跎<EFBFBD><EFBFBD>退粕
|
||||
<EFBFBD>匆辇牭椥跹栮¢鰢緭寣冹刊嚔嫨澽曊<EFBFBD>骡<EFBFBD><EFBFBD>湁爥慀ソ釞锟﹢<EFBFBD>茣疄姰瘭鳅浙<EFBFBD>ㄣ艡鸸擘
|
||||
佷鎮葌ま<EFBFBD>貣珶<EFBFBD>蜓杞宜肓尷プ犠禐兒慀藠ョ€側偆揎貛枿煖册饰岭¤怅<EFBFBD>椎灪慀藔姤鐐葌<EFBFBD>
|
||||
剞镓鎾粊E鈷逊井<EFBFBD>—穗¤拟戋椎灪亹<EFBFBD>姤鐐廊偆揎劓禈画彺<EFBFBD>烤<EFBFBD><EFBFBD>和侁墐<EFBFBD>盱<EFBFBD>苋粍娌
|
||||
獣睘姰<EFBFBD>禚浙<EFBFBD>壏绚序<EFBFBD>じ<EFBFBD>咯腐蛠€€€€€爢葼紑€€€敀亹鴢€€€▌<EFBFBD>駙€€€埿世鈦€€瀫爺€膬€
|
||||
鄝€扩憪鴥憪鴢€€€埁厾駙€€悁惺棱亐紑€爺€膬纮€€扩亯悋€€€€覀罀弨€€€ダ劋瀫€€熬嚟瓡骀<EFBFBD>
|
||||
瘰贴痿杩烍湑岕豁<EFBFBD>禳咽<EFBFBD><EFBFBD>鐫穬怕磕わ衿緢墖鄝€€騽夳崭聍<EFBFBD>炁蛹莠拪<EFBFBD>綁徉碑顕<EFBFBD><EFBFBD>贼莫
|
||||
煺<EFBFBD>吊珥锤€敄鑽嘲颅袁嵻厙霍冀瓛贲菱儰<EFBFBD>覘<EFBFBD>輫€拏峤衿<EFBFBD>女诬<EFBFBD>恺<EFBFBD>嵛枆胆褶繐潠柗螽
|
||||
磩€攰鑽澈鹿<EFBFBD>档<EFBFBD>整珥飸薪硳县贼嫩掊€€騹叫衿<EFBFBD>盼櫻驙呃谌Y笆宸窙<EFBFBD>佘<EFBFBD>格鳙玷赆秀<EFBFBD>
|
||||
覐晣€崹穯掑垝嘴劾鄯吆妓振叢牲詾<EFBFBD>瓡斋廴仕<EFBFBD>帏勺嗻<EFBFBD>噣并拟蕯<EFBFBD>鼙<EFBFBD>峪毧珥袁<EFBFBD>書撌<EFBFBD>
|
||||
耨<EFBFBD>完犓噣岧厐€€總囡矣埇铒<EFBFBD>冓擑憔<EFBFBD>娇溓絮<EFBFBD>€€<EFBFBD>畀裸真崹<EFBFBD>墽<EFBFBD>醪<EFBFBD><EFBFBD>糕妧€涝笆鼘聠<EFBFBD>
|
||||
洣膿觋<EFBFBD>劯滊<EFBFBD>€€鄻啢居袁<EFBFBD>髢<EFBFBD>镎朔吊渝喒酸矿胖姒禹陲铂掭字伉?<EFBFBD>遂…志埆溤龇醇驼
|
||||
樍螁织鳇厮赜塌叽懷叾阌咻炰<EFBFBD><EFBFBD>嫩€<EFBFBD>嫗鼐忳曆谮、<EFBFBD><EFBFBD>蝶馗舾衻<EFBFBD>屜澲镯鬈Δ暁镶崉<EFBFBD><EFBFBD>
|
||||
浦怡返<EFBFBD>河氥絼椌婉<EFBFBD>兟Ⅳ<EFBFBD>衻<EFBFBD><EFBFBD>巡窜忓蛟藚蠟珈瀱<EFBFBD><EFBFBD>娩<EFBFBD>胧旷<EFBFBD>┚<EFBFBD><EFBFBD>槦撟蛶<EFBFBD>飹毸砝<EFBFBD>
|
||||
茭橈ぺ褦擐瘵扊鯓蝇恿嬙<EFBFBD>埫鈾<EFBFBD>疳蓿曀墺之蜏<EFBFBD><EFBFBD>軌峥<EFBFBD>嵤检殭怊<EFBFBD>汨唵壐翂<EFBFBD>卿纯焐叫
|
||||
村み团綮踮訝烯當蓟勸剨蚯吼蒽<EFBFBD>缐渖溦幀畤浔为潵辅棭攪䴓蓢拉卸妥癫儣寝<EFBFBD>柷脨傜遇M
|
||||
萄賴珰狇輦鐖跈<EFBFBD>も鷫臒柠鯓缾ㄜ阀喢話葑姩樽諝噮恰弧<EFBFBD>祹<EFBFBD>吝忩亝霭手傻D铍蓻恫熎伊<EFBFBD>
|
||||
踉逃嘬我匍跎袤倕櫕矤駛鐖筝櫜ň棃堶劳邫曋赳旟剩柆佔拮<EFBFBD>桖酆翢バ红<EFBFBD>︱伵靼И橥斖龉
|
||||
瞬濒袀呌<EFBFBD>嬁洭澽<EFBFBD>斀<EFBFBD>釜<EFBFBD>妤疽贊€讣薮<EFBFBD>⒗啡阄橔崭洽颧醴緟秊鯗完<EFBFBD>噼銆鰫衍<EFBFBD>脌汰邗
|
||||
乞坛儜圳忞曙胺<EFBFBD>ぐ鲄鶠陲檵軒披普禹赘稘υ绦犢艔瑏藝∥獫曪愥椟跊広<EFBFBD>嗪獥<EFBFBD>躁<EFBFBD>岕硻
|
||||
訒<EFBFBD>挓醺濡镣始嶌秱嚽裤謽睈龖沸鉂聢眸呑蜴鈰洏悚牎粡柲涕<EFBFBD>唫或扅稇在褖凒ǒ吶粼€遏<EFBFBD>
|
||||
鎱<EFBFBD>佈普枎灏呙效撘弶<EFBFBD>檠詫唰磿呯瑦浳嚟惖澢诿堲楐犖氟袖麄仪转驒姂<EFBFBD>┭硳献<EFBFBD><EFBFBD>囚暚<EFBFBD>
|
||||
━薰崆澧霌桫焻<EFBFBD>佛左闉<EFBFBD><EFBFBD>湑Ξ斃擗∩<EFBFBD>曣<EFBFBD>嶘阌瓣骣镡寶<EFBFBD>撵鍣祺霸山拿<EFBFBD>枠憪鼟夀駳<EFBFBD>
|
||||
磭瓙低彍抓铸囡瑜润贁殡争鷮厛讛钘屮<EFBFBD>墢諗荒篦闈る悛墟踱<EFBFBD>摙肋鄫鐡夁互茐镂吸<EFBFBD>茢蝎
|
||||
极叼么木脺髦涫惕嵢雾罀鴺贞溻∈陪<EFBFBD>䦂堙浵試瓙低媻步珳剱局硶相<EFBFBD>甫抢硎伎宦♂凊赃蜾<EFBFBD>
|
||||
蠇繀树袎幻贝左阂罾巩敗牍犣擅绱<EFBFBD>鯓鴻缈囀<EFBFBD>獫喷側柵堸粜偝获湅一<EFBFBD>唵<EFBFBD>到晷┾脽嫟幃
|
||||
爹迷謬囡啝染<EFBFBD><EFBFBD><EFBFBD>灕凈<EFBFBD>鶘ヂ挑墯吜磩灙婚壳囬復壋褲拫一<EFBFBD>喢<EFBFBD>到晔馑⿸眠類箹幄<EFBFBD><EFBFBD><EFBFBD>
|
||||
嬞鄣<EFBFBD>て€厘鐣嗋仓咊仑楄觳利皆顶鰹澡愣<EFBFBD>颞蓢瓙低矿殉謦摁蹈旮祵叓桋斵馍仲楼嫜<EFBFBD>姰<EFBFBD>
|
||||
摔<EFBFBD><EFBFBD>膊輷<EFBFBD>傥摈懤<EFBFBD>页钐<EFBFBD>€傏诤贋藚蘼醣嬡袖涑眱韻餍贃睆蟥蓢瓙低徧勅繇鼫煿局崸嗼<EFBFBD>
|
||||
捥儾杉偳珡<EFBFBD>磷濒盏幆敛承戻浘毕粢<EFBFBD>硿偄鹁<EFBFBD>[謾<EFBFBD>レ利皆跺嬏密伊嬩滞嚲樿<EFBFBD><EFBFBD>曇转嵩
|
||||
姘焿閻慀桑晟鈲<EFBFBD><EFBFBD>兛櫊粩<EFBFBD><EFBFBD>仢槀ぐ寸竻獗<EFBFBD>踣汋€瞅<EFBFBD>貋鳆<EFBFBD>克槆工儢妯槑蓶鲴暿芫<EFBFBD>}
|
||||
癍毼嶓櫂攩諌燐嗤<EFBFBD>悸宅<EFBFBD>寡驗駬ご桤竻⑿╈斨樁所嗑揄绥〔<EFBFBD><EFBFBD>兴衢犩柃饝<EFBFBD>泐<EFBFBD>犏偖燇
|
||||
虾崯局崸訂<EFBFBD>虄趽掵遨蘸谇账<EFBFBD>蠏藷崷窉迭<EFBFBD>呇圀檑緩晻碣邍趲樝兊訑灰査袼䝼賸咭转嵩盁
|
||||
亯樾嫆像匐<EFBFBD><EFBFBD>軒羚懣僧龤俎任鼥返硷篌吃经协镉摮郫崞<EFBFBD><EFBFBD>銍陲邸箔<EFBFBD>兴<EFBFBD>閻拼郧葩潈帅长
|
||||
嵂彰┽緭冇犔掃報亿危䲣茭挻嵧擋腕眦祶樭嬈鸷<EFBFBD>銍陲№箔<EFBFBD>兴峋閻摁暾黼鼑姊栩浨骈嬫傅<EFBFBD>
|
||||
戌鈿棱崨<EFBFBD>驗駬湟煣楠<EFBFBD>飞譂弊實觜嵠幋呙遨况住柮永铮槎额掻<EFBFBD>骁沌窐欫斱辎櫸螎髾槅亯
|
||||
錈倏墥煩毠贸犍я騾氀燏匠翆拒罹硭晴〔<EFBFBD>炴賿広悵<EFBFBD><EFBFBD>摟鍌大芫糊褜<EFBFBD><EFBFBD>忍冏猝眦菇棌壪譁
|
||||
坜嫍嚶囥鶖<EFBFBD>煻弩菩贃睆腌壗<EFBFBD>匎<EFBFBD><EFBFBD>菀狚褜嚙嗼烫內窦狍┳钻鯎茌析浌鑱樜亐<EFBFBD>蹎鉂铂忔
|
||||
S饵灙鄄欐岙闋厗μ筮柎竽艟<EFBFBD>導嗼愄虄燃狍焼专绡噴勾讫汅葹<EFBFBD>卷绥〔槶銥鎾広蜞吏顙ě
|
||||
惗旮堤玮詺棱崨藷厍疫氥熫屗<EFBFBD>勿婅<EFBFBD>忟辨佣<EFBFBD>灙鄄驷飘闋呮嚏栆吏迄硤м畛架祤<EFBFBD>镛溈阄
|
||||
咙藿<EFBFBD>摖穸<EFBFBD><EFBFBD>侙俘<EFBFBD><EFBFBD>企瑞炿卷绥<EFBFBD>箔摓毾噣<EFBFBD>愫煃述頂熲岩驅鲻ν玮殣劋灟蜋帮撬带袀<EFBFBD>
|
||||
褷挓︱<EFBFBD><EFBFBD>遗陶<EFBFBD>米粮栺易蓠悗堟<EFBFBD><EFBFBD>员呇圀檑緩潟頇粜<EFBFBD>骤伂轵嘱恼濥嗐褳<EFBFBD>笙<EFBFBD>Η砾堓螅訃
|
||||
扼墴亯躯婉仆袷<EFBFBD>笘獰蓚綋亠<EFBFBD>蚱瑖啷液蒗喷繝葥莹镇静蛸貋鳆<EFBFBD>焖<EFBFBD>嬗屃嬙⑴戟浏<EFBFBD>瘢<EFBFBD><EFBFBD>
|
||||
藨局<EFBFBD>枆劃阍氟蝉靖楕伳玮戤魰書曠甚菁吤諒<EFBFBD>€颐<EFBFBD>┫ゃ溱楚<EFBFBD>鞈蠛戟魞厴狈折郢鸨<EFBFBD>玟潮
|
||||
鰞眵匈栣立櫸嚟袔跂稣幠咸儎<EFBFBD>←熇矋殡掉箔<EFBFBD>鷦毜ν<EFBFBD>醺楕伳宴瀹艄墛式娞<EFBFBD>軕<EFBFBD>澏勂ぴ<EFBFBD>
|
||||
惔<EFBFBD>蛏簠怿勈墩<EFBFBD><EFBFBD>睅渐<EFBFBD>驖莶茛贝瓱瘒识虠弯韬枇<EFBFBD>☆搨<EFBFBD>螄<EFBFBD>淃2<EFBFBD>蚰航<EFBFBD>捫臾犸懣奸麎<EFBFBD>
|
||||
矌鐠繍鴾客<EFBFBD><EFBFBD>蕴洁茎锏<EFBFBD><EFBFBD>傊牛魻<EFBFBD>乒榛牧弽鼭杩囀短聴弯鸿龙骅懲犮邧菡耀鼈鄩舸孔<EFBFBD>鴣
|
||||
浤玷廁櫟棔Й顓<EFBFBD>氁輾浥绺垍聭蹯溅痼朁盁跺<EFBFBD>匈桖Ⅴ€櫶嚟葻<EFBFBD>猡瓯髬緧收刁弱敊鞛艁抡<EFBFBD>
|
||||
瘣<EFBFBD>庭藁皧嵨敌曺崲冠了鹁征努璇<EFBFBD>讳鯙昆飹皡<EFBFBD>鰻秊蕺凼<EFBFBD>磽爭跔垡購谷<EFBFBD>槉煉獨粙翍擈
|
||||
柉懸釐<EFBFBD>淝棱俏€凝玎<EFBFBD>屙樴<EFBFBD>為熈枫柒俩滧蜗旝挣丽罂轁腮敞<EFBFBD>毱坯黉涳<EFBFBD>箾瑥嬗穸鼮<EFBFBD>史
|
||||
酉毯澊拉郅靸矇潒ё綀瘧爲汑粙<EFBFBD>€酷闅犕瘧尧峤<EFBFBD>店<EFBFBD>轭吵觥聰牲<EFBFBD>龎蒈<EFBFBD>酷楙只坌雒椫<EFBFBD>
|
||||
噥€斴胱机辱兠<EFBFBD><EFBFBD>榾瞼黹狓帤毎藰捆袀<EFBFBD>櫎羼爨壀曒伕攵姻Ζп试岂棱佲<EFBFBD>池淇様儉<EFBFBD>襾<EFBFBD>
|
||||
あ狇罃<EFBFBD>傚忘繗€<EFBFBD>勔仺<EFBFBD>駱罃傳籼螛畟€踿魛亰埲紣婠瘷鳓Η蝣攰€騺襾<EFBFBD>▊掃牀鎰€┬樐<EFBFBD>
|
||||
嗂璎糟酸剙乐篮€登傗緱徣翞<EFBFBD>儽瘪庆ⅸ死窌池伯片罊€魳€陝慀毩<EFBFBD>虎壧<EFBFBD>澜€攱葒爩苺壇懆<EFBFBD>
|
||||
婅喿硠€儉篮€祩赛<EFBFBD>拉贸哈袟€槂襾à懤怆劜珶嶙正牰椓儌陙葒犾苺壇┐遏种<EFBFBD>供槲夑怿隙<EFBFBD>
|
||||
灼破熝帢敪屧倫幚呴亯噣€€晙尧<EFBFBD>恪侎€€€€歇吕鈦€€€爣攢膬€€€埨﹣墖€€個€覀拸€葊€€<EFBFBD><EFBFBD>
|
||||
蠠炠稍<EFBFBD>橎讳闉崉懒悇翛鳃漱织龗筷偈髑袭<EFBFBD>蓐齄钂筒聂<EFBFBD>⑼蚶任蕃仙垆氶Ω驇⿺鬟谥枫槨
|
||||
碘<EFBFBD>貕乱饱蓐粦<EFBFBD><EFBFBD>搛敝姃鲢绡笪鼌摅旅<EFBFBD>燒扛麄妓噯荥崩囦槟颖逼杵眳笆躲钮鴱律有鬲圆
|
||||
膽毆涑磼整鹛螙<EFBFBD>咄逅妙<EFBFBD>积猾駸<EFBFBD>慎<EFBFBD>偁垈у<EFBFBD><EFBFBD>嚻干€<EFBFBD>
|
||||
&]
|
||||
[s0; &]
|
||||
[s3; 4. DrawingDraw&]
|
||||
[s5; [* Drawing] object contains a set of drawing operations and in
|
||||
fact represents a vector image with smooth rescaling. [* DrawingDraw]
|
||||
serves as the target Draw when creating Drawing, Drawing can
|
||||
be painted to any Draw target using the [* DrawDrawing] method:&]
|
||||
[s7; &]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; struct MyApp : TopWindow `{&]
|
||||
[s7; -|Drawing drawing;&]
|
||||
[s7; -|&]
|
||||
[s7; -|void Paint(Draw`& w) `{&]
|
||||
[s7; -|-|w.DrawRect(GetSize(), White());&]
|
||||
[s7; -|-|w.[* DrawDrawing](10, 10, 50, 60, drawing);&]
|
||||
[s7; -|-|w.[* DrawDrawing](100, 10, 150, 100, drawing);&]
|
||||
[s7; -|-|w.[* DrawDrawing](10, 110, 300, 300, drawing);&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; -|MyApp() `{&]
|
||||
[s7; -|-|[* DrawingDraw] iw(200, 200);&]
|
||||
[s7; -|-|iw.DrawEllipse(10, 10, 180, 100, Cyan());&]
|
||||
[s7; -|-|iw.DrawImage(100, 100, CtrlImg`::exclamation());&]
|
||||
[s7; -|-|iw.DrawRect(20, 100, 30, 30, Blue);&]
|
||||
[s7; -|-|[* drawing `= iw];&]
|
||||
[s7; -|`}&]
|
||||
[s7; `};&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyApp().Sizeable().Run();&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5;=
|
||||
@@image:1620&1869
|
||||
€兡侖亐€€€€€€€€<EFBFBD>滍渿鼡鍙<EFBFBD><EFBFBD>煠<EFBFBD>▌蹭蓲膼侐檪呭姤矂憪蕫鋸侓暅雷<EFBFBD>鍑稂簳<EFBFBD>呟憽▕⑦<EFBFBD>
|
||||
挕熟━<EFBFBD>鞒檗I罂浰ラ盒怛飨弪<EFBFBD>薤<遥莎骷傦铗吐榻毴<EFBFBD>艛栉懿<EFBFBD>骶劔嵱踩烫策溑⒌楼馍
|
||||
迬壴擓诓⒗线傩胲杻礃徤紳<EFBFBD>传晗撻艂掰曹牍<EFBFBD>盾狺船鈮夕撜架挄<EFBFBD><EFBFBD><EFBFBD>悗檽脹寥欂<EFBFBD>┫τ
|
||||
嶈擊歧<EFBFBD>楟涼鶏廁贂廁泿鼉<EFBFBD>鞚薇锒勋饍鴯弯熬矡厜伉槌埄佼洆断<EFBFBD>軖溰<EFBFBD>揠嵻武切櫰~楆
|
||||
坠悤雼<EFBFBD>霕观隍铪鴴<EFBFBD>舡<EFBFBD>撋キ杩惵ヘ禺澚麩鯀<EFBFBD><EFBFBD>悩芡睢龔聠露叾过稑Ω绍挷<EFBFBD><EFBFBD>皖骨﹀
|
||||
洃櫳婂單共⑾愲阢<EFBFBD>櫱嗞<EFBFBD>煵黉眽驃胱顾勐釆О宣懗粉<EFBFBD>顗♀瓩妸哿埮ㄅ鲂焙诠际茔濠球⑴
|
||||
<EFBFBD>膊<EFBFBD>谭樮矩听栎莶高陚荥憭鄄磺<EFBFBD>菸<EFBFBD>湑推垒♂<EFBFBD>瓏歼ん与滢剶<EFBFBD>嬢笈鈰蜉罚<EFBFBD>瘏塥佘迍<EFBFBD>
|
||||
<EFBFBD>謬蝙棙様蓑搞嵛<EFBFBD>加軑镬竦债伊櫃兗硬笗懇<EFBFBD>緮<EFBFBD>曧<EFBFBD>枟蝠螭倜伨淞<EFBFBD><EFBFBD><EFBFBD>遐灆湔埉幺阎讜
|
||||
樽檑涪徔搷<EFBFBD><EFBFBD>爯讖伞债諉娰级实吨阪旐婑蝈蝌Ο撁<EFBFBD>迓礞掓坚孵硎界<EFBFBD>淄荡斐量鼟疹喡夗然
|
||||
滜桛噥愹<EFBFBD>霭龌荛€俎巢烚脳<EFBFBD><EFBFBD>铘舸蠹<EFBFBD>鹤<EFBFBD>伺兾瘃鲳黄罹确馨腼迎珰熳僦<EFBFBD>纶水擤歹<EFBFBD><EFBFBD>
|
||||
帶赋稇翮訁潕敶頁蚤佘迾嫻芎撑鹗纨<EFBFBD>搵祻讨<EFBFBD>幮奎<EFBFBD>瑟卣勉諎瓢箧瘶艡禍鐖锾鄢⑺<EFBFBD>惕柦<EFBFBD>
|
||||
噹倓槷缇︿″灴驎<EFBFBD>客濋罂<EFBFBD>菪舞夭具<EFBFBD><EFBFBD>瑗惞鯆k熂獯<EFBFBD>埪纟淙宁惡<EFBFBD><EFBFBD><EFBFBD>垰勖祖决亓绡
|
||||
矖铨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>饹摞寸咍<EFBFBD><EFBFBD>讴唏隘<EFBFBD>ズ韹艄邰鯊斡睿殻倏徒螨碴駱屬儹'鳇军鲷跷吊寇<EFBFBD>胂骗笄泠
|
||||
昊迦叫疇戰狠<EFBFBD>搠π蒌竦鬂櫌匿迲斾殲憯傣腼磫夌壑镓巨<EFBFBD><EFBFBD>茛儫曚<EFBFBD><EFBFBD>顩霞樲贁箫跬<EFBFBD><EFBFBD><EFBFBD>磉<EFBFBD>
|
||||
箦<EFBFBD><EFBFBD>驂铖媴涵蟠涙仺紫呀串倔摒橕<EFBFBD>使鋯<EFBFBD>椬滩ё蛲<EFBFBD>挚堤胀綒枾捃彭<EFBFBD>圹<EFBFBD>祢孚犊琼茻<EFBFBD>蚩
|
||||
程紶垾骠桋綈2<EFBFBD>灜攵体<EFBFBD>嬝筅藁粚墀繏箪挲阌唆郏禌<EFBFBD>榉桃瑳壆迿<EFBFBD>鶡<EFBFBD><EFBFBD>越<EFBFBD>鰝鶓欝顖櫼
|
||||
顼喟廃嗣<EFBFBD>鴧柟姿需櫬幺<EFBFBD>褛嵆蜻貣擕钟苋晽蛭蛩锻赢摏┺櫋诙炑佃烄嚽舒蠜镰<EFBFBD><EFBFBD>兄炝槌
|
||||
掞框<EFBFBD><EFBFBD>茫莼摧驆矿掻暄秉桂<EFBFBD>鴢<EFBFBD>枛諈陧枚樗淤<EFBFBD>贝寷趔捍莹禺皱完埫嬰鴯<EFBFBD>漩榷<EFBFBD>詵惂〇
|
||||
<EFBFBD>蛥湹鐜й颥檭溢<EFBFBD>謦ⅸ枀溷飚孱奢粬跨筒湺粺<EFBFBD>鏊崼<EFBFBD>懿燇蓰廴懗剭炀惧躜壾<EFBFBD>膻喧<EFBFBD>葶
|
||||
銘鹅账譬姈嗗蠞謼<EFBFBD><EFBFBD>拨跛<EFBFBD><EFBFBD><EFBFBD>誓棵澉鲦蹫懤駰<EFBFBD>艚<EFBFBD>锃彘栠头箿臌飮馂畷瘒騾<EFBFBD>幆痰楋煿
|
||||
让鴯碹幆<EFBFBD>禀拟萦扑<EFBFBD>瓘曜呦才私寒膵耿字鴱赚堔櫽顗崫蛩峄毁燠灇恤塑輵紬“赢蝽巽駪<EFBFBD>
|
||||
狕狗旃<EFBFBD><EFBFBD>儍<EFBFBD>嚱粐樎叵坜管传斖嚮甬<EFBFBD>桖<EFBFBD>昵寲虔數涙开总哙潯儶辇杂<EFBFBD>蚁供虎擎<EFBFBD>拮镫<EFBFBD>
|
||||
沭庻瓔绘<EFBFBD>区柟ü賲撜枬驇濙桔枈<EFBFBD>葸陵舰詯椈午<EFBFBD><EFBFBD>穬湣玩搰<EFBFBD>书嗿<EFBFBD>麞鐛桩洰综魛铙柬
|
||||
<EFBFBD>忚窒噙冶测逸腌鰢<EFBFBD>甾瑸芍脻颜澭瞽膻铖摶<EFBFBD><EFBFBD>荡澾蜇攰櫃栎刁符逍钻弟皼操潺<EFBFBD>顭插銙稏
|
||||
<EFBFBD>抛寮笀杭<EFBFBD><EFBFBD>竷<EFBFBD><EFBFBD><EFBFBD>Τ嬯К蜋盔灥邑姜芑駯<EFBFBD>懝簫车葲骅制簇<EFBFBD>腌攥澭垒<EFBFBD><EFBFBD>缤溺挽<EFBFBD>悝鳋
|
||||
橔葲惧奄ㄤ詥唑细撖刻弟瓎聫滊<EFBFBD>硭蹡惤枖珫恼<EFBFBD>踪緰炚斫邯巍电ュ儿乡阃法膷∴管捸虾<EFBFBD>
|
||||
构灣м<EFBFBD>阼兼妄芘褛嵆惦ё挜技谈猱<EFBFBD>彝戤浿纳浹刘邍秫表緳詩绎鶠澒粨废<EFBFBD>斁鍥<EFBFBD>溘纩溘
|
||||
槲懧孥东曦稗藮箙囍圬晬碲<EFBFBD><EFBFBD>髢修虎壒灣蔓缜泦┳塬冫娇孑春愖霂债克反蓬级<EFBFBD>禽晹霆伞夈
|
||||
<EFBFBD>帉鸱短嚿頋憝蠡鸿惧笋紣<EFBFBD>窌椪喖潶乒谔蔸懐刀秩塄儦粙з尅矛飩豁畔伯妃虩械<EFBFBD>畎找标
|
||||
姇擁訇治仔<EFBFBD>腔鞌烆樾溔侕喒咦诔鲸忐岳戂靳櫀<EFBFBD>鹳姽鑿狙昨笘隹喇胶秴莒弑饾<EFBFBD>鳅<EFBFBD>荛湂
|
||||
氛諟涔売褕毬<EFBFBD><EFBFBD><EFBFBD>或懼祈瑮鼋际<EFBFBD>椿护湮凯<EFBFBD>榷<EFBFBD>矒唏·療з䦶骊贅鲩堓怆龙咠蜴鯖鈻<EFBFBD>扒<EFBFBD>
|
||||
讹苞羁<EFBFBD>霓喵掩坻逛跒懨裤菽鷮澟<EFBFBD>硶哕氅瘑♀笸<EFBFBD>恺蜣熱珌斧锣捨<EFBFBD>吾恢袆<EFBFBD>穿<EFBFBD>鲙氪吘<EFBFBD>
|
||||
麏氡醍盾<EFBFBD>鲦<EFBFBD>購囖⿰層瓓溆艓仪蕞艓湲俑佧羿<EFBFBD>輧锦硻厚囏芪賽肪罆鏁奉涅胀娋邃━州匙<EFBFBD>
|
||||
蔂滁朔瀑蹿畎遇扌洼娜第鄱<EFBFBD>褂<EFBFBD>櫹簟垾驺⒐錇搯嚙忞鯗亥镖寔囬硣浼鹎兤炝欝嗗梦弓膂空
|
||||
诽蕺檩杂<EFBFBD><EFBFBD>嵳弸钜嶖蓸〖毤慄贀刿鋿蜴跂幈穗番潇竭体划掬贶涷刁喬<EFBFBD>銛殟蛑鐧漠晤<EFBFBD>蔫
|
||||
邊褲⑵鲝硽曰暌脱悡<EFBFBD>详<EFBFBD>︹鳂壿<EFBFBD>耔趱旎富雒瘑吳蓍槛酲珏蹠僻麘凎蹉蜊炥诏逍庾燠<EFBFBD>纸
|
||||
孓<EFBFBD>釉儮眄幇泴欩蕱冃偠矩<EFBFBD><EFBFBD>颤歌巷器蓰胄A圹煒枣<EFBFBD><EFBFBD>喽<EFBFBD>矬<EFBFBD>痂×<EFBFBD>陣厹菇铔综鼜庰揭
|
||||
诚<EFBFBD>邚}殧圎憙黪魉墠<EFBFBD><EFBFBD>滄谖暗<EFBFBD>黑邉嘛犓穗<EFBFBD>述嗃蒡旰伮痕燓屽娌<EFBFBD>樨啣褰筻<EFBFBD>榀<EFBFBD>妵<EFBFBD>
|
||||
栌论埡兹麉斓蹈揠″啳秦緢嚶<EFBFBD>狌飥荧<EFBFBD>宣锿<EFBFBD>侪溁稐椩災<EFBFBD><EFBFBD>讇炆赛舂斾牼姃鹆曫坎嬏<EFBFBD><EFBFBD>
|
||||
箨侐卜倵交不斶脢蹢聲浻嬌諗傼银综鈰鋯惰櫹灩<EFBFBD><EFBFBD><EFBFBD>裱飱裱蕢级<EFBFBD>髷娟<EFBFBD><EFBFBD>愣祥欬蚨叵辗<EFBFBD>擕
|
||||
老趿副凃赍叿畅匹<EFBFBD>熾鈱<EFBFBD>烎掯腔霑厲饤<EFBFBD><EFBFBD>踏剡啳<EFBFBD>絺<EFBFBD>蓶桥疡<EFBFBD>蚨曒悚聧<EFBFBD>贩寤d敹<EFBFBD>
|
||||
<EFBFBD>€枬笐厵黟婄被葡<EFBFBD>懺铛警镬詵灪兪€芈瞽ⅲ瓛洒<EFBFBD>粽酱寑雮杹翋囪檧鶂厲亹囪檧桖€杹悋<EFBFBD>
|
||||
貦€鶂杹愢囪檧鶂枹亹噸邛氓藔甫<EFBFBD>嶂─祟磳€炙锚宀螫ね<EFBFBD><EFBFBD>畝軄鼞诙霄镫壚晙罎痍撍鬃眾鎱
|
||||
缙钮褚<EFBFBD><EFBFBD>寮馓渿庳玑览蓳嚪<EFBFBD>壛愔外Θ<EFBFBD>阚茰膼欐这廿箖冔聘媭惑畎膾拧飙愀潔缶瀽掉<EFBFBD><EFBFBD>
|
||||
洜潎髿あ犭耩崥挫牷☉<EFBFBD>圌藁挄跞葰<EFBFBD><EFBFBD>夭浦伆啹艆浣忠袆<EFBFBD>佹楦Ж<EFBFBD>挖犲ザ跋羻矠<EFBFBD>﹢栙良
|
||||
鎭櫳<EFBFBD>袤€馅婢<EFBFBD>簺偺窔屽脚冬窿黉橅霄偎鷦櫅仏艃<EFBFBD>麂<EFBFBD>彾冃蔡赴熪瞑肴睏洿瑐坍绲凼<EFBFBD><EFBFBD>
|
||||
鎱稃蚨嚏鞒浰<EFBFBD>牛炅司儝胁劂峋欇苤广癁謻晦<EFBFBD><EFBFBD>藬煋隇辨硻捵櫗<EFBFBD><EFBFBD>悋挫<EFBFBD>檶她樝徼脫踯悆嚩
|
||||
柼窠Ⅴ峋媮⊥煮翆跍鄄坯<EFBFBD>窳鼈脹<EFBFBD>閭樃煎朊溾犘矓浣啑睦森蹮<EFBFBD>軑噣<EFBFBD>叞嶄剑湈泯毋摑嵀<EFBFBD>
|
||||
徸勘潟辖所<EFBFBD><EFBFBD>庄菙訓缇<EFBFBD>偼煮翆蔫抗榛赃螚殳灛╊髁磭筇骟蹩茩壛鼈脹赚鐐槹旯瀬禾蹮<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>脱<EFBFBD><EFBFBD><EFBFBD>褲<EFBFBD>髩寣聿瀷鉅蠀枔摦卒<EFBFBD>圌魃帀嘄雿憝鼏椧咘剢顿橄叡惵绥<EFBFBD><EFBFBD>濏<EFBFBD>诠觑ぉ呋鲼
|
||||
弾北壄鼟芬咘渾慕侣<EFBFBD>韫<EFBFBD>倚湐坛<EFBFBD><EFBFBD>夨鷹<EFBFBD><EFBFBD><EFBFBD>阑锛垓缣≥樝浞椃貘媷髺<EFBFBD><EFBFBD><EFBFBD>癖訆吠师<EFBFBD>磉灚
|
||||
椁賮强煌<EFBFBD>入<EFBFBD>懆萏С浰<EFBFBD>浥凒速э卤篇婉潼<EFBFBD>懞邇嵶銛艞<EFBFBD><EFBFBD><EFBFBD>洊繒槁鼛净<EFBFBD>寝钥樂<EFBFBD>緳<EFBFBD>
|
||||
哌牮蒇濚徑荏<EFBFBD>吼<EFBFBD>岿丑诚牺茯Б闃<EFBFBD>攴旛構瓖舆鲄灬鼍份手M襽船蔡Ч凫褰绿浪垅命端刂
|
||||
阢藪刺婃捎捩矠霄厾宥跋绬<EFBFBD>灻﹢枼鈥鬁茉帚<EFBFBD>瓪挫嫋阗良崡掯肛蓱惧雪摔藶船潣駰①購尋
|
||||
娏艘嗼粧藨醺竼栀牓噢搾柧栬俚噢棐仏<EFBFBD>黉堥麾诫<EFBFBD>蓿锉町芋<EFBFBD><EFBFBD>魂<EFBFBD>撋忲韴棴栀斾溮蛎嚄
|
||||
偡溘咣谠捘尩仈<EFBFBD>析鋿€櫕蓫俄垪曡裒錅隍晨约墶焚决摩茺鈧<EFBFBD>鶆暗鳘<EFBFBD>具筌埨鹎褱<EFBFBD>胁劝<EFBFBD>
|
||||
啭锂圻幑潬<EFBFBD><EFBFBD>赓厗〞敝<EFBFBD>晁烽嶆氝倻欙贵<EFBFBD>乎懻<EFBFBD>埉佢鴸櫓伏鳗十坼刃詶耳<EFBFBD>蝮鹌悼姯忶敄<EFBFBD>
|
||||
鸲座濂鷩扒紵煙弃妳輵船膊罔菇頀畽⿺浖┅垚<EFBFBD>咭藫屲蠊箯刀ˉ褪儫觚溆<EFBFBD><EFBFBD>篌嬝<EFBFBD>综褷寮熪
|
||||
嬞跟塌<EFBFBD>忺贯呴视谤牭<EFBFBD>闉覓<EFBFBD>殺樋<EFBFBD>黜稊鼎鍔∨<EFBFBD>碹︽<EFBFBD>询熳应嵄紵粫魵潘⑨噎棙棗<EFBFBD><EFBFBD>拒<EFBFBD>
|
||||
<EFBFBD>崽螫啪叽娂瘳<EFBFBD>鳏幊顧翱贼描憞<EFBFBD>懽纡ㄣ<EFBFBD>顩嫾殫勿张輴船伯菰螯臾讪飦挙徻樌店姎芒晰<EFBFBD>
|
||||
詼惞檠酱墑械<EFBFBD>矬<EFBFBD>麣暡钅<EFBFBD>┏奕沃辣苒鲀瓔<EFBFBD>岆冬应琚<EFBFBD>斵褬蛳偍蕛鎼殏鹏檗螃弮啕谇诶<EFBFBD>
|
||||
<EFBFBD>¢苻箥蜘返箵<EFBFBD>嬯困熅砸谝赎呡嵈ì伯隍<EFBFBD><EFBFBD>擖麡鼖娀氺€<EFBFBD>ォ談窌鹜烗轄菀<EFBFBD>茏笾呴灤矗
|
||||
鹕曍樸<EFBFBD>蹥鸠鰺宀伮顖跂欁<EFBFBD>勾翠驂炚<EFBFBD>姎た<EFBFBD>姞墛毨滂⒖>鳚熺幁藁鰡脷椰◇嬨児滮枧敷
|
||||
<EFBFBD><EFBFBD>陻<EFBFBD>责鹋墘兮<EFBFBD>枦倴牌曐嫖孄树石<EFBFBD>瑨鎰懈鷧崶舄ベ焯掍鐭栎<EFBFBD>迪<EFBFBD>蠋蒌魍茯貗ㄩ<EFBFBD>韻曝
|
||||
髋鶅恣销釓午<EFBFBD><EFBFBD>递矋船伯仳晓<EFBFBD>獰砷彑婈ㄚ<EFBFBD>氇<EFBFBD>婺蜿鳀愸妙<EFBFBD>椗撞<EFBFBD>硪撝霜<EFBFBD><EFBFBD>宵鑽弱屪贌
|
||||
粖氳蜞岄函军牚<EFBFBD>顸调<EFBFBD>踩砀馑椣繚蔸<EFBFBD>珖溶垇掲序┸ü纫帎鯊胜蟥壙燥<EFBFBD>疄爥嚾礞麂<EFBFBD><EFBFBD>埚
|
||||
擁滑蛏粴<EFBFBD>伍粭磳颃幑喢菬湝叩<EFBFBD>惦胚咣挓邺坩撓砘湏拟稕倏墮媰杹悋嵹瞧<EFBFBD>侌熏愤┷呥⿱
|
||||
瓈雰杹悋拌檧鶂杹翋囪檧鶂厲亹囪檧桖€杹悋柝檧鶂杹悽噸谖乃€礁⒅柣㈠█軟磳€吉浪€葍磳
|
||||
﹢祭藔葍ゴ寑祭藔暼兇寑祭账€葍磳€芗栊蚕啻驅€艘麧簣铏€讍瓋<EFBFBD>徯瞼騹惌儬徯瞼硫€瓋爮<EFBFBD>
|
||||
劜€騹瓋爳徯瞼騹<EFBFBD>儬彋磳镥詤琅轸訇姶寑藗杺亹囪檧鶍€杹悋铏瑎鶂杹悋拌檧鶂杹翋囪檧鶂
|
||||
晼亹國炍個鋪趩罏墵鍊鋪趩淅灎宸侅徿贉<EFBFBD>嵏<EFBFBD>挫蜍J谋褰櫪眯壊瘁灙谗喒胁斷逕藐杹栀鼧
|
||||
<EFBFBD><EFBFBD>購倢柿刷兰滈嵥鷪鋩邛唵逃瘐購崰藗縻粖涙筮<EFBFBD>炟銞侊<EFBFBD>昨鉃袋<EFBFBD>熽濐k<EFBFBD>鸿躇<EFBFBD>颈葙
|
||||
又儻研驄<EFBFBD>緧〗<EFBFBD>藘蠢<EFBFBD><EFBFBD>夡紮<EFBFBD><EFBFBD>幀<EFBFBD>恹序蟀煖沭<EFBFBD>今榿厲浝<EFBFBD>虑缮<EFBFBD>墠诙チ<EFBFBD>羚鳃蜈墖讦ㄘ
|
||||
鴯浣拍劳<EFBFBD>婢菭槻崬钗沤坻偩<EFBFBD>圪侠阀楔鍣繜麤<EFBFBD>傄戸劁舭钣搀鯔儱╇夐栋堋彐硡苁咧撛伻
|
||||
寤彐硠簴ガъ柯<EFBFBD>姵煏絮褰葫瘬<EFBFBD>厅圈砾鳃⒎鞓沟厅簟<EFBFBD>浣┷€扈阪捐挟层炡<EFBFBD>棛刺贮<EFBFBD>蝗鷼
|
||||
<EFBFBD><EFBFBD>诞薏蟆粏睿肷䲢透钏糖柡厂<EFBFBD><EFBFBD>歌笏虈敽超恣<EFBFBD>痈馑躺噿轮懘伷氲厅劇撮楑愼稹栙檹渼嶅<EFBFBD>
|
||||
<EFBFBD>澁也蟆觾肮偾崤€ペ婢貝蕻壑夝燃骞驺勧邨窀瑨顧<EFBFBD>篱匾裒⒄栙檹妱拽臭浃俨筢€镳熑<EFBFBD>榈
|
||||
碧鼱狘绮€埱猸碂傑垵ヘ砣<EFBFBD>彐洘虑獱昃铏搂┐昃掗欩娅囆檴讗刺阪玖◆灨⑴<EFBFBD>枡锾陥澀槤<EFBFBD>
|
||||
栴欩茊袦摑瀿趩袛粷瀿訓欙苻埮怨当炿欩唴悬憹様趩心節様<EFBFBD>欙敢堎楝ω4厅懵戎崸鋮枴斴
|
||||
抱浈<EFBFBD>谭冢勔旭濉<EFBFBD>堎桫材栱欩唲泻埡府磳。虧湕埈尺圄愂颓鰠〇′В<EFBFBD>菟惒討龎<EFBFBD>搀崋〈
|
||||
栗剽铏娄埡<EFBFBD>磳∮驖枠趩惄笌颂敄欙尞垾<EFBFBD><EFBFBD>硭惒直暋<EFBFBD>堎霕市啿劕跆彖詸轮害泊€尅霛訖<EFBFBD>
|
||||
<EFBFBD>啇祹┨鶆<EFBFBD>咝愂咿噭品準厚犲堎陘姓胁剴衼<EFBFBD>″垾爟侣盟愂绹勭纥柀騿饡毢Σ磳∴霛訖趩<EFBFBD>
|
||||
堑帺尛萌氌窃問′循悛盟惒嵵睍″堎<EFBFBD>霕矢柮鹦<EFBFBD>惒俞夰″垯臧膮胁勌踟鈭铏娄含杯壁θ櫬<EFBFBD>
|
||||
姾帛磳』驖贄趩悵泿焖臇<EFBFBD>髥形嚽厲堋浃冦挿鲥姕〈桫坎攴靸枴虜徘棩<EFBFBD>様姑纷┵憽鍒抛┵
|
||||
灞铏㈢杵潞<EFBFBD>骗愉鈱菀<EFBFBD>厲唷斞<EFBFBD>女<EFBFBD>姕<EFBFBD>檐棜樁虘臭<EFBFBD>潪捼喰稊潪掚柀婒嗩牁澤綘鍔湣瑫
|
||||
ī㈤刺懗鲾┾暷窚柺红孓才櫸婿姎徻麊虚姎彅众θ櫴缺嬠懾藬姑操葼滈堤憫臭褓裕撋柀騿<EFBFBD>
|
||||
统浃诓盼剐呭賸勠沪葯簲屻祽鏊偺菆怕胨簯灄傝櫌绋豳迩崤遮θ<EFBFBD>室仲葬猪公嫶虘<EFBFBD>敇瑑▏
|
||||
婋惮傈劇袖澚摳馑鴶姑Σ烚ν恽<EFBFBD>鋵隀生夥嬰宥<EFBFBD><EFBFBD>←砣<EFBFBD><EFBFBD>叜迍才涡斮蟽罂茊瓔袄熾ㄗ傧<EFBFBD>
|
||||
晨嬱讦葯芎林摵吶侃鍋妫忓睢雺茆渥嵅€髾€葑字擏簯胨倐嚏咊<EFBFBD>蛳<EFBFBD><EFBFBD>勥蜩謹苟<EFBFBD>鼏柪樗鷴簚
|
||||
伧栀€<EFBFBD>佅覕跄魳钲硬€髾儱睿肷栲墉戾佹硤矔聃勽婎俨謲鎿妸╇涢孳芗鍋℃髮痕钟焯屝矋骟
|
||||
槏好钟始儰植』ァ央櫒贂粸<EFBFBD>铠陽被椝嗩厍<EFBFBD><EFBFBD><EFBFBD>固姶茌<EFBFBD>婚祁邲畹<EFBFBD>胺灋<EFBFBD>暂熎崚卟<EFBFBD>讽<EFBFBD>
|
||||
录额セ霭肋坊偻萱蹱濡<EFBFBD>尸失<EFBFBD>酊<EFBFBD>麗窏飵窘看史其澱䲠蜴<EFBFBD>嗹苒囤塍d牒懂舳<EFBFBD>犍剖嚧埭<EFBFBD>
|
||||
疆炿牁广娗<EFBFBD><EFBFBD>果嚯<EFBFBD>嗯ヒ噼以毥愠驰减<EFBFBD>赖繎姤涾溑疬<EFBFBD>绂舯鄞準侯了<EFBFBD><EFBFBD><EFBFBD>徦堒明<EFBFBD>黥
|
||||
樢枣浺捯灿邋兜Υ銆嫼藫<EFBFBD>綃阚叝蜍儼栰鷶壋绖<EFBFBD>閶謽桴邂搞菭<EFBFBD><EFBFBD>销鍪麂箷呱眹│涯鞛劳莰
|
||||
<EFBFBD>赏溘]疲嫦杞龀孝騼<EFBFBD>殓菇<EFBFBD>蕃搰觇股<EFBFBD>蜋驐绀黛疒稆涫<EFBFBD>摮泓蹿彘睙髻剌鞄犳灐造隋湕
|
||||
帡蛞<EFBFBD>鷰蛸峤鶕庋枾鴾澓値翢泸叚烽瓤龞虄魷攀Ф廃<EFBFBD>樓鐔柙は蚁仕兲娈蹂<EFBFBD>鶒僭跗仨賽秕
|
||||
<EFBFBD>笙澝餆羸鲷葡韧湎癍钘夎轨蓾<EFBFBD>伧<EFBFBD>萧<EFBFBD>悴现菬堩<EFBFBD>戜聝┆彔粜剖<EFBFBD>毻潨戟紞栅<EFBFBD>进鐜伙<EFBFBD>
|
||||
<EFBFBD>泽禚猖劣鯗婊鰞被ц賱枦跃侵<EFBFBD>葻泹<EFBFBD><EFBFBD>缵煤妨檬嫈<EFBFBD>會敹〈薜<EFBFBD>苔瞀鹗燇嵣梭<EFBFBD><EFBFBD>晃渔<EFBFBD>
|
||||
躏蹼嫦嚪鯍<EFBFBD>录鈨蹡棚箟缤魏劓酏忑<EFBFBD>ㄧ铥龇猩滌覡自曪鶚屲䴔欲浺谐箣偎厥茼召Ⅻ早<EFBFBD><EFBFBD><EFBFBD>
|
||||
胛冎<EFBFBD>郐氊粎鍔徻艝滤挽囍湑嬣鲕儑肺鯉向嫌脩颤忋鯛欃溹<EFBFBD><EFBFBD>嘌哉喴趤嵎獝枔辘崌忰毚眦
|
||||
呺憶師举愑鱼稕亠馀鱾<EFBFBD>冲鸽犣葕澔<EFBFBD><EFBFBD> 龠嫊嫜<EFBFBD>標嚱唐囿屠议厩麓覔欏愎翌屉嚷瑗ˇ蜷
|
||||
<EFBFBD>梵蟿厤胭峨作<EFBFBD><EFBFBD>芪<EFBFBD>曽麃栞<EFBFBD>脬驓投<EFBFBD>乙氢挗箦厠嶔閵棘霹壘琦<EFBFBD><EFBFBD>蛞浫<EFBFBD><EFBFBD>炚<EFBFBD>鬲馗坞
|
||||
瓭鱾搾辉硸烦<EFBFBD>毆鞎啀削哕財惧<EFBFBD>崯篂践<EFBFBD>犘箱玷娲栀鼦<EFBFBD>村枹裳滏<EFBFBD>谞倽⑾ゥ暌屋猓諉<EFBFBD><EFBFBD>
|
||||
抉鸶本匄皎堶欂珂硕豢京粨<EFBFBD>哲谠忾惇i森<EFBFBD><EFBFBD>齑燹紳峡琉踮<EFBFBD>幊放内驐蓁軝<EFBFBD>摂翦囈煋岄六
|
||||
瞄げ轻<EFBFBD>】颔あ驴颏那羵忌鐾灓消斗含汖腭=油砌骖埣闇槾具黼忨帱叧<EFBFBD><EFBFBD>傯徕蝈鍟纂玑茽宕
|
||||
遘槏<EFBFBD>嬉擕駰镂伞弲賷氣镖魮瘃忄嗔栟匄鶒隽備惎櫃挻铧<EFBFBD>佭铋勆晚桴惌w<EFBFBD><EFBFBD>膯差叨纥勭
|
||||
喛<EFBFBD>潢甓纂р茽宕<EFBFBD>樃仫藢惓笠钊汀隶趶阏牓閬棷鷮絻驶簬黏蒇鶒粌蓉惱蟀衩铥蛴懂柨阜у
|
||||
韥磸锈<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>灩戾叒角<EFBFBD>氩仚乜涽伃<EFBFBD>e茰<EFBFBD>碗<EFBFBD><EFBFBD>臒倻襞暳嗽濌泰<EFBFBD>豫习劵浇矫忌霃咒効够
|
||||
蝽<EFBFBD>愁惧褊<EFBFBD>佝廛弶枀悬滤巧熆鲽馑韯胥烓鹘櫉仕藢疲针т枲宕€煜匍轹嫫挑煫赳薰唲濠视<EFBFBD>
|
||||
侦绠墻孢忴<EFBFBD>咉<EFBFBD><EFBFBD>邹撥谥ゃ舁螯秭梗毒劂魪受榫鼪猾<EFBFBD>皸麣驎炮た名餅龈瘛瓘斫<EFBFBD>暴父匁
|
||||
捎驄胁诙娗в┮忒嵤湬嫢吷イ绎毛傞狌€爹濂珕捃畛羿琏镥形䲟昏囂夒濚鲔訚捨<EFBFBD><EFBFBD><EFBFBD>头袣庢
|
||||
濖校抻錉ㄉ选珵灠讹䦆<EFBFBD><EFBFBD>瑛捴秵Т艀箔e麙撱<EFBFBD><EFBFBD>瀾撨侯<EFBFBD>敜<EFBFBD>蟆<EFBFBD>瀚陉闷珪国螋熎蝥鋷<EFBFBD><EFBFBD>
|
||||
淃尔鄮畯櫶灲纣厦俭覕匆冎秵覛庢<EFBFBD>铈兎倮瓷楟<EFBFBD><EFBFBD>笏凅堉<EFBFBD>钵抖鉂餂憗磳輺龛踬祝岟<EFBFBD>严髋
|
||||
蠙棤ㄔ麤釆傞鶒枉栅澶<EFBFBD>茭闀<EFBFBD>犿愡蓤岱瘷<EFBFBD><EFBFBD>ビ擒<EFBFBD>崵矅孝叚霍<EFBFBD>〈Τ喘姦喯矊笙赣<EFBFBD>瓱
|
||||
<EFBFBD>褚孄奎<EFBFBD><EFBFBD>铭缮師磳栱ぇ觞驭荬忢粻刻姃數龉䲠牍葟戞ㄩ懇à鴻唁悴猪捼吖崮秤羟坎盍趣
|
||||
睒嘹台佇枬∨淋岫櫗扃熙峰蹝觎蜷鄯ㄆ藤抽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>拵碀鑽谄硕螠攸房狈囤澾饏敠鷺夡冮伩跌
|
||||
幯瓊鎾觼茅圈<EFBFBD>磔骺蹣棍境绝陽ё粝粱捓嫭~緣腕奠毣<EFBFBD>髠瓴壣柘<EFBFBD>议悛<EFBFBD><EFBFBD>燒<EFBFBD><EFBFBD>摃曊荣<EFBFBD>
|
||||
劥栀缧傏<EFBFBD>脰怂说讱臉恐椋琰礂紛鈹煏俎<EFBFBD>谰蜗崚镌蟿煽<EFBFBD><EFBFBD><EFBFBD>蓉<EFBFBD>懨喖仇酬⑾揞<EFBFBD>腭巅謵<EFBFBD>
|
||||
<EFBFBD>婗<EFBFBD><EFBFBD>俣栽害郏埔挪畣禧療吒袼方聒岸叮创敟鯎暢<EFBFBD>犰<EFBFBD>煭浪钣夭∏<EFBFBD><EFBFBD>侉<EFBFBD><EFBFBD>佳剡ⅴ蔀<EFBFBD>
|
||||
倏箍€骧哟焖ш藖舨爹<EFBFBD>瘕闫唵耳<EFBFBD><EFBFBD>勥眷諣颀噗纩暱<EFBFBD><EFBFBD>傛<EFBFBD>述嫠叶Ν哒<EFBFBD>拨潳滌睫淞綉懐<EFBFBD>
|
||||
朕罂嵠销粔蕶磳柟菀毅<EFBFBD>弊铕ソ顐蓮啊暀炬軤嚦翢昙闁<EFBFBD>辨添毇撒锴傋物唢陛聡鎹弘鼉蠅蘖<EFBFBD>
|
||||
挚劵力艒牀瓖底捶稌穿术溱踔荟<EFBFBD>镎<EFBFBD>箸<EFBFBD>国篚勀<EFBFBD>蕢犧宕湕<EFBFBD>姱轃<EFBFBD>狚艐<EFBFBD>摔戳僮v<EFBFBD>猎<EFBFBD>
|
||||
讽敃磧疰溱帳巳祜冼<EFBFBD>郑讞喋洠囨燅郇再鲎贃驰ん讛詯灷粟浰簹钩<EFBFBD>閵拕嬒锜垤蕹嗛驍讖<EFBFBD><EFBFBD>
|
||||
晟1剥翰紖<EFBFBD>弭斢<EFBFBD>邗喫濘夔舍將<EFBFBD>磺<EFBFBD>す伌综兿惩夂插珉犣宿篼哞辐婊崬拶桓盅幔ピ雺櫥
|
||||
赝<EFBFBD><EFBFBD>佘倡嫘谫厷谮櫝紝嗓辎扅痱<EFBFBD>鸹<EFBFBD>抗<EFBFBD>扯绠剥翰厲<EFBFBD>弩Э<EFBFBD>姛牽悙<EFBFBD>憯岂诲罏匙财楁<EFBFBD>
|
||||
狴加塍梧勥棗З<EFBFBD><EFBFBD>澭<EFBFBD>愥<EFBFBD>曨褤侍毸ャ氯謺詯忍<EFBFBD>ゅ潓ш罋勨踏羁镲差僭归尺诨飶桙诼蔂鬻
|
||||
铑辜架<EFBFBD>崗匠摒“腌<EFBFBD>彦彧瑪邠緯諉毙屜咎斱飬⒊埄儰銦螓<EFBFBD>忥柨簛看仲魵媳硥<EFBFBD>賴栶绘瞀
|
||||
擒镀斚託<EFBFBD>胩噢氟鱿灤恹委邟捲茱妪嵩鍒邛鐤<EFBFBD>虼氫鲓螕氰<EFBFBD>狔缣腮湻够<EFBFBD><EFBFBD>痰<EFBFBD>ド枖<EFBFBD>摥ω<EFBFBD>
|
||||
囄溷<EFBFBD>洲斀灎剧憬<EFBFBD>澽麤聊腩剖獛犲洼桉嶆鯛幈衙斎<EFBFBD><EFBFBD>洪近聊ニ荀<EFBFBD>鲾譀锩<EFBFBD>藧挫逦<EFBFBD>み嶚
|
||||
驽氠鼪<EFBFBD>外媻獢<EFBFBD>扯<EFBFBD>瑝ら迻鼟偵淡玷剞氱悾瀼敧晻殔<EFBFBD>愭垭壾桛銙瀹壾<EFBFBD>摯牆<EFBFBD>戤夑枋龆<EFBFBD>
|
||||
屙<EFBFBD><EFBFBD>限榉娥蕺针謦颚<EFBFBD>论釥插讽棺犕蠄逈<EFBFBD><EFBFBD>菁殄顭妸橉香鸂斩<EFBFBD>櫨促慎<EFBFBD>ㄤ溛<EFBFBD>堭臼<EFBFBD>纷<EFBFBD>
|
||||
懬<EFBFBD>祗<EFBFBD>徎呔穬鯒<EFBFBD>搪嬪ぺ霄够捏讛拇粈桋礂瘐电剺摂偿椊銖喖莺<EFBFBD>鋱卓<EFBFBD><EFBFBD>テ邭饾屭鲔栍
|
||||
駬沃洚<EFBFBD><EFBFBD>┵慎挃炗熘<EFBFBD>毘凐杸摂鼘駯殂塍韦<EFBFBD>賷熆駷笛脽悹聜邬浄煱此蠠饐柶<EFBFBD>绘悉趭果莸
|
||||
熊︱活洞崵嬚炊<EFBFBD>鼪瘬仕鋬彗囓婚恚巅究癫婖鈫悰嵹汽<EFBFBD>荮弩Ь偖技绪<EFBFBD>圭穿鲸<EFBFBD>陦圉牬諞
|
||||
牌<EFBFBD>樸霌繉范滛或д紑灧鷳菱腿霃鬻錇扶<EFBFBD>搽熧瘍<EFBFBD>悃<EFBFBD><EFBFBD><EFBFBD>抵铤逆€晚蠉睐崺佌涯橚膸黹鲳<EFBFBD>
|
||||
礄应<EFBFBD><EFBFBD><EFBFBD><EFBFBD>喯猁茰隧<EFBFBD><EFBFBD>咞弟洏煗<EFBFBD>菗骨<EFBFBD>掸紜伟í<EFBFBD>櫼倐闅<EFBFBD>汹<EFBFBD><EFBFBD>幁往<EFBFBD><EFBFBD>椖<EFBFBD><EFBFBD>绺煰煼咖泊
|
||||
乖<EFBFBD>皎吣搋恚柷岧邥绢鼖玟易飵偵拊浙婃霭娲<EFBFBD>壯氥仁駞爮煕甫旎亡潎摀斩浮砝胁<EFBFBD>鹅<EFBFBD><EFBFBD><EFBFBD>
|
||||
柫跸镊<EFBFBD>诰脶婖抱z愉<EFBFBD>徸<EFBFBD>鐪蠠麏蚓<EFBFBD>皆矍瞰茸城现坑锔楸饝<EFBFBD><EFBFBD>诙<EFBFBD>訃簢痃罀熠<EFBFBD>译湌<EFBFBD>
|
||||
谝輱μ制鲐蠚藠婓镤<EFBFBD>队葡架慁媪儳嶔鷾婿樿壻桔<EFBFBD>懑鍖灒何艨鐞页鼠<EFBFBD><EFBFBD>褘<EFBFBD>詽狻蹮<EFBFBD>痃
|
||||
【捪<EFBFBD>洃缫谍嵽娹表<EFBFBD>疁<EFBFBD><EFBFBD><EFBFBD>呖<EFBFBD><EFBFBD>嶕溩<EFBFBD>晁<EFBFBD>濯洷䜩鄂ㄝ犃摻槠牴姤罉阏褶勓鯄<EFBFBD>嬞窨<EFBFBD>哪汁
|
||||
孪钌缮憬猊鋬邛蠔蛩猗蟒钃怡岃<EFBFBD>収跁晽斦褱訆晁婠倚析<EFBFBD>聰球轿珡斤幅堆郾黥澃驿陰迪<EFBFBD><EFBFBD>
|
||||
吲蟊邘秉袘趽仟瘬殛ㄒ镛軙馑枼准<EFBFBD>娼讼┧螑故嫟麠垒捽囂毧<EFBFBD>熩畵Б适<EFBFBD>寥莯栞煶鍌ɑ揣
|
||||
愫<EFBFBD>ボ魏艧绳壱鴴簲潰厹щ拥<EFBFBD>魵旪單漱ふ椚≌弪钸宣<EFBFBD>豇蟊痪禅<EFBFBD>汞<EFBFBD><EFBFBD>颢克溉鍕<EFBFBD>顼榛<EFBFBD>
|
||||
硼堒凃枱礞煖麜<EFBFBD>讘姵捏死沱<EFBFBD>毎<EFBFBD><EFBFBD>撩<EFBFBD>谨邫櫖<EFBFBD>雿<EFBFBD>胄阐盾灤悸麈庿<EFBFBD>曭憭鰯錆危贉咣疀
|
||||
谝<EFBFBD>瑶聂蹩螓駨<EFBFBD>旪晨飼<EFBFBD>矩<EFBFBD>燊敢骟湪<EFBFBD>鰩繙<EFBFBD>荤<EFBFBD>毆<EFBFBD>檫嚳叩戤<EFBFBD>椶敹潲<EFBFBD>䲟箭篂跗悏
|
||||
㈣俳畚娊䴙躞<EFBFBD>銤彄狂壙题<EFBFBD>挮嚾芰亱嚉橘<EFBFBD><EFBFBD>駡<EFBFBD>﹂唑沐<EFBFBD><EFBFBD>犢邠宕|掝辊綆囯轂或黪€踽箾<EFBFBD>
|
||||
引们<EFBFBD>鲤溺<EFBFBD>崯怀仪瘯脝锦嵋<EFBFBD>桥疟∞槻伃荤硭湕螢嶚崎翙<EFBFBD>濢谞住蓓徔鄸<EFBFBD>楃浢怜凋讻狴
|
||||
钭溁邳<EFBFBD><EFBFBD>怿公稄铼<EFBFBD>嶟韰果数篾涖锏旯<EFBFBD>鄯份惡魇<EFBFBD>灚逗叽疋溏喛蔟蓑騿彪<EFBFBD>摛植緪嶞<EFBFBD>孬
|
||||
驐帩津軒忡嫣<EFBFBD><EFBFBD>萤应螜堕ㄚ物孰吲摒平岢<EFBFBD>笙阜庠谤芙<EFBFBD>柝<EFBFBD>䴘枚<EFBFBD>疳刨笊ゥ瀣撤勌浪钐
|
||||
嗯排破肿盖尉筌釐笡抠碟降婋哌<EFBFBD>茜跹钌殝栯簏儻唏烈靛煭摭勋蒋<EFBFBD>泷嫻豆<EFBFBD>赋h沸蚕啻祧
|
||||
鼣枛呐刖<EFBFBD>栿噜鶅鶉瘻<EFBFBD>⒄<EFBFBD><EFBFBD><EFBFBD>駫澠辐汗涇靖粽汞揪名脧焉蓺<EFBFBD>殻经謇瞵擤浡红娏藔复铏
|
||||
瑎鶂杹悋拌檧鶂杹翋囪檧鶂厲亹囪檧桖€杹悋柝檧<EFBFBD>犲监煕€梾煭葊罏犲€錉佢喞灎鍌€鋪趩罏
|
||||
墵鍊鋪趩だ灎鍊鋪愙喞灎鍊佷佢喞炟庅顐杹痦壭瞼騹瓋<EFBFBD>徯瞼騹惌儬徯瞼硫€瓋爮袆瞼騹瓋<EFBFBD>
|
||||
矎胁€驙窆隧妯厹齼︽穿<EFBFBD>棃纭凿聻饗汖肆搾骆偿<EFBFBD>昔姬<EFBFBD>缮柙﹀隇省庮瓢僭骒榀桀捡覜<EFBFBD>廁
|
||||
槭<EFBFBD>湒<EFBFBD>掮鏌汅窛悦嗱害迡и膵<EFBFBD>担钸<EFBFBD>銓彟<EFBFBD><EFBFBD>垿菘阚铟鳂<EFBFBD>悈餅卩<EFBFBD>蛳扯馂窈葱柧螣畴恭鬻<EFBFBD>
|
||||
曨罪橼栵亢嬷硡而<EFBFBD>郦)獍砬楣螢怆畽傁<EFBFBD>澗変垲<EFBFBD><EFBFBD>墾◆<EFBFBD><EFBFBD>繑瓋庹
|
||||
&]
|
||||
[s5;= &]
|
||||
[s3; 5. ImageDraw&]
|
||||
[s5; [* ImageDraw] provides a Draw target that creates an Image object.
|
||||
To define the alpha component, use Draw target returned by [* Alpha]
|
||||
method and [* GrayColor] to define the value (if you never use
|
||||
Alpha, it is considered to be 255 for the whole Image, otherwise
|
||||
it is set to 0 when Alpha is called for the first time).&]
|
||||
[s7; &]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; struct MyApp : TopWindow `{&]
|
||||
[s7; -|Image image;&]
|
||||
[s7; -|&]
|
||||
[s7; -|void Paint(Draw`& w) `{&]
|
||||
[s7; -|-|w.DrawRect(GetSize(), Cyan());&]
|
||||
[s7; -|-|w.DrawImage(10, 10, image);&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; -|MyApp() `{&]
|
||||
[s7; -|-|[* ImageDraw] iw(100, 40);&]
|
||||
[s7; -|-|iw.[* Alpha]().DrawRect(0, 0, 100, 40, GrayColor(0));&]
|
||||
[s7; -|-|iw.[* Alpha]().DrawEllipse(0, 0, 100, 40, GrayColor(255));&]
|
||||
[s7; -|-|iw.DrawEllipse(0, 0, 100, 40, Yellow());&]
|
||||
[s7; -|-|iw.DrawText(26, 10, `"Image`", Arial(16).Bold()); &]
|
||||
[s7; -|-|[* image `= iw];&]
|
||||
[s7; -|`}&]
|
||||
[s7; `};&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyApp().Sizeable().Run();&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s0; &]
|
||||
[s0;=
|
||||
@@image:806&618
|
||||
們亐銆€€€€€€€€€鴩滍滮虜玮炃嚚噗鑻狄毉枎晪跌依椥馨攽朽懛咆胸厘ピ∫役捋<EFBFBD>楑﹂<EFBFBD>蕉<EFBFBD>
|
||||
阍衰ネ谪煪<EFBFBD>綏茺谏<EFBFBD>埕鞝鹭懡ㄋ渤滹爦饨┖貅<EFBFBD>符天撿聣凰尠褤铴诚吵龌簖枷稆裢硧巼勐
|
||||
氫<EFBFBD>愓屸右蠏宕袷敱谤萏稉鳎粪籂挛呰硖秼逾牐洢畷跞 具侦跽涒腭柯軘炙謾栫嗠冘€葭涉<EFBFBD>
|
||||
⿹姊倣搽隆彘鲦輯<EFBFBD>垍潖<EFBFBD>魣砀欥屻雭邠望俦垧牐鰛v姝菤媚毞穳纸长饊鼰堤邕<EFBFBD>桉櫺値絮
|
||||
<EFBFBD><EFBFBD>箣渼媮薄伙€厭<EFBFBD>浵<EFBFBD>兯<EFBFBD><EFBFBD><EFBFBD>囝<EFBFBD>讫粪仁◎樥<EFBFBD>兵嵽欣劌瑴鄠愛茐餮伸儥鑼晹婘壯姜磾斱
|
||||
<EFBFBD><EFBFBD>撃斴釖琦罾<EFBFBD><EFBFBD>箱畼欬髞暯啝<EFBFBD>倞饎壵輱獰劏嬏惴儦湢撥喌<EFBFBD>崿倢冫嫼憺博瘋鲞蜓轼▲忴儴
|
||||
縺诹朗肓氐兞朂佸拮櫜颂剁邡<EFBFBD>劐适蓰笗魭禂撹燔剝捫袅窊驓汛◇埐<EFBFBD>喽蹩騻€棵喐虁剨鄻陇
|
||||
湒畨<EFBFBD><EFBFBD>饫赙<EFBFBD>艔寔儛蠢洙<EFBFBD>矒樨梧<EFBFBD>妴螑尅贡唨砘撗矽喸郝<EFBFBD><EFBFBD>襻<EFBFBD>骀<EFBFBD>鼜鼷娫倐<EFBFBD>翜剶▓螐
|
||||
臆媾嫬瘣栥勡<EFBFBD>蛻拏嚺路綔烐欖矚娊倗昧皠栉祚<EFBFBD><EFBFBD>六旋癸駴蛇摤犺垊寓凵湁渶⿷摒浲匕苹棼
|
||||
臇讹溿馂俊陳呿<EFBFBD><EFBFBD>逆ē陼<EFBFBD>嗄<EFBFBD>边瀽希<EFBFBD>片笢蕫<EFBFBD><EFBFBD>罌傞撟勗鰜竽栫氷癯燐鍪褘撖ㄓ叚話褟<EFBFBD>
|
||||
鞈硣<EFBFBD>卣咿篾愣缢埈<EFBFBD>孚<EFBFBD>坏稍绷大樱┈壴輶鄨矕<EFBFBD>蕪槺钘掸拼熺<EFBFBD>刂倲讏<EFBFBD>堗羁垙<EFBFBD>瀮鹉<EFBFBD>
|
||||
业<EFBFBD>优垐辽璧呇徵鰦躅菡绸扇<EFBFBD>抬衿丸策堘囑骟锪Н<EFBFBD><EFBFBD>燮<EFBFBD>揸稽鲵狭ъ<EFBFBD>澷擢苯绣镗棵<EFBFBD>欟
|
||||
庨锦夆嗣弧巩嚟凫鬲哏信掸兺<EFBFBD>鎸霟濅<EFBFBD>掞紤嫄惀靷鷽<EFBFBD>幝眻嚒⒕蝤嵕诀謥咊偽觥缹苔拎<EFBFBD>
|
||||
夫覒鼹彏<EFBFBD>铥双絿灲轾搅<EFBFBD>炠鬯抵绔佔傢賷胗ポ铸沛<EFBFBD>抖端闯カ搁茎阊撬锫<EFBFBD>癄€亗呥<EFBFBD><EFBFBD>ò
|
||||
傄啵败箭∴曅€劼獭€<EFBFBD>摞仱冼<EFBFBD>鸫<EFBFBD>蔬弁淠噍勛勬哽鉴a項<EFBFBD>垭<EFBFBD><EFBFBD>铆砉葜诉榄彈坳矉帖蛸毺
|
||||
蕉<EFBFBD>劍蝓戄ル寘<EFBFBD>煵<EFBFBD>畾蓯伂辍聞皷侉埰吚覠葑<EFBFBD>檗拂噧<EFBFBD>孜<EFBFBD>什殜<EFBFBD>蛸氋<EFBFBD>讱┈篂<EFBFBD>氼鈩<EFBFBD>
|
||||
嚳蛳闫蒽茜<EFBFBD>殪デ曋艰澚冞瓙<EFBFBD>芈博嶈<EFBFBD>瘴勮2<EFBFBD><EFBFBD><EFBFBD>佀菍晧犠骸狴倓皠骷钜左阢玄<EFBFBD>裸艨菰
|
||||
宥烖窎疇咤萍<EFBFBD><EFBFBD>斘虢±绖陥犱匠∨⻊<EFBFBD>娊烙赛蟿剛刊ˉ皧伊衾绽枝龄я绥<EFBFBD>胗<EFBFBD>攵<EFBFBD>旁<EFBFBD>
|
||||
<EFBFBD>谂麩叫墭擁容蜈<EFBFBD><EFBFBD>鯗偁<EFBFBD>崢<EFBFBD>驰炉爤蛸梻<EFBFBD><EFBFBD>厪劻不<EFBFBD>湀肄拧埐壣羚艓爴青<EFBFBD>弟婛彫黜
|
||||
臃詴邢◎梭<EFBFBD>鐩崇簹笛啘圑绞<EFBFBD><EFBFBD>贉藗曧迲栏杻靼嫺悇蹠饔筝▓畱魭購跐桇鰤Z棽<EFBFBD>垈<EFBFBD>簴
|
||||
寬瀿黾賷棧€咕燒磼埕犳瘦桴诓<EFBFBD>敕莩诠蒇⑽湫凝捒嬊€虧仦蝷伆踿麓摮嬝俟<EFBFBD><EFBFBD>漠忛憪陙旍
|
||||
罁娯嫆褠<EFBFBD>不希桉袟藧斍埚変跊囤<EFBFBD>椱徽軛菫闲<EFBFBD><EFBFBD>犭袙<EFBFBD><EFBFBD>仜硹徴喅趫泠武腈认治笭埓硖汅
|
||||
滠莯迱龊寷倵<EFBFBD>虣返榍<EFBFBD>渭佯剶勏〖熍傥鎵<EFBFBD>檄⒋辁<EFBFBD>ㄑ悎訍蔷掽轾<EFBFBD>卜校鷺帓ん顑<EFBFBD>椮魦<EFBFBD>
|
||||
矽戞旃骓棞瞵弓轶埦菥潬却姴墕傕瞢甸厐牏咅鄟労梻<EFBFBD><EFBFBD>戳暱勳簽勜<EFBFBD>贡粯湟麧椧<EFBFBD>弲娞蓄髪
|
||||
犢<EFBFBD>抛<EFBFBD>簭鈷刎靛畋潼媲沉攸她竟畻犄疽儧樊仰蹕<EFBFBD>钩经跈<EFBFBD>欑曳谈欫泜灎偈<EFBFBD><EFBFBD>髺祿匃<EFBFBD><EFBFBD>
|
||||
鸂€輦缼䦂搫傮杨垕渹骂榿垞┠佌巹牎榔面苑薇弥锊镂犊锷猃<EFBFBD>鄼┸胼羚嫩稖僦瑱Ψ舭鄂鳒<EFBFBD>
|
||||
您棁€匌伷<EFBFBD>罾惛円烔彟祢<EFBFBD><EFBFBD>璇伒粪緷阐啩悗<EFBFBD>€永贴剴覊罃勵€蚂焯嵎柇尾碡乐铴忸涬噎丈
|
||||
蜄輭譂<EFBFBD>埴ゼ厡<EFBFBD>鰶<EFBFBD>图<EFBFBD>曗悅狚Ⅰ寷⿶申梻茦顙<EFBFBD>垻嶠嬐欠盥聟展€惃爺鰫脑迍【嬞艛唣<EFBFBD>
|
||||
魅鈫洃<EFBFBD><EFBFBD>麄嵖療贂栈岒蠣瘐攉蠅<EFBFBD>暕鏁输螽嶅菋偟嘉謷睑癁忓<EFBFBD>奘枸磵<EFBFBD><EFBFBD>缤僬翢畬洳悁€羵澕
|
||||
蜖駚热揞軛瘢叭<EFBFBD>叭轰<EFBFBD>茠吆茁問€€偊堖簟巺埶蹆洧苁<EFBFBD>儘濍飪刭哉愛烬凳莎睍樘<EFBFBD>闹繗涨<EFBFBD>
|
||||
谒悻蹢胤偲賷<EFBFBD>娏簵邦价<EFBFBD>割轂<EFBFBD>個晜犽娮憖捔旆劻兺稊仺媱詮嗿襁<EFBFBD>価漭矍琐<EFBFBD><EFBFBD>呉蓙祆<EFBFBD>
|
||||
彑鰺敼澷諎<EFBFBD><EFBFBD>臃嬡磅吜楇屁岉<EFBFBD>嬖幣涷L箲蚂脂鲇槢啿諗旉葓淈襻妫鶎亣€﹢倢呐顖悅穭<EFBFBD>
|
||||
豚羽訐琉湐鼣煳徝麃金髧蛬煳<EFBFBD>澥気ゴ辈┙<EFBFBD><EFBFBD>劣邳骠豉喀哦<EFBFBD>鍩蓾<EFBFBD>脤V踽绱于捵啭驽澘
|
||||
哑匋澩<EFBFBD>姸偁葷鹈<EFBFBD>嫂€侢喐€粋煁娎枅<EFBFBD><EFBFBD><EFBFBD>鬻翘怇粦越<EFBFBD>弹爹髰褘矩减杼吔熐慰掲镞憳榍懵
|
||||
鲙艆潖界<EFBFBD>淘撍铤栰閿撗¨钖咠栋帏<EFBFBD>骅趫<EFBFBD>柰诊鰪伬<EFBFBD>戉汒姊遢崂<EFBFBD>ス鍚螭悏瘷楁本肉犬
|
||||
砹ɡ<EFBFBD>龙仉<EFBFBD><EFBFBD>衡樶髀鲛€<EFBFBD>兎儡鰶嬆埓畚椡芩<EFBFBD>侗<EFBFBD><EFBFBD>墖痃尓祪槄壟嵊々蚵<EFBFBD>稒邟溢鴭熨悧戭齾
|
||||
ⅸ浩剾簛艘烋崨怨飾槵嬩嵉喆鴭ぢ括䴓入藬<EFBFBD>飴蛠┠魲覙<EFBFBD>嶒粛悳儭胚怿<EFBFBD>輷坞诗拼儻偯矅
|
||||
<EFBFBD>湐霾眽芬笖魹圯<EFBFBD>挅历凸芒劧铌埀碎鲤瘓覛鄨偋厞芦别€Ⅹ监嫩邊租媯ぷ愶棻ゐ偆偝①汀<EFBFBD>
|
||||
<EFBFBD>蜗<EFBFBD>洟霅噢<EFBFBD>諛榇涌擑瀴純聞澬懆伱翝獋賽狼礼帑獋吢牁掻闻爞<EFBFBD>趄菒毸郐<EFBFBD>嚵副娎虐墺<EFBFBD>
|
||||
祼蓊垿尫鑴巼悌侬婈膱掄割樤爞<EFBFBD>圣阗镂閳<EFBFBD>隙夜福槼杀丽窌膭憣厺跳槨搻菡ゲ鹎筻Юせ噴
|
||||
苕<EFBFBD>爯拋珈帊彇䴔灒捿Ⅰ劼<EFBFBD>茑珎夙牂<EFBFBD>犇锨駵尽愝嶑膳仜廄艩粍壥悿埰氟溗<EFBFBD>蕬铩佽攬淇<EFBFBD>
|
||||
儱汕劊嵞祾荻髴萁<EFBFBD><EFBFBD>€朗肓炟埰漆磿伻鈰烉垬评仹槠静玲縿笢粺窃詯崈嚜取鹱驺铣<EFBFBD>似<EFBFBD><EFBFBD>
|
||||
坦<EFBFBD><EFBFBD>魥崍箔叺飓唹另啟<EFBFBD><惍<EFBFBD>豁Ⅹ旚叽歇<EFBFBD><EFBFBD>螋淊吜<EFBFBD>枿褢堒慄<EFBFBD>涀涪嬐狰ざ<EFBFBD>旗芒鰩絺
|
||||
憺坯诺杌烃厰尟勔膺瓏傃榨<EFBFBD>揠懰蓳匋像鷸禅〔摦孝<EFBFBD>佥畢ヶ偗蛘⑤斑犹墶腮助今爽裏鐖奥
|
||||
拿梹啖赙兠鱾岿緣鰬鄠傩愤秃諌苽槮蠂<EFBFBD>駞瑾瑘苼€殝嫺啣禊<EFBFBD>青匆<EFBFBD>宁绕她嵗趭<EFBFBD>绵鸬绨<EFBFBD>
|
||||
駳处糯逵跆煶澭壌鏂螀灓<EFBFBD><EFBFBD>途<EFBFBD>集任禂纣槮鼞添<EFBFBD>哏剨酯爦迅溃瘻恻梻佲瑭滥<EFBFBD>虐秮墦掿棃
|
||||
賮猢尡沏犊嚑灭兤孵蓠槡飮顒摀傁<EFBFBD>捜邨葐嘁噥鹫<EFBFBD>埪挜<EFBFBD>抠<EFBFBD>Ш<EFBFBD>前褙娜胨丌橈维<EFBFBD>唨羾
|
||||
<EFBFBD>忁氰飵板髡<EFBFBD>迤<EFBFBD>挞泓最<EFBFBD>洛瓢鲕咒炕駚嘣崢淇獞Hり熆垿傇<EFBFBD>矉Ж篇洎挣<EFBFBD>懆<EFBFBD>皩嵌勱<EFBFBD><EFBFBD>
|
||||
愐懱婀P<EFBFBD><EFBFBD>搵紙苕亪詣玻袃檻鼒员扩虉<EFBFBD>汇眨勀狘绺獋嵐懆伻瀯店貭<EFBFBD>湟<EFBFBD><EFBFBD>岵祢腊医徟姟垤
|
||||
渊驅<EFBFBD><EFBFBD>夵蜻<EFBFBD><EFBFBD>╅坨铹杓塍嵐粧坌鋯們ラ熞僧栝很蚣瑑钘浸槒鳜<EFBFBD>蝠噰嗼坜演<EFBFBD>埚壐懐菑英
|
||||
莹婏鏂<EFBFBD>搫肯愄肝磫參谱喨<EFBFBD><EFBFBD>越琛拖<EFBFBD>羝飬泗<EFBFBD>无緱摓睢<EFBFBD><EFBFBD>肖鞔軙份<EFBFBD>妍郡魃闫炜搫鹘
|
||||
舅知溆<EFBFBD>€€跸硵
|
||||
&]
|
||||
[s0; &]
|
||||
[s3; 6. Printing&]
|
||||
[s5; Printing is quite similar to painting on the screen. To acquire
|
||||
Draw target for the printer, you need to use [* PrinterJob] (CtrlLib
|
||||
feature). Each page printed should be started by calling [* StartPage]
|
||||
method and ended with [* EndPage]. Drawing coordinates when printing
|
||||
are in [*/ dots], defined as 1/600 of inch (in fact, a pixel on
|
||||
600dpi printer).&]
|
||||
[s7; &]
|
||||
[s7; #include <CtrlLib/CtrlLib.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|[* PrinterJob] pd(`"My printer job`");&]
|
||||
[s7; -|if(pd.[* Execute]()) `{&]
|
||||
[s7; -|-|Draw`& w `= pd.[* GetDraw]();&]
|
||||
[s7; -|-|w.[* StartPage]();&]
|
||||
[s7; -|-|w.DrawText(200, 1200, `"Helo world!`", Arial(600));&]
|
||||
[s7; -|-|w.[* EndPage]();&]
|
||||
[s7; -|-|w.[* StartPage]();&]
|
||||
[s7; -|-|w.DrawText(200, 1200, `"Second page`", Roman(600));&]
|
||||
[s7; -|-|w.[* EndPage]();&]
|
||||
[s7; -|`}&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s0; ]
|
||||
1924
archive/olddraw/Draw/srcdoc.tpp/ImgTutorial$en-us.tpp
Normal file
1924
archive/olddraw/Draw/srcdoc.tpp/ImgTutorial$en-us.tpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue