From be242850ba3a55bcc5620f501ed8914b44dd434d Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 26 May 2013 17:35:34 +0000 Subject: [PATCH] .uppdev git-svn-id: svn://ultimatepp.org/upp/trunk@6106 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppdev/AccessKey/AccessKey.lay | 2 +- uppdev/Glyph/help.txt | 6 ++ uppdev/Glyph/main.cpp | 7 ++ uppdev/RichEditTest/main.cpp | 1 + uppdev/SDL20/SDL20.cpp | 121 ++++++++++----------------------- uppdev/SDL20/SDL20.h | 39 +++++++++++ uppdev/SDL20/SDL20.upp | 13 +++- uppdev/SDL20/SDLDraw.cpp | 111 ++++++++++++++++++++++++++++++ uppdev/SDL20/Window.cpp | 50 ++++++++++++++ uppdev/SDL20/init | 2 + uppdev/SDL20/text.qtf | 65 ++++++++++++++++++ 11 files changed, 329 insertions(+), 88 deletions(-) create mode 100644 uppdev/SDL20/SDL20.h create mode 100644 uppdev/SDL20/SDLDraw.cpp create mode 100644 uppdev/SDL20/Window.cpp create mode 100644 uppdev/SDL20/text.qtf diff --git a/uppdev/AccessKey/AccessKey.lay b/uppdev/AccessKey/AccessKey.lay index f6612ac4e..5f2fb619b 100644 --- a/uppdev/AccessKey/AccessKey.lay +++ b/uppdev/AccessKey/AccessKey.lay @@ -1,7 +1,7 @@ LAYOUT(AccessKeyLayout, 200, 100) ITEM(Base, ok, RightPosZ(90, 80).BottomPosZ(4, 22)) ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(4, 80).BottomPosZ(4, 22)) - ITEM(Label, dv___2, SetLabel(t_("asdfasdf\aTest")).SetFont(SansSerifZ(20)).LeftPosZ(4, 48).TopPosZ(4, 32)) + ITEM(Label, dv___2, SetLabel(t_("asdfasdf\aTest\\a\\n\\b\001asdfasdf")).SetFont(SansSerifZ(20)).LeftPosZ(0, 136).TopPosZ(32, 32)) ITEM(EditDate, dv___3, LeftPosZ(56, 140).TopPosZ(4, 19)) END_LAYOUT diff --git a/uppdev/Glyph/help.txt b/uppdev/Glyph/help.txt index 8b110525e..93694ad8d 100644 --- a/uppdev/Glyph/help.txt +++ b/uppdev/Glyph/help.txt @@ -286,3 +286,9 @@ GUI_APP_MAIN RTIMING("Draw"); // ParseQTF(txt).Paint(Zoom(2, 10), w, 0, 0, sz.cx); } + +TIMING Painter : 2.11 s - 11.39 ms ( 2.11 s / 185 ), min: 7.00 ms, max: 16.00 ms, nesting: 1 - 185 +TIMING Draw : 117.99 ms - 637.79 us (118.00 ms / 185 ), min: 0.00 ns, max: 7.00 ms, nesting: 1 - 185 +TIMING Render glyph : 5.99 ms - 49.95 us ( 6.00 ms / 120 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 120 +TIMING Paint glyph : 944.23 ms - 6.49 us (951.00 ms / 145410 ), min: 0.00 ns, max: 3.00 ms, nesting: 1 - 145410 +TIMING SDraw : 1.10 s - 5.94 ms ( 1.10 s / 185 ), min: 4.00 ms, max: 18.00 ms, nesting: 1 - 185 diff --git a/uppdev/Glyph/main.cpp b/uppdev/Glyph/main.cpp index 5d12bdad0..c7d05a5fe 100644 --- a/uppdev/Glyph/main.cpp +++ b/uppdev/Glyph/main.cpp @@ -81,6 +81,13 @@ void MyApp::Paint(Draw& w) RTIMING("Draw"); txt.Paint(Zoom(2, 10), w, 0, 0, sz.cx); } + if(1) { + RTIMING("Painter"); + ImageBuffer ib(sz); + BufferPainter sw(ib); + sw.Clear(White()); + txt.Paint(Zoom(2, 10), sw, 0, 0, sz.cx); + } /* fw.cloff.Add(); fw.cloff.Top().offset = Point(0, 0); diff --git a/uppdev/RichEditTest/main.cpp b/uppdev/RichEditTest/main.cpp index 91a5fff88..6b3046176 100644 --- a/uppdev/RichEditTest/main.cpp +++ b/uppdev/RichEditTest/main.cpp @@ -50,6 +50,7 @@ GUI_APP_MAIN // w.ToolWindow(); w.SetRect(0, 0, 700, 500); w.Sizeable().Zoomable(); + e.SetReadOnly(); w.Add(e.SizePos()); w.Run(); /* diff --git a/uppdev/SDL20/SDL20.cpp b/uppdev/SDL20/SDL20.cpp index b4a796366..cba251664 100644 --- a/uppdev/SDL20/SDL20.cpp +++ b/uppdev/SDL20/SDL20.cpp @@ -1,9 +1,6 @@ -#include -#include +#include "SDL20.h" -using namespace Upp; - -#include "SDL.h" +#include #define IMAGECLASS TestImg #define IMAGEFILE @@ -13,92 +10,48 @@ using namespace Upp; #define IMAGEFILE #include -SDL_Texture *TextureFromImage(SDL_Renderer *renderer, const Image& m) -{ - Size isz = m.GetSize(); - void *pixels; - int pitch; - SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, isz.cx, isz.cy); - if(SDL_LockTexture(texture, NULL, &pixels, &pitch) >= 0) { - const RGBA *s = ~m; - for(int y = 0; y < isz.cy; y++) { - Copy((RGBA *)((Uint8*)pixels + y * pitch), s, isz.cx); - s += isz.cx; - } - SDL_UnlockTexture(texture); - SDL_SetTextureColorMod(texture, 200, 100, 50); - return texture; - } - - SDL_DestroyTexture(texture); - return NULL; -} - -void DrawImage(SDL_Renderer *renderer, int x, int y, const Image& m) -{ - Size isz = m.GetSize(); - SDL_Texture *tex = TextureFromImage(renderer, m); - SDL_Rect t; - t.x = x; - t.y = y; - t.w = isz.cx; - t.h = isz.cy; - SDL_RenderCopy(renderer, tex, NULL, &t); - SDL_DestroyTexture(tex); -} - -Image DownSample3x(const Image& src) -{ - Size tsz = src.GetSize() / 3; - ImageBuffer ib(tsz); - int w = src.GetSize().cx; - int w2 = 2 * w; - for(int y = 0; y < tsz.cy; y++) { - RGBA *t = ib[y]; - RGBA *e = t + tsz.cx; - const RGBA *s = src[3 * y]; - while(t < e) { - int r, g, b, a; - const RGBA *q; - r = g = b = a = 0; -#define S__SUM(delta) q = s + delta; r += q->r; g += q->g; b += q->b; a += q->a; - S__SUM(0) S__SUM(1) S__SUM(2) - S__SUM(w + 0) S__SUM(w + 1) S__SUM(w + 2) - S__SUM(w2 + 0) S__SUM(w2 + 1) S__SUM(w2 + 2) -#undef S__SUM - t->a = a / 9; - t->r = r / 9; - t->g = g / 9; - t->b = b / 9; - t++; - s += 3; - } - } - return ib; -} - int main(int argc, char** argv){ SDL_Init(SDL_INIT_EVERYTHING); - SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 1600, 900, SDL_WINDOW_SHOWN); - SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + SDLWindow win; + win.Create(RectC(100, 100, 1024, 768), "First test"); + + bool quit = false; int i = 0; - for(;;) { - SDL_RenderClear(ren); - DrawImage(ren, 300, 600, DownSample3x(UPP::Rotate(Magnify(TestImg::pinkie(), 3, 3), 500 * i))); - DrawImage(ren, 100, 800, DownSample3x(UPP::Rotate(Magnify(TestImg::pinkie(), 3, 3), 140 * i))); - DrawImage(ren, 800, 600, DownSample3x(UPP::Rotate(Magnify(TestImg::pinkie(), 3, 3), 70 * i))); - DrawImage(ren, 40, 60, DownSample3x(UPP::Rotate(Magnify(TestImg::pinkie(), 3, 3), 60 * i))); - i++; - SDL_RenderPresent(ren); - + while(!quit) { + SDLDraw w; + w.Set(win); + Size sz = Size(1024, 768); + w.Init(sz); + + w.DrawRect(sz, White); +// w.DrawText(10, 10, "Hello world!", Arial(40)); + +// w.DrawImage(300, 300, TestImg::pinkie()); + + RichText txt = ParseQTF(LoadFile(GetDataFile("text.qtf"))); + if(1) { + RTIMING("SDLDraw"); + txt.Paint(Zoom(2, 10), w, 0, 0, sz.cx); + } + + win.Present(); + + SDL_Event e; + while (SDL_PollEvent(&e)){ + //If user closes he window + if (e.type == SDL_QUIT) + quit = true; + //If user presses any key + if (e.type == SDL_KEYDOWN) + quit = true; + //If user clicks the mouse + if (e.type == SDL_MOUSEBUTTONDOWN) + quit = true; + } SDL_Delay(20); } - SDL_DestroyRenderer(ren); - SDL_DestroyWindow(win); - SDL_Quit(); return 0; } diff --git a/uppdev/SDL20/SDL20.h b/uppdev/SDL20/SDL20.h new file mode 100644 index 000000000..4cf24b52b --- /dev/null +++ b/uppdev/SDL20/SDL20.h @@ -0,0 +1,39 @@ +#ifndef _SDL20_SDL20_h_ +#define _SDL20_SDL20_h_ + +#include + +#include + +using namespace Upp; + +struct SDLWindow { + SDL_Window *win; + SDL_Renderer *ren; + int64 serial; + + bool Create(const Rect& rect, const char *title); + void Destroy(); + + void Present(); + + operator bool() const { return win; } + + SDLWindow(); + ~SDLWindow(); +}; + +struct SDLDraw : SDraw { + SDLWindow *win; + + virtual void PutImage(Point p, const Image& m, const Rect& src); + virtual void PutRect(const Rect& r, Color color); + virtual Image RenderGlyph(Point at, int angle, int chr, Font fnt, Color color, Size sz); + + void Set(SDLWindow& win_); + + SDLDraw(); + ~SDLDraw(); +}; + +#endif diff --git a/uppdev/SDL20/SDL20.upp b/uppdev/SDL20/SDL20.upp index 34adba738..c5c64878f 100644 --- a/uppdev/SDL20/SDL20.upp +++ b/uppdev/SDL20/SDL20.upp @@ -1,11 +1,18 @@ uses Core, - Draw; + Draw, + Painter, + RichText; -library - "SDLmain.lib SDL.lib"; +library(WIN32) "SDLmain.lib SDL.lib"; + +library(POSIX) "SDL2 SDL2main"; file + SDL20.h, + Window.cpp, + SDLDraw.cpp, + text.qtf, SDL20.cpp, test.iml; diff --git a/uppdev/SDL20/SDLDraw.cpp b/uppdev/SDL20/SDLDraw.cpp new file mode 100644 index 000000000..3adb5b682 --- /dev/null +++ b/uppdev/SDL20/SDLDraw.cpp @@ -0,0 +1,111 @@ +#include "SDL20.h" + +#define LLOG(x) // DLOG(x) + +struct RectSDL { + SDL_Rect sr; + + operator SDL_Rect *() { return &sr; } + + RectSDL(const Rect& r) + { + sr.x = r.left; + sr.y = r.top; + sr.w = r.GetWidth(); + sr.h = r.GetHeight(); + } +}; + +SDL_Texture *TextureFromImage(SDL_Renderer *renderer, const Image& m) +{ + Size isz = m.GetSize(); + void *pixels; + int pitch; + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, isz.cx, isz.cy); + if(texture) { + SDL_UpdateTexture(texture, RectSDL(isz), ~m, isz.cx * sizeof(RGBA)); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + } + return texture; +} + +struct ImageSysData { + Image img; + SDL_Texture *texture; + + void Init(SDL_Renderer *renderer, const Image& img); + ~ImageSysData(); +}; + +void ImageSysData::Init(SDL_Renderer *renderer, const Image& m) +{ + img = m; + texture = TextureFromImage(renderer, img); + SysImageRealized(img); +} + +ImageSysData::~ImageSysData() +{ + SysImageReleased(img); + SDL_DestroyTexture(texture); +} + +struct ImageSysDataMaker : LRUCache::Maker { + Image img; + int wserial; + SDL_Renderer *renderer; + + virtual int64 Key() const { return img.GetSerialId(); } // TODO! add ren_serial + virtual int Make(ImageSysData& object) const { object.Init(renderer, img); return img.GetLength(); } +}; + +void SDLDraw::PutImage(Point p, const Image& img, const Rect& src) +{ + if(img.GetLength() == 0 || !win) + return; + LLOG("SysDrawImageOp " << img.GetSerialId() << ' ' << p.x << ", " << p.y << ", "<< img.GetSize()); + ImageSysDataMaker m; + static LRUCache cache; + LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount()); + m.img = img; + m.renderer = win->ren; + m.wserial = win->serial; + ImageSysData& sd = cache.Get(m); + { + RTIMING("SDL_RenderCopy"); + SDL_RenderCopy(win->ren, sd.texture, RectSDL(src), RectSDL(Rect(p, src.GetSize()))); + } + cache.Shrink(4 * 1024 * 768, 1000); // Cache shrink must be after Paint because of PaintOnly! +} + +void SDLDraw::PutRect(const Rect& r, Color color) +{ + if(win && !IsNull(color)) { + SDL_SetRenderDrawColor(win->ren, color.GetR(), color.GetG(), color.GetB(), 255); // Optimize? + SDL_RenderFillRect(win->ren, RectSDL(r)); + } +} + +Image SDLDraw::RenderGlyph(Point at, int angle, int chr, Font fnt, Color color, Size sz) +{ + ImageBuffer ib(sz); + BufferPainter sw(ib); + sw.Clear(RGBAZero()); + sw.DrawText(at.x, at.y, angle, WString(chr, 1), fnt, color); + return ib; +} + +void SDLDraw::Set(SDLWindow& win_) +{ + win = win_.ren ? &win_ : NULL; +} + +SDLDraw::SDLDraw() +{ + win = NULL; +} + +SDLDraw::~SDLDraw() +{ +} diff --git a/uppdev/SDL20/Window.cpp b/uppdev/SDL20/Window.cpp new file mode 100644 index 000000000..4663ebffc --- /dev/null +++ b/uppdev/SDL20/Window.cpp @@ -0,0 +1,50 @@ +#include "SDL20.h" + +bool SDLWindow::Create(const Rect& rect, const char *title) +{ + win = SDL_CreateWindow(title, rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), + SDL_WINDOW_SHOWN); + if(!win) + return false; + MemoryIgnoreLeaksBegin(); + ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + MemoryIgnoreLeaksEnd(); + if(!ren) { + Destroy(); + return false; + } + INTERLOCKED { + static int64 h; + serial = h++; + } + return true; +} + +void SDLWindow::Destroy() +{ + if(ren) { + SDL_DestroyRenderer(ren); + ren = NULL; + } + if(win) { + SDL_DestroyWindow(win); + win = NULL; + } +} + +void SDLWindow::Present() +{ + if(ren) + SDL_RenderPresent(ren); +} + +SDLWindow::SDLWindow() +{ + ren = NULL; + win = NULL; +} + +SDLWindow::~SDLWindow() +{ + Destroy(); +} diff --git a/uppdev/SDL20/init b/uppdev/SDL20/init index 58facd2be..e198f40ef 100644 --- a/uppdev/SDL20/init +++ b/uppdev/SDL20/init @@ -2,4 +2,6 @@ #define _SDL20_icpp_init_stub #include "Core/init" #include "Draw/init" +#include "Painter/init" +#include "RichText/init" #endif diff --git a/uppdev/SDL20/text.qtf b/uppdev/SDL20/text.qtf new file mode 100644 index 000000000..1cd5b9e24 --- /dev/null +++ b/uppdev/SDL20/text.qtf @@ -0,0 +1,65 @@ +[ $$0,0#00000000000000000000000000000000:Default] +[*C@3+75 $$1,1#36268203433472503231438721581057:code] +[*/+117 $$2,0#07143242482611002448121871408047:title] +[@(128.0.255)2 $$3,0#65874547464505293575048467215454:QTF Chr] +[{_}%EN-US +[s0;= [*8 QTF]&] +[s0; &] +[s0; QTF is the native format of Ultimate`+`+ rich texts (formatted +texts).&] +[s0; &] +[s0; It is byte oriented format. Bytes with values 2`-31 are ignored. +Other are interpreted as characters or formatting commands.&] +[s0; &] +[s0; Letters ([@4 a]`-[@4 zA]`-[@4 Z]), numbers ([@4 0]`-[@4 9]), space (32) +and characters&] +[s0; &] +[s0; [*@4 . , ; ! ? % ( ) / < > #]&] +[s0; &] +[s0; and bytes greater than 127 are guaranteed to be never used as +command characters (not even in future versions of QTF). Other +characters should be prefixed with escape character `` (reverse +apostrophe). Group of characters can be escaped using byte 1. +Example:&] +[s0; &] +[s1; `\"`\1a`[x`]`\1`[`* bold`]`\"&] +[s0; &] +[s0; Byte 0 represents the end of input sequence.&] +[s0; &] +[s0; Dimension units of QTF are dots `- one dot is defined as 1/600 +of inch.&] +[s0; &] +[s0; Colors are described as either number [@(128.0.255) 0]`-[@(128.0.255) 9], +with meaning&] +[s0; &] +[ {{1000:1000:1000:1000:1000:1000:1000:1000:1000:1000<96;>96;f4; [s0;%- [* 0]] +:: [s0;%- [* 1]] +:: [s0;%- [* 2]] +:: [s0;%- [* 3]] +:: [s0;%- [* 4]] +:: [s0;%- [* 5]] +:: [s0;%- [* 6]] +:: [s0;%- [* 7]] +:: [s0;%- [* 8]] +:: [s0;%- [* 9]] +::l/0r/0t/0b/0@0 [s0; ] +::@1 [s0; ] +::@2 [s0; ] +::@3 [s0; ] +::@4 [s0; ] +::@5 [s0; ] +::@6 [s0; ] +::@7 [s0; ] +::@8 [s0; ] +::@9 [s0; ] +::l/25r/25t/15b/15@2 [s0;%- [1 Black]] +:: [s0; [1 LtGray]] +:: [s0; [1 White]] +:: [s0;%- [1 Red]] +:: [s0;%- [1 Green]] +:: [s0;%- [1 Blue]] +:: [s0;%- [1 LtRed]] +:: [s0;%- [1 WhiteGray]] +:: [s0;%- [1 LtCyan]] +:: [s0;%- [1 Yellow]]}}&] +[s0; &]