Draw: SDraw

git-svn-id: svn://ultimatepp.org/upp/trunk@6084 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2013-05-19 20:48:58 +00:00
parent 744b470794
commit 8825606e35
10 changed files with 327 additions and 0 deletions

View file

@ -885,6 +885,7 @@ DrawingToPdfFnType GetDrawingToPdfFn();
#include "Display.h"
#include "Cham.h"
#include "DDARasterizer.h"
#include "SDraw.h"
END_UPP_NAMESPACE

View file

@ -61,6 +61,12 @@ file
DDA readonly separator,
DDARasterizer.h,
DDARasterizer.cpp,
SDraw readonly separator,
SDraw.h,
SDrawClip.cpp,
SDrawPut.cpp,
SDrawText.cpp,
SDraw.cpp,
Chameleon readonly separator,
Cham.h,
Cham.cpp,

View file

@ -122,6 +122,37 @@ Image Crop(const Image& img, int x, int y, int cx, int cy)
return Crop(img, RectC(x, y, cx, cy));
}
bool IsUniform(const RGBA *s, RGBA c, int add, int n)
{
while(n-- > 0) {
if(*s != c)
return false;
s += add;
}
return true;
}
Image AutoCrop(const Image& m, RGBA c)
{
Size isz = m.GetSize();
Rect r = isz;
for(r.top = 0; r.top < isz.cy && IsUniform(m[r.top], c, 1, isz.cx); r.top++)
;
for(r.bottom = isz.cy; r.bottom > r.top && IsUniform(m[r.bottom - 1], c, 1, isz.cx); r.bottom--)
;
if(r.bottom <= r.top)
return Null;
int h = r.GetHeight();
const RGBA *p = m[r.top];
for(r.left = 0; r.left < isz.cy && IsUniform(p + r.left, c, isz.cx, h); r.left++)
;
for(r.right = isz.cx; r.right > r.left && IsUniform(p + r.right - 1, c, isz.cx, h); r.right--)
;
Point p1 = m.GetHotSpot() - r.TopLeft();
Point p2 = m.Get2ndSpot() - r.TopLeft();
return WithHotSpots(Crop(m, r), p1.x, p1.y, p2.x, p2.y);
}
Image ColorMask(const Image& src, Color key)
{
ImageBuffer ib(src.GetSize());

View file

@ -18,6 +18,8 @@ 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 AutoCrop(const Image& m, RGBA c);
Image ColorMask(const Image& src, Color transparent);
void CanvasSize(RasterEncoder& tgt, Raster& img, int cx, int cy);

38
uppsrc/Draw/SDraw.cpp Normal file
View file

@ -0,0 +1,38 @@
#include "Draw.h"
NAMESPACE_UPP
dword SDraw::GetInfo() const
{
return DRAWTEXTLINES;
}
void SDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color)
{
// TODO
}
void SDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor)
{
// TODO
}
void SDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color)
{
Width(width);
docolor = color;
Move(Point(x1, y1));
Line(Point(x2, y2));
}
void SDraw::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)
{
// TODO
}
void SDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor)
{
// TODO
}
END_UPP_NAMESPACE

46
uppsrc/Draw/SDraw.h Normal file
View file

@ -0,0 +1,46 @@
struct SDraw : Draw, DDARasterizer {
virtual dword GetInfo() const;
virtual void BeginOp();
virtual bool ClipOp(const Rect& r);
virtual bool ClipoffOp(const Rect& r);
virtual bool IntersectClipOp(const Rect& r);
virtual void OffsetOp(Point p);
virtual bool ExcludeClipOp(const Rect& r);
virtual void EndOp();
virtual bool IsPaintingOp(const Rect& r) const;
virtual void SysDrawImageOp(int x, int y, const Image& img, Color color);
virtual void SysDrawImageOp(int x, int y, const Image& img, const Rect& src, Color color);
virtual void DrawRectOp(int x, int y, int cx, int cy, Color color);
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx);
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
virtual void 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);
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor);
virtual void PutHorz(int x, int y, int cx);
virtual void PutVert(int x, int y, int cy);
private:
struct Cloff {
Vector<Rect> clip;
Point offset;
void operator<<=(const Cloff& b) { clip <<= b.clip; offset = b.offset; }
};
Array<Cloff> cloff;
Color docolor;
public:
virtual void PutImage(Point p, const Image& m, const Rect& src) = 0;
virtual void PutRect(const Rect& r, Color color) = 0;
virtual Image RenderGlyph(Point at, int angle, int chr, Font fnt, Color color, Size sz) = 0;
void Init(const Rect& r);
};

69
uppsrc/Draw/SDrawClip.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "Draw.h"
NAMESPACE_UPP
void SDraw::Init(const Rect& r)
{
Cloff& c = cloff.Add();
c.clip.Add(r);
c.offset = Point(0, 0);
}
void SDraw::BeginOp()
{
Cloff& c = cloff.Top();
cloff.Add() <<= c;
}
bool SDraw::ClipOp(const Rect& r)
{
Cloff& c = cloff.Top();
Cloff& c1 = cloff.Add();
c1.clip = Intersection(c.clip, r + c.offset);
c1.offset = c.offset;
return c1.clip.GetCount();
}
bool SDraw::ClipoffOp(const Rect& r)
{
Cloff& c = cloff.Top();
Cloff& c1 = cloff.Add();
c1.clip = Intersection(c.clip, r + c.offset);
c1.offset = c.offset + r.TopLeft();
return c1.clip.GetCount();
}
bool SDraw::IntersectClipOp(const Rect& r)
{
Cloff& c = cloff.Top();
c.clip = Intersection(c.clip, r + c.offset);
return c.clip.GetCount();
}
bool SDraw::ExcludeClipOp(const Rect& r)
{
Cloff& c = cloff.Top();
bool dummy;
c.clip = Subtract(c.clip, r + c.offset, dummy);
return c.clip.GetCount();
}
bool SDraw::IsPaintingOp(const Rect& r) const
{
return true;
}
void SDraw::OffsetOp(Point p)
{
Cloff& c = cloff.Top();
Cloff& c1 = cloff.Add();
c1.clip <<= c.clip;
c1.offset = c.offset + p;
}
void SDraw::EndOp()
{
cloff.Drop();
}
END_UPP_NAMESPACE

68
uppsrc/Draw/SDrawPut.cpp Normal file
View file

@ -0,0 +1,68 @@
#include "Draw.h"
NAMESPACE_UPP
struct sColorize : public ImageMaker
{
Image img;
Color color;
virtual String Key() const {
StringBuffer h;
RawCat(h, color);
RawCat(h, img.GetSerialId());
return h;
}
virtual Image Make() const {
return SetColorKeepAlpha(img, color);
}
};
void SDraw::SysDrawImageOp(int x, int y, const Image& img, const Rect& src, Color color)
{
if(!IsNull(color)) {
sColorize m;
m.img = img;
m.color = color;
SysDrawImageOp(x, y, MakeImage(m), src, Null);
return;
}
Rect sr(Point(x, y) + cloff.Top().offset, (src & img.GetSize()).GetSize());
const Vector<Rect>& clip = cloff.Top().clip;
for(int i = 0; i < clip.GetCount(); i++) {
Rect cr = clip[i] & sr;
if(!cr.IsEmpty())
PutImage(cr.TopLeft(), img, Rect(cr.TopLeft() - sr.TopLeft() + src.TopLeft(), cr.GetSize()));
}
}
void SDraw::SysDrawImageOp(int x, int y, const Image& img, Color color)
{
SysDrawImageOp(x, y, img, img.GetSize(), color);
}
void SDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
{
Rect r = RectC(x, y, cx, cy);
r += cloff.Top().offset;
const Vector<Rect>& clip = cloff.Top().clip;
for(int i = 0; i < clip.GetCount(); i++) {
Rect cr = clip[i] & r;
if(!cr.IsEmpty())
PutRect(cr, color);
}
}
void SDraw::PutHorz(int x, int y, int cx)
{
DrawRect(x, y, cx, 1, docolor);
}
void SDraw::PutVert(int x, int y, int cy)
{
DrawRect(x, y, 1, cy, docolor);
}
END_UPP_NAMESPACE

60
uppsrc/Draw/SDrawText.cpp Normal file
View file

@ -0,0 +1,60 @@
#include "Draw.h"
#define LTIMING(x) RTIMING(x)
NAMESPACE_UPP
struct sMakeTextGlyph : public ImageMaker
{
int chr;
Font font;
int angle;
Color color;
SDraw *draw;
virtual String Key() const {
StringBuffer h;
RawCat(h, chr);
RawCat(h, font);
RawCat(h, angle);
RawCat(h, color);
return h;
}
virtual Image Make() const {
LTIMING("Render glyph");
Point at(font[chr], font.GetLineHeight());
int n = 2 * (at.x + at.y);
return AutoCrop(WithHotSpot(draw->RenderGlyph(at, angle, chr, font, color, Size(n, n)), at.x, at.y), RGBAZero());
}
};
void SDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx)
{
sMakeTextGlyph g;
g.font = font;
g.color = ink;
g.angle = angle;
g.draw = this;
for(int i = 0; i < n; i++) {
g.chr = text[i];
LTIMING("Paint glyph");
if(font.GetHeight() > 200) {
Point at(font[g.chr], font.GetLineHeight());
int n = at.x + at.y;
Size bandsz(2 * n, 32);
for(int yy = 0; yy < n; yy += bandsz.cy) {
Image m = RenderGlyph(Point(0, -yy), angle, g.chr, font, ink, bandsz);
SysDrawImageOp(x, y + yy, m, m.GetSize(), Null);
}
}
else {
Image m = MakeImage(g);
Point h = m.GetHotSpot();
SysDrawImageOp(x - h.x, y - h.y, m, m.GetSize(), Null);
}
x += dx ? *dx++ : font[g.chr];
}
}
END_UPP_NAMESPACE

View file

@ -306,6 +306,12 @@ mage][@(0.0.255) `&]_[*@3 img], [@(0.0.255) const]_[_^Rect^ Rect][@(0.0.255) `&]
[%-*@3 y], width [%-*@3 cx] and height [%-*@3 cy].&]
[s3;%% &]
[s4; &]
[s5;:AutoCrop`(const Image`&`,RGBA`): [_^Image^ Image]_[* AutoCrop]([@(0.0.255) const]_[_^Image^ I
mage][@(0.0.255) `&]_[*@3 m], [_^RGBA^ RGBA]_[*@3 c])&]
[s2;%% Detects rectangular margin with uniform color [%-*@3 c] and
then crops this margin out.&]
[s3;%% &]
[s4; &]
[s5;:ColorMask`(const Image`&`,Color`): [_^Image^ Image]_[* ColorMask]([@(0.0.255) const]_[_^Image^ I
mage][@(0.0.255) `&]_[*@3 src], [_^Color^ Color]_[*@3 transparent])&]
[s2;%% Returns a new Image based on [%-*@3 src] replaced Color [%-*@3 transparent]