diff --git a/newdraw/Draw/Draw.h b/newdraw/Draw/Draw.h index 5a6b7e1a0..75d40c51e 100644 --- a/newdraw/Draw/Draw.h +++ b/newdraw/Draw/Draw.h @@ -1,916 +1,912 @@ -#ifndef DRAW_H -#define DRAW_H - -#define SYSTEMDRAW 1 - -#include - -#ifdef PLATFORM_X11 - -#define Time XTime -#define Font XFont -#define Display XDisplay -#define Picture XPicture - -#include -#include -#include - -#include -#include - -#undef Picture -#undef Time -#undef Font -#undef Display - -#undef True -#undef False - -#define XFalse 0 -#define XTrue 1 -#endif - - -NAMESPACE_UPP - -#ifdef PLATFORM_X11 - -extern XDisplay *Xdisplay; -extern Visual *Xvisual; -extern int Xscreenno; -extern Window Xroot; -extern Screen *Xscreen; -extern Colormap Xcolormap; -extern int Xheight; -extern int Xwidth; -extern int XheightMM; -extern int XwidthMM; -extern int Xdepth; -extern dword Xblack; -extern dword Xwhite; -extern int Xconnection; - -extern dword (*Xgetpixel)(int r, int g, int b); - -void InitX11Draw(const char *dispname = NULL); -void InitX11Draw(XDisplay *display); - -void XError(); -void XError(const char *s); - -inline dword GetXPixel(int r, int g, int b) { return (*Xgetpixel)(r, g, b); } -inline dword GetXPixel(Color color) { return (*Xgetpixel)(color.GetR(), color.GetG(), color.GetB()); } - -enum { - 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, -}; - -#endif - -class Drawing; -class Draw; -class Painting; -class SystemDraw; - -#ifdef PLATFORM_WIN32 -HDC ScreenHDC(); -#endif - -bool ScreenInPaletteMode(); -Size GetScreenSize(); - -#include "Image.h" - -#ifdef _MULTITHREADED -void EnterGuiMutex(); -void EnterGuiMutex(int n); -void LeaveGuiMutex(); -int LeaveGuiMutexAll(); - -struct GuiLock { - GuiLock() { EnterGuiMutex(); } - ~GuiLock() { LeaveGuiMutex(); } -}; -#else -inline void EnterGuiMutex() {} -inline void EnterGuiMutex(int n) {} -inline void LeaveGuiMutex() {} -inline int LeaveGuiMutexAll() { return 0; } - -struct GuiLock { - GuiLock() {} - ~GuiLock() {} -}; -#endif - -typedef GuiLock DrawLock; - -const int FONT_V = 40; - -#include "FontInt.h" - -class FontInfo; - -class Font : AssignValueTypeNo >{ - union { - int64 data; - struct { - word face; - word flags; - int16 height; - int16 width; - } v; - }; - - static Font AStdFont; - static Size StdFontSize; - - static const Vector& List(); - static void SyncStdFont(); - static void InitStdFont(); - - const CommonFontInfo& Fi() const; - - friend void sInitFonts(); - -public: - enum { - FIXEDPITCH = 0x0001, - SCALEABLE = 0x0002, - LOCAL = 0x0010, - }; - - static int GetFaceCount(); - static String GetFaceName(int index); - static int FindFaceNameIndex(const String& name); - static dword GetFaceInfo(int index); - - static void SetStdFont(Font font); - static Font GetStdFont(); - static Size GetStdFontSize(); - - enum { - STDFONT, - SCREEN_SERIF, - SCREEN_SANS, - SCREEN_FIXED, - ROMAN, - ARIAL, - COURIER, - #ifdef PLATFORM_WIN32 - SYMBOL, - WINGDINGS, - TAHOMA, - #endif - OTHER, - }; - - int GetFace() const { return v.face; } - int GetHeight() const { return v.height; } - int GetWidth() const { return v.width; } - bool IsBold() const { return v.flags & 0x8000; } - bool IsItalic() const { return v.flags & 0x4000; } - bool IsUnderline() const { return v.flags & 0x2000; } - bool IsStrikeout() const { return v.flags & 0x1000; } - bool IsNonAntiAliased() const { return v.flags & 0x800; } - bool IsTrueTypeOnly() const { return v.flags & 0x400; } - String GetFaceName() const; - dword GetFaceInfo() const; - int64 AsInt64() const { return data; } - - Font& Face(int n) { v.face = n; return *this; } - Font& Height(int n) { v.height = n; return *this; } - Font& Width(int n) { v.width = n; return *this; } - Font& Bold() { v.flags |= 0x8000; return *this; } - Font& NoBold() { v.flags &= ~0x8000; return *this; } - Font& Bold(bool b) { return b ? Bold() : NoBold(); } - Font& Italic() { v.flags |= 0x4000; return *this; } - Font& NoItalic() { v.flags &= ~0x4000; return *this; } - Font& Italic(bool b) { return b ? Italic() : NoItalic(); } - Font& Underline() { v.flags |= 0x2000; return *this; } - Font& NoUnderline() { v.flags &= ~0x2000; return *this; } - Font& Underline(bool b) { return b ? Underline() : NoUnderline(); } - Font& Strikeout() { v.flags |= 0x1000; return *this; } - Font& NoStrikeout() { v.flags &= ~0x1000; return *this; } - Font& Strikeout(bool b) { return b ? Strikeout() : NoStrikeout(); } - Font& NonAntiAliased() { v.flags |= 0x800; return *this; } - Font& NoNonAntiAliased() { v.flags &= ~0x800; return *this; } - Font& NonAntiAliased(bool b) { return b ? NonAntiAliased() : NoNonAntiAliased(); } - Font& TrueTypeOnly() { v.flags |= 0x400; return *this; } - Font& NoTrueTypeOnly() { v.flags &= ~0x400; return *this; } - Font& TrueTypeOnly(bool b) { return b ? TrueTypeOnly() : NoTrueTypeOnly(); } - Font& FaceName(const String& name); - - Font operator()() const { return *this; } - Font operator()(int n) const { return Font(*this).Height(n); } - - - int GetAscent() const { return Fi().ascent; } - int GetDescent() const { return Fi().descent; } - int GetCy() const { return Fi().height; } - int GetExternal() const { return Fi().external; } - int GetInternal() const { return Fi().internal; } - int GetLineHeight() const { return Fi().lineheight; } - int GetOverhang() const { return Fi().overhang; } - int GetAveWidth() const { return Fi().avewidth; } - int GetMaxWidth() const { return Fi().maxwidth; } - int HasChar(int ch) const; - int GetWidth(int c) const; - int operator[](int c) const { return GetWidth(c); } - int GetLeftSpace(int c) const; - int GetRightSpace(int c) const; - bool IsFixedPitch() const { return Fi().fixedpitch; } - bool IsScaleable() const { return Fi().scaleable; } -#ifdef PLATFORM_X11 - String GetFontPath() const { return Fi().path; } -#endif - - void Serialize(Stream& s); - - bool operator==(Font f) const { return v.face == f.v.face && v.flags == f.v.flags && - v.width == f.v.width && v.height == f.v.height; } - bool operator!=(Font f) const { return !operator==(f); } - - dword GetHashValue() const { return CombineHash(v.width, v.flags, v.height, v.face); } - bool IsNull() const { return v.face == 0xffff; } - - Font() { v.height = v.width = 0; v.face = v.flags = 0; } - Font(int face, int height) { v.face = face; v.height = height; v.flags = 0; v.width = 0; } - Font(const Nuller&) { v.face = 0xffff; v.height = v.width = 0; v.flags = 0; } - - operator Value() const { return RichValue(*this); } - Font(const Value& q) { *this = RichValue::Extract(q); } - -// BW compatibility - FontInfo Info() const; -}; - -//BW compatibility -class FontInfo { - Font font; - friend class Font; -public: - int GetAscent() const { return font.GetAscent(); } - int GetDescent() const { return font.GetDescent(); } - int GetExternal() const { return font.GetExternal(); } - int GetInternal() const { return font.GetInternal(); } - int GetHeight() const { return font.GetCy(); } - int GetLineHeight() const { return font.GetLineHeight(); } - int GetOverhang() const { return font.GetOverhang(); } - int GetAveWidth() const { return font.GetAveWidth(); } - int GetMaxWidth() const { return font.GetMaxWidth(); } - int HasChar(int c) const { return font.HasChar(c); } - int GetWidth(int c) const { return font.GetWidth(c); } - int operator[](int c) const { return GetWidth(c); } - int GetLeftSpace(int c) const { return font.GetLeftSpace(c); } - int GetRightSpace(int c) const { return font.GetRightSpace(c); } - bool IsFixedPitch() const { return font.IsFixedPitch(); } - bool IsScaleable() const { return font.IsScaleable(); } - int GetFontHeight() const { return font.GetHeight(); } - Font GetFont() const { return font; } -#ifdef PLATFORM_X11 - String GetFileName() const { return font.GetPath(); } -#endif -}; - -struct ComposedGlyph { - wchar basic_char; - Point mark_pos; - wchar mark_char; - Font mark_font; -}; - -bool Compose(Font fnt, int chr, ComposedGlyph& cs); - -template<> -inline bool IsNull(const Font& f) { return f.IsNull(); } - -template<> -inline unsigned GetHashValue(const Font& f) { return f.GetHashValue(); } - -template<> -String AsString(const Font& f); - -inline void SetStdFont(Font font) { Font::SetStdFont(font); } -inline Font GetStdFont() { return Font::GetStdFont(); } -inline Size GetStdFontSize() { return Font::GetStdFontSize(); } -inline int GetStdFontCy() { return GetStdFontSize().cy; } - -Font StdFont(); - -inline Font StdFont(int h) { return StdFont().Height(h); } - -struct ScreenSans : public Font { ScreenSans(int n = 0) : Font(SCREEN_SANS, n) {} }; -struct ScreenSerif : public Font { ScreenSerif(int n = 0) : Font(SCREEN_SERIF, n) {} }; -struct ScreenFixed : public Font { ScreenFixed(int n = 0) : Font(SCREEN_FIXED, n) {} }; - -struct Roman : public Font { Roman(int n) : Font(ROMAN, n) {} }; -struct Arial : public Font { Arial(int n) : Font(ARIAL, n) {} }; -struct Courier : public Font { Courier(int n) : Font(COURIER, n) {} }; -struct Symbol : public Font { Symbol(int n) : Font(SYMBOL, n) {} }; - -#ifdef PLATFORM_WIN32 -struct WingDings : public Font { WingDings(int n) : Font(WINGDINGS, n) {} }; -struct Tahoma : public Font { Tahoma(int n) : Font(TAHOMA, n) {} }; -#endif - -#ifdef PLATFORM_WIN32 -#ifndef PLATFORM_WINCE -HPALETTE GetQlibPalette(); -#endif -#endif - -Size GetTextSize(const wchar *text, Font font, int n = -1); -Size GetTextSize(const WString& text, Font font); -Size GetTextSize(const char *text, byte charset, Font font, int n = -1); -Size GetTextSize(const char *text, Font font, int n = -1); -Size GetTextSize(const String& text, Font font); - -enum { - PEN_NULL = -1, - PEN_SOLID = -2, - PEN_DASH = -3, -#ifndef PLATFORM_WINCE - PEN_DOT = -4, - PEN_DASHDOT = -5, - PEN_DASHDOTDOT = -6, -#endif -}; - -class Image; - -//DEPRECATED: TODO -Color SBlack(); -Color SGray(); -Color SLtGray(); -Color SWhiteGray(); -Color SWhite(); -Color SRed(); -Color SGreen(); -Color SBrown(); -Color SBlue(); -Color SMagenta(); -Color SCyan(); -Color SYellow(); -Color SLtRed(); -Color SLtGreen(); -Color SLtYellow(); -Color SLtBlue(); -Color SLtMagenta(); -Color SLtCyan(); -//END OF DEPRECATED - -Color SColorPaper(); -Color SColorText(); -Color SColorHighlight(); -Color SColorHighlightText();// -Color SColorMenu(); -Color SColorMenuText(); -Color SColorInfo(); -Color SColorInfoText();// -Color SColorMark(); -Color SColorDisabled(); -Color SColorLight(); -Color SColorFace(); -Color SColorLabel(); -Color SColorShadow(); - -Color SColorLtFace(); -Color SColorDkShadow(); - - -void SBlack_Write(Color c); -void SGray_Write(Color c); -void SLtGray_Write(Color c); -void SWhiteGray_Write(Color c); -void SWhite_Write(Color c); -void SRed_Write(Color c); -void SGreen_Write(Color c); -void SBrown_Write(Color c); -void SBlue_Write(Color c); -void SMagenta_Write(Color c); -void SCyan_Write(Color c); -void SYellow_Write(Color c); -void SLtRed_Write(Color c); -void SLtGreen_Write(Color c); -void SLtYellow_Write(Color c); -void SLtBlue_Write(Color c); -void SLtMagenta_Write(Color c); -void SLtCyan_Write(Color c); - -void SColorPaper_Write(Color c); -void SColorText_Write(Color c); -void SColorHighlight_Write(Color c); -void SColorHighlightText_Write(Color c);// -void SColorMenu_Write(Color c); -void SColorMenuText_Write(Color c); -void SColorInfo_Write(Color c); -void SColorInfoText_Write(Color c);// -void SColorMark_Write(Color c); -void SColorDisabled_Write(Color c); -void SColorLight_Write(Color c); -void SColorFace_Write(Color c); -void SColorLabel_Write(Color c); -void SColorShadow_Write(Color c); - -void SColorLtFace_Write(Color c); -void SColorDkShadow_Write(Color c); - - -inline Color InvertColor() { return Color(255, 0); } -inline Color DefaultInk() { return Black(); } //TODO! - -class Painting : AssignValueTypeNo > { - String cmd; - ValueArray data; - Sizef size; - - friend class PaintingPainter; - friend class Painter; - -public: - Sizef GetSize() const { return size; } - - void Clear() { size = Null; data.Clear(); cmd.Clear(); } - void Serialize(Stream& s) { s % cmd % data % size; } - bool IsNullInstance() const { return cmd.IsEmpty(); } - bool operator==(const Painting& b) const { return cmd == b.cmd && data == b.data && size == b.size; } - unsigned GetHashValue() const { return CombineHash(cmd, data); } - String ToString() const { return "painting " + AsString(size); } - - operator Value() const { return RichValue(*this); } - Painting(const Value& q) { *this = RichValue::Extract(q); } - - Painting() { size = Null; } - Painting(const Nuller&) { size = Null; } -}; - -enum { - MODE_ANTIALIASED = 0, - MODE_NOAA = 1, - MODE_SUBPIXEL = 2, -}; - -bool HasPainter(); -void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos, int mode = MODE_ANTIALIASED); -void PaintImageBuffer(ImageBuffer& ib, const Painting& p, int mode = MODE_ANTIALIASED); -void PaintImageBuffer(ImageBuffer& ib, const Drawing& p, int mode = MODE_ANTIALIASED); - -class Draw : NoCopy { -private: - struct DrawingPos; - -public: - enum { - DOTS = 0x001, - GUI = 0x002, - PRINTER = 0x004, - NATIVE = 0x008, - }; - - virtual dword GetInfo() const = 0; - - virtual Size GetPageSize() const; - virtual void StartPage(); - virtual void EndPage(); - - virtual void BeginOp() = 0; - virtual void EndOp() = 0; - virtual void OffsetOp(Point p) = 0; - virtual bool ClipOp(const Rect& r) = 0; - virtual bool ClipoffOp(const Rect& r) = 0; - virtual bool ExcludeClipOp(const Rect& r) = 0; - virtual bool IntersectClipOp(const Rect& r) = 0; - virtual bool IsPaintingOp(const Rect& r) const = 0; - - virtual void DrawRectOp(int x, int y, int cx, int cy, Color color) = 0; - virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) = 0; - virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); - virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) = 0; - - virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, - const int *counts, int count_count, - int width, Color color, Color doxor) = 0; - 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) = 0; - virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) = 0; - - virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) = 0; - virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, - Color ink, int n, const int *dx) = 0; - virtual void DrawDrawingOp(const Rect& target, const Drawing& w); - virtual void DrawPaintingOp(const Rect& target, const Painting& w); - - virtual Size GetNativeDpi() const; - virtual void BeginNative(); - virtual void EndNative(); - - virtual int GetCloffLevel() const; - - virtual ~Draw(); - -// -------------- - Size GetPixelsPerInch() const; - Size GetPageMMs() const; - - bool Dots() const { return GetInfo() & DOTS; } - bool Pixels() const { return !Dots(); } - bool IsGui() const { return GetInfo() & GUI; } - bool IsPrinter() const { return GetInfo() & PRINTER; } - bool IsNative() const { return GetInfo() & NATIVE; } - - int GetNativeX(int x) const; - int GetNativeY(int x) const; - void Native(int& x, int& y) const; - void Native(Point& p) const; - void Native(Size& sz) const; - void Native(Rect& r) const; - - void Begin() { BeginOp(); } - void End() { EndOp(); } - void Offset(Point p) { OffsetOp(p); } - void Offset(int x, int y); - bool Clip(const Rect& r) { return ClipOp(r); } - bool Clip(int x, int y, int cx, int cy); - bool Clipoff(const Rect& r) { return ClipoffOp(r); } - bool Clipoff(int x, int y, int cx, int cy); - bool ExcludeClip(const Rect& r) { return ExcludeClipOp(r); } - bool ExcludeClip(int x, int y, int cx, int cy); - bool IntersectClip(const Rect& r) { return IntersectClipOp(r); } - bool IntersectClip(int x, int y, int cx, int cy); - bool IsPainting(const Rect& r) const { return IsPaintingOp(r); } - bool IsPainting(int x, int y, int cx, int cy) const; - - void DrawRect(int x, int y, int cx, int cy, Color color); - void DrawRect(const Rect& rect, Color color); - - void DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src); - void DrawImage(int x, int y, int cx, int cy, const Image& img); - void DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); - void DrawImage(int x, int y, int cx, int cy, const Image& img, Color color); - - void DrawImage(const Rect& r, const Image& img, const Rect& src); - void DrawImage(const Rect& r, const Image& img); - void DrawImage(const Rect& r, const Image& img, const Rect& src, Color color); - void DrawImage(const Rect& r, const Image& img, Color color); - - void DrawImage(int x, int y, const Image& img, const Rect& src); - void DrawImage(int x, int y, const Image& img); - void DrawImage(int x, int y, const Image& img, const Rect& src, Color color); - void DrawImage(int x, int y, const Image& img, Color color); - - void DrawData(int x, int y, int cx, int cy, const String& data, const char *type); - void DrawData(const Rect& r, const String& data, const char *type); - - void DrawLine(int x1, int y1, int x2, int y2, int width = 0, Color color = DefaultInk); - void DrawLine(Point p1, Point p2, int width = 0, Color color = DefaultInk); - - void DrawEllipse(const Rect& r, Color color = DefaultInk, - int pen = Null, Color pencolor = DefaultInk); - void DrawEllipse(int x, int y, int cx, int cy, Color color = DefaultInk, - int pen = Null, Color pencolor = DefaultInk); - - void DrawArc(const Rect& rc, Point start, Point end, int width = 0, Color color = DefaultInk); - - void DrawPolyPolyline(const Point *vertices, int vertex_count, - const int *counts, int count_count, - int width = 0, Color color = DefaultInk, Color doxor = Null); - void DrawPolyPolyline(const Vector& vertices, const Vector& counts, - int width = 0, Color color = DefaultInk, Color doxor = Null); - void DrawPolyline(const Point *vertices, int count, - int width = 0, Color color = DefaultInk, Color doxor = Null); - void DrawPolyline(const Vector& vertices, - int width = 0, Color color = DefaultInk, Color doxor = Null); - - void DrawPolyPolyPolygon(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 = DefaultInk, int width = 0, Color outline = Null, - uint64 pattern = 0, Color doxor = Null); - void DrawPolyPolyPolygon(const Vector& vertices, - const Vector& subpolygon_counts, - const Vector& disjunct_polygon_counts, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolyPolygon(const Point *vertices, int vertex_count, - const int *subpolygon_counts, int subpolygon_count_count, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolyPolygon(const Vector& vertices, const Vector& subpolygon_counts, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolygons(const Point *vertices, int vertex_count, - const int *polygon_counts, int polygon_count_count, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolygons(const Vector& vertices, const Vector& polygon_counts, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolygon(const Point *vertices, int vertex_count, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - void DrawPolygon(const Vector& vertices, - Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); - - void DrawDrawing(const Rect& r, const Drawing& iw) { DrawDrawingOp(r, iw); } - void DrawDrawing(int x, int y, int cx, int cy, const Drawing& iw); - - void DrawPainting(const Rect& r, const Painting& iw) { DrawPaintingOp(r, iw); } - void DrawPainting(int x, int y, int cx, int cy, const Painting& iw); - - void DrawText(int x, int y, int angle, const wchar *text, Font font = StdFont(), - Color ink = DefaultInk, int n = -1, const int *dx = NULL); - void DrawText(int x, int y, const wchar *text, Font font = StdFont(), - Color ink = DefaultInk, int n = -1, const int *dx = NULL); - - void DrawText(int x, int y, const WString& text, Font font = StdFont(), - Color ink = DefaultInk, const int *dx = NULL); - void DrawText(int x, int y, int angle, const WString& text, Font font = StdFont(), - Color ink = DefaultInk, const int *dx = NULL); - - void DrawText(int x, int y, int angle, const char *text, byte charset, - Font font = StdFont(), Color ink = DefaultInk, int n = -1, const int *dx = NULL); - void DrawText(int x, int y, const char *text, byte charset, Font font = StdFont(), - Color ink = DefaultInk, int n = -1, const int *dx = NULL); - - void DrawText(int x, int y, int angle, const char *text, - Font font = StdFont(), Color ink = DefaultInk, int n = -1, const int *dx = NULL); - void DrawText(int x, int y, const char *text, Font font = StdFont(), - Color ink = DefaultInk, int n = -1, const int *dx = NULL); - - void DrawText(int x, int y, const String& text, Font font = StdFont(), - Color ink = DefaultInk, const int *dx = NULL); - void DrawText(int x, int y, int angle, const String& text, Font font = StdFont(), - Color ink = DefaultInk, const int *dx = NULL); - - static void SinCos(int angle, double& sina, double& cosa); - - // deprecated: - static void SetStdFont(Font font) { UPP::SetStdFont(font); } - static Font GetStdFont() { return UPP::GetStdFont(); } - static Size GetStdFontSize() { return UPP::GetStdFontSize(); } - static int GetStdFontCy() { return GetStdFontSize().cy; } - - -#ifdef PLATFORM_WIN32_ - static void Flush(); - HDC BeginGdi(); - void EndGdi(); -#endif -}; - -void DrawImageBandRLE(Draw& w, int x, int y, const Image& m, int minp); - -class DataDrawer { - typedef DataDrawer *(*Factory)(); - template static DataDrawer *FactoryFn() { return new T; } - static void AddFormat(const char *id, Factory f); - static VectorMap& Map(); - -public: - virtual void Open(const String& data, int cx, int cy) = 0; - virtual void Render(ImageBuffer& ib) = 0; - virtual ~DataDrawer(); - - static One Create(const String& id); - - template static void Register(const char *id) { AddFormat(id, &DataDrawer::FactoryFn); } -}; - -class Drawing : AssignValueTypeNo > { - Size size; - String data; - ValueArray val; - - friend class DrawingDraw; - friend class Draw; - -public: - operator bool() const { return !data.IsEmpty(); } - Size GetSize() const { return size; } - void SetSize(Size sz) { size = sz; } - void SetSize(int cx, int cy) { size = Size(cx, cy); } - - Size RatioSize(int cx, int cy) const; - Size RatioSize(Size sz) const { return RatioSize(sz.cx, sz.cy); } - - void Clear() { data.Clear(); size = Null; } - - void Append(Drawing& dw); - - void Serialize(Stream& s); - - bool IsNullInstance() const { return data.IsEmpty(); } - bool operator==(const Drawing& b) const { return val == b.val && data == b.data && size == b.size; } - String ToString() const { return "drawing " + AsString(size); } - unsigned GetHashValue() const { return CombineHash(data, val); } - - operator Value() const { return RichValue(*this); } - Drawing(const Value& src); - - Drawing() { size = Null; } - Drawing(const Nuller&) { size = Null; } -}; - -class DrawingDraw : public Draw { -public: - virtual dword GetInfo() const; - virtual Size GetPageSize() const; - virtual void BeginOp(); - virtual void EndOp(); - virtual void OffsetOp(Point p); - virtual bool ClipOp(const Rect& r); - virtual bool ClipoffOp(const Rect& r); - virtual bool ExcludeClipOp(const Rect& r); - virtual bool IntersectClipOp(const Rect& r); - virtual bool IsPaintingOp(const Rect& r) const; - - virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); - virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); - virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); - virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); - virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, - const int *counts, int count_count, - int width, Color color, Color doxor); - 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 DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor); - virtual void DrawArcOp(const Rect& rc, Point start, Point end, int pen, Color pencolor); - virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, - Color ink, int n, const int *dx); - - virtual void DrawDrawingOp(const Rect& target, const Drawing& w); - virtual void DrawPaintingOp(const Rect& target, const Painting& w); - -private: - Size size; - StringStream drawing; - ValueArray val; - - Stream& DrawingOp(int code); - -public: - void Create(int cx, int cy); - void Create(Size sz); - - Size GetSize() const { return size; } - - Drawing GetResult(); - operator Drawing() { return GetResult(); } - - DrawingDraw(); - DrawingDraw(int cx, int cy); - DrawingDraw(Size sz); -}; - -class NilDraw : public Draw { -public: - virtual dword GetInfo() const; - virtual Size GetPageSize() const; - virtual void BeginOp(); - virtual void EndOp(); - virtual void OffsetOp(Point p); - virtual bool ClipOp(const Rect& r); - virtual bool ClipoffOp(const Rect& r); - virtual bool ExcludeClipOp(const Rect& r); - virtual bool IntersectClipOp(const Rect& r); - virtual bool IsPaintingOp(const Rect& r) const; - - virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); - virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); - virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); - virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); - virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, - const int *counts, int count_count, - int width, Color color, Color doxor); - 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 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 DrawTextOp(int x, int y, int angle, const wchar *text, Font font, - Color ink, int n, const int *dx); - virtual void DrawDrawingOp(const Rect& target, const Drawing& w); - virtual void DrawPaintingOp(const Rect& target, const Painting& w); -}; - -void AddNotEmpty(Vector& result, int left, int right, int top, int bottom); -bool Subtract(const Rect& r, const Rect& sub, Vector& result); -bool Subtract(const Vector& rr, const Rect& sub, Vector& result); -Vector Subtract(const Vector& rr, const Rect& sub, bool& changed); -Vector Intersect(const Vector& b, const Rect& a, bool& changed); - -void Subtract(Vector& rr, const Rect& sub); -void Union(Vector& rr, const Rect& add); - -#ifdef PLATFORM_X11 -void SetClip(GC gc, XftDraw *xftdraw, const Vector& cl); -#endif - -void DrawRect(Draw& w, const Rect& rect, const Image& img, bool ralgn = false); //??? TODO -void DrawRect(Draw& w, int x, int y, int cx, int cy, const Image& img, bool ra = false); - -void DrawTiles(Draw& w, int x, int y, int cx, int cy, const Image& img); -void DrawTiles(Draw& w, const Rect& rect, const Image& img); - -void DrawFatFrame(Draw& w, int x, int y, int cx, int cy, Color color, int n); -void DrawFatFrame(Draw& w, const Rect& r, Color color, int n); - -void DrawFrame(Draw& w, int x, int y, int cx, int cy, - Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor); -void DrawFrame(Draw& w, const Rect& r, - Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor); -void DrawFrame(Draw& w, int x, int y, int cx, int cy, - Color topleftcolor, Color bottomrightcolor); -void DrawFrame(Draw& w, const Rect& r, - Color topleftcolor, Color bottomrightcolor); -void DrawFrame(Draw& w, int x, int y, int cx, int cy, Color color); -void DrawFrame(Draw& w, const Rect& r, Color color); - -void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *colors_ltrd); //TODO -void DrawBorder(Draw& w, const Rect& r, const ColorF *colors_ltrd); - -const ColorF *BlackBorder(); -const ColorF *ButtonPushBorder(); -const ColorF *EdgeButtonBorder(); -const ColorF *DefButtonBorder(); -const ColorF *ButtonBorder(); -const ColorF *InsetBorder(); -const ColorF *OutsetBorder(); -const ColorF *ThinOutsetBorder(); -const ColorF *ThinInsetBorder(); - -void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *(*colors_ltrd)()); -void DrawBorder(Draw& w, const Rect& r, const ColorF *(*colors_ltrd)()); - -void DrawRectMinusRect(Draw& w, const Rect& rect, const Rect& inner, Color color); - -void DrawHighlightImage(Draw& w, int x, int y, const Image& img, bool highlight = true, - bool enabled = true, Color maskcolor = SColorPaper); - -Color GradientColor(Color fc, Color tc, int i, int n); - -void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, uint64 pattern); - -enum { - BUTTON_NORMAL, BUTTON_OK, BUTTON_HIGHLIGHT, BUTTON_PUSH, BUTTON_DISABLED, BUTTON_CHECKED, - BUTTON_VERTICAL = 0x100, - BUTTON_EDGE = 0x200, - BUTTON_TOOL = 0x400, - BUTTON_SCROLL = 0x800, -}; - -void DrawXPButton(Draw& w, Rect r, int type); - -void DrawTextEllipsis(Draw& w, int x, int y, int cx, const char *text, const char *ellipsis, - Font font = StdFont(), Color ink = SColorText(), int n = -1); -void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const char *ellipsis, - Font font = StdFont(), Color ink = SColorText(), int n = -1); -Size GetTLTextSize(const wchar *text, Font font = StdFont()); -int GetTLTextHeight(const wchar *s, Font font = StdFont()); -void DrawTLText(Draw& draw, int x, int y, int cx, const wchar *text, Font font = StdFont(), - Color ink = SColorText(), int accesskey = 0); - - -typedef String (*DrawingToPdfFnType)(const Array& report, Size pagesize, int margin); - -void SetDrawingToPdfFn(DrawingToPdfFnType Pdf); -DrawingToPdfFnType GetDrawingToPdfFn(); - -#ifdef PLATFORM_WIN32 -#include "DrawWin32.h" -#endif - -#ifdef PLATFORM_X11 -#include "DrawX11.h" -#endif - -#include "SystemDraw.h" - -#include "Display.h" -#include "Debug.h" -#include "Cham.h" - -typedef ImageDraw SystemImageDraw; - -END_UPP_NAMESPACE - -#endif +#ifndef DRAW_H +#define DRAW_H + +#define SYSTEMDRAW 1 + +#include + +#ifdef PLATFORM_X11 + +#define Time XTime +#define Font XFont +#define Display XDisplay +#define Picture XPicture + +#include +#include +#include + +#include +#include + +#undef Picture +#undef Time +#undef Font +#undef Display + +#undef True +#undef False + +#define XFalse 0 +#define XTrue 1 +#endif + + +NAMESPACE_UPP + +#ifdef PLATFORM_X11 + +extern XDisplay *Xdisplay; +extern Visual *Xvisual; +extern int Xscreenno; +extern Window Xroot; +extern Screen *Xscreen; +extern Colormap Xcolormap; +extern int Xheight; +extern int Xwidth; +extern int XheightMM; +extern int XwidthMM; +extern int Xdepth; +extern dword Xblack; +extern dword Xwhite; +extern int Xconnection; + +extern dword (*Xgetpixel)(int r, int g, int b); + +void InitX11Draw(const char *dispname = NULL); +void InitX11Draw(XDisplay *display); + +void XError(); +void XError(const char *s); + +inline dword GetXPixel(int r, int g, int b) { return (*Xgetpixel)(r, g, b); } +inline dword GetXPixel(Color color) { return (*Xgetpixel)(color.GetR(), color.GetG(), color.GetB()); } + +enum { + 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, +}; + +#endif + +class Drawing; +class Draw; +class Painting; +class SystemDraw; + +#ifdef PLATFORM_WIN32 +HDC ScreenHDC(); +#endif + +bool ScreenInPaletteMode(); +Size GetScreenSize(); + +#include "Image.h" + +#ifdef _MULTITHREADED +void EnterGuiMutex(); +void EnterGuiMutex(int n); +void LeaveGuiMutex(); +int LeaveGuiMutexAll(); + +struct GuiLock { + GuiLock() { EnterGuiMutex(); } + ~GuiLock() { LeaveGuiMutex(); } +}; +#else +inline void EnterGuiMutex() {} +inline void EnterGuiMutex(int n) {} +inline void LeaveGuiMutex() {} +inline int LeaveGuiMutexAll() { return 0; } + +struct GuiLock { + GuiLock() {} + ~GuiLock() {} +}; +#endif + +typedef GuiLock DrawLock; + +const int FONT_V = 40; + +#include "FontInt.h" + +class FontInfo; + +class Font : AssignValueTypeNo >{ + union { + int64 data; + struct { + word face; + word flags; + int16 height; + int16 width; + } v; + }; + + static Font AStdFont; + static Size StdFontSize; + + static const Vector& List(); + static void SyncStdFont(); + static void InitStdFont(); + + const CommonFontInfo& Fi() const; + + friend void sInitFonts(); + +public: + enum { + FIXEDPITCH = 0x0001, + SCALEABLE = 0x0002, + LOCAL = 0x0010, + }; + + static int GetFaceCount(); + static String GetFaceName(int index); + static int FindFaceNameIndex(const String& name); + static dword GetFaceInfo(int index); + + static void SetStdFont(Font font); + static Font GetStdFont(); + static Size GetStdFontSize(); + + enum { + STDFONT, + SCREEN_SERIF, + SCREEN_SANS, + SCREEN_FIXED, + ROMAN, + ARIAL, + COURIER, + #ifdef PLATFORM_WIN32 + SYMBOL, + WINGDINGS, + TAHOMA, + #endif + OTHER, + }; + + int GetFace() const { return v.face; } + int GetHeight() const; + int GetWidth() const { return v.width; } + bool IsBold() const { return v.flags & 0x8000; } + bool IsItalic() const { return v.flags & 0x4000; } + bool IsUnderline() const { return v.flags & 0x2000; } + bool IsStrikeout() const { return v.flags & 0x1000; } + bool IsNonAntiAliased() const { return v.flags & 0x800; } + bool IsTrueTypeOnly() const { return v.flags & 0x400; } + String GetFaceName() const; + dword GetFaceInfo() const; + int64 AsInt64() const { return data; } + + Font& Face(int n) { v.face = n; return *this; } + Font& Height(int n) { v.height = n; return *this; } + Font& Width(int n) { v.width = n; return *this; } + Font& Bold() { v.flags |= 0x8000; return *this; } + Font& NoBold() { v.flags &= ~0x8000; return *this; } + Font& Bold(bool b) { return b ? Bold() : NoBold(); } + Font& Italic() { v.flags |= 0x4000; return *this; } + Font& NoItalic() { v.flags &= ~0x4000; return *this; } + Font& Italic(bool b) { return b ? Italic() : NoItalic(); } + Font& Underline() { v.flags |= 0x2000; return *this; } + Font& NoUnderline() { v.flags &= ~0x2000; return *this; } + Font& Underline(bool b) { return b ? Underline() : NoUnderline(); } + Font& Strikeout() { v.flags |= 0x1000; return *this; } + Font& NoStrikeout() { v.flags &= ~0x1000; return *this; } + Font& Strikeout(bool b) { return b ? Strikeout() : NoStrikeout(); } + Font& NonAntiAliased() { v.flags |= 0x800; return *this; } + Font& NoNonAntiAliased() { v.flags &= ~0x800; return *this; } + Font& NonAntiAliased(bool b) { return b ? NonAntiAliased() : NoNonAntiAliased(); } + Font& TrueTypeOnly() { v.flags |= 0x400; return *this; } + Font& NoTrueTypeOnly() { v.flags &= ~0x400; return *this; } + Font& TrueTypeOnly(bool b) { return b ? TrueTypeOnly() : NoTrueTypeOnly(); } + Font& FaceName(const String& name); + + Font operator()() const { return *this; } + Font operator()(int n) const { return Font(*this).Height(n); } + + + int GetAscent() const { return Fi().ascent; } + int GetDescent() const { return Fi().descent; } + int GetCy() const { return Fi().height; } + int GetExternal() const { return Fi().external; } + int GetInternal() const { return Fi().internal; } + int GetLineHeight() const { return Fi().lineheight; } + int GetOverhang() const { return Fi().overhang; } + int GetAveWidth() const { return Fi().avewidth; } + int GetMaxWidth() const { return Fi().maxwidth; } + int HasChar(int ch) const; + int GetWidth(int c) const; + int operator[](int c) const { return GetWidth(c); } + int GetLeftSpace(int c) const; + int GetRightSpace(int c) const; + bool IsFixedPitch() const { return Fi().fixedpitch; } + bool IsScaleable() const { return Fi().scaleable; } +#ifdef PLATFORM_POSIX + String GetPath() const { return Fi().path; } +#endif + + void Serialize(Stream& s); + + bool operator==(Font f) const { return v.face == f.v.face && v.flags == f.v.flags && + v.width == f.v.width && v.height == f.v.height; } + bool operator!=(Font f) const { return !operator==(f); } + + dword GetHashValue() const { return CombineHash(v.width, v.flags, v.height, v.face); } + bool IsNull() const { return v.face == 0xffff; } + + Font() { v.height = v.width = 0; v.face = v.flags = 0; } + Font(int face, int height) { v.face = face; v.height = height; v.flags = 0; v.width = 0; } + Font(const Nuller&) { v.face = 0xffff; v.height = v.width = 0; v.flags = 0; } + + operator Value() const { return RichValue(*this); } + Font(const Value& q) { *this = RichValue::Extract(q); } + +// BW compatibility + FontInfo Info() const; +}; + +//BW compatibility +class FontInfo { + Font font; + friend class Font; +public: + int GetAscent() const { return font.GetAscent(); } + int GetDescent() const { return font.GetDescent(); } + int GetExternal() const { return font.GetExternal(); } + int GetInternal() const { return font.GetInternal(); } + int GetHeight() const { return font.GetCy(); } + int GetLineHeight() const { return font.GetLineHeight(); } + int GetOverhang() const { return font.GetOverhang(); } + int GetAveWidth() const { return font.GetAveWidth(); } + int GetMaxWidth() const { return font.GetMaxWidth(); } + int HasChar(int c) const { return font.HasChar(c); } + int GetWidth(int c) const { return font.GetWidth(c); } + int operator[](int c) const { return GetWidth(c); } + int GetLeftSpace(int c) const { return font.GetLeftSpace(c); } + int GetRightSpace(int c) const { return font.GetRightSpace(c); } + bool IsFixedPitch() const { return font.IsFixedPitch(); } + bool IsScaleable() const { return font.IsScaleable(); } + int GetFontHeight() const { return font.GetHeight(); } + Font GetFont() const { return font; } +#ifdef PLATFORM_POSIX + String GetFileName() const { return font.GetPath(); } +#endif +}; + +struct ComposedGlyph { + wchar basic_char; + Point mark_pos; + wchar mark_char; + Font mark_font; +}; + +bool Compose(Font fnt, int chr, ComposedGlyph& cs); + +template<> +inline bool IsNull(const Font& f) { return f.IsNull(); } + +template<> +inline unsigned GetHashValue(const Font& f) { return f.GetHashValue(); } + +template<> +String AsString(const Font& f); + +inline void SetStdFont(Font font) { Font::SetStdFont(font); } +inline Font GetStdFont() { return Font::GetStdFont(); } +inline Size GetStdFontSize() { return Font::GetStdFontSize(); } +inline int GetStdFontCy() { return GetStdFontSize().cy; } + +Font StdFont(); + +inline Font StdFont(int h) { return StdFont().Height(h); } + +struct ScreenSans : public Font { ScreenSans(int n = 0) : Font(SCREEN_SANS, n) {} }; +struct ScreenSerif : public Font { ScreenSerif(int n = 0) : Font(SCREEN_SERIF, n) {} }; +struct ScreenFixed : public Font { ScreenFixed(int n = 0) : Font(SCREEN_FIXED, n) {} }; + +struct Roman : public Font { Roman(int n) : Font(ROMAN, n) {} }; +struct Arial : public Font { Arial(int n) : Font(ARIAL, n) {} }; +struct Courier : public Font { Courier(int n) : Font(COURIER, n) {} }; + +#ifdef PLATFORM_WIN32 +struct Symbol : public Font { Symbol(int n) : Font(SYMBOL, n) {} }; +struct WingDings : public Font { WingDings(int n) : Font(WINGDINGS, n) {} }; +struct Tahoma : public Font { Tahoma(int n) : Font(TAHOMA, n) {} }; +#endif + +#ifdef PLATFORM_WIN32 +#ifndef PLATFORM_WINCE +HPALETTE GetQlibPalette(); +#endif +#endif + +Size GetTextSize(const wchar *text, Font font, int n = -1); +Size GetTextSize(const WString& text, Font font); +Size GetTextSize(const char *text, byte charset, Font font, int n = -1); +Size GetTextSize(const char *text, Font font, int n = -1); +Size GetTextSize(const String& text, Font font); + +enum { + PEN_NULL = -1, + PEN_SOLID = -2, + PEN_DASH = -3, +#ifndef PLATFORM_WINCE + PEN_DOT = -4, + PEN_DASHDOT = -5, + PEN_DASHDOTDOT = -6, +#endif +}; + +class Image; + +//DEPRECATED: TODO +Color SBlack(); +Color SGray(); +Color SLtGray(); +Color SWhiteGray(); +Color SWhite(); +Color SRed(); +Color SGreen(); +Color SBrown(); +Color SBlue(); +Color SMagenta(); +Color SCyan(); +Color SYellow(); +Color SLtRed(); +Color SLtGreen(); +Color SLtYellow(); +Color SLtBlue(); +Color SLtMagenta(); +Color SLtCyan(); +//END OF DEPRECATED + +Color SColorPaper(); +Color SColorText(); +Color SColorHighlight(); +Color SColorHighlightText();// +Color SColorMenu(); +Color SColorMenuText(); +Color SColorInfo(); +Color SColorInfoText();// +Color SColorMark(); +Color SColorDisabled(); +Color SColorLight(); +Color SColorFace(); +Color SColorLabel(); +Color SColorShadow(); + +Color SColorLtFace(); +Color SColorDkShadow(); + + +void SBlack_Write(Color c); +void SGray_Write(Color c); +void SLtGray_Write(Color c); +void SWhiteGray_Write(Color c); +void SWhite_Write(Color c); +void SRed_Write(Color c); +void SGreen_Write(Color c); +void SBrown_Write(Color c); +void SBlue_Write(Color c); +void SMagenta_Write(Color c); +void SCyan_Write(Color c); +void SYellow_Write(Color c); +void SLtRed_Write(Color c); +void SLtGreen_Write(Color c); +void SLtYellow_Write(Color c); +void SLtBlue_Write(Color c); +void SLtMagenta_Write(Color c); +void SLtCyan_Write(Color c); + +void SColorPaper_Write(Color c); +void SColorText_Write(Color c); +void SColorHighlight_Write(Color c); +void SColorHighlightText_Write(Color c);// +void SColorMenu_Write(Color c); +void SColorMenuText_Write(Color c); +void SColorInfo_Write(Color c); +void SColorInfoText_Write(Color c);// +void SColorMark_Write(Color c); +void SColorDisabled_Write(Color c); +void SColorLight_Write(Color c); +void SColorFace_Write(Color c); +void SColorLabel_Write(Color c); +void SColorShadow_Write(Color c); + +void SColorLtFace_Write(Color c); +void SColorDkShadow_Write(Color c); + + +inline Color InvertColor() { return Color(255, 0); } +inline Color DefaultInk() { return Black(); } //TODO! + +class Painting : AssignValueTypeNo > { + String cmd; + ValueArray data; + Sizef size; + + friend class PaintingPainter; + friend class Painter; + +public: + Sizef GetSize() const { return size; } + + void Clear() { size = Null; data.Clear(); cmd.Clear(); } + void Serialize(Stream& s) { s % cmd % data % size; } + bool IsNullInstance() const { return cmd.IsEmpty(); } + bool operator==(const Painting& b) const { return cmd == b.cmd && data == b.data && size == b.size; } + unsigned GetHashValue() const { return CombineHash(cmd, data); } + String ToString() const { return "painting " + AsString(size); } + + operator Value() const { return RichValue(*this); } + Painting(const Value& q) { *this = RichValue::Extract(q); } + + Painting() { size = Null; } + Painting(const Nuller&) { size = Null; } +}; + +enum { + MODE_ANTIALIASED = 0, + MODE_NOAA = 1, + MODE_SUBPIXEL = 2, +}; + +bool HasPainter(); +void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos, int mode = MODE_ANTIALIASED); +void PaintImageBuffer(ImageBuffer& ib, const Painting& p, int mode = MODE_ANTIALIASED); +void PaintImageBuffer(ImageBuffer& ib, const Drawing& p, int mode = MODE_ANTIALIASED); + +class Draw : NoCopy { +private: + struct DrawingPos; + +public: + enum { + DOTS = 0x001, + GUI = 0x002, + PRINTER = 0x004, + NATIVE = 0x008, + }; + + virtual dword GetInfo() const = 0; + + virtual Size GetPageSize() const; + virtual void StartPage(); + virtual void EndPage(); + + virtual void BeginOp() = 0; + virtual void EndOp() = 0; + virtual void OffsetOp(Point p) = 0; + virtual bool ClipOp(const Rect& r) = 0; + virtual bool ClipoffOp(const Rect& r) = 0; + virtual bool ExcludeClipOp(const Rect& r) = 0; + virtual bool IntersectClipOp(const Rect& r) = 0; + virtual bool IsPaintingOp(const Rect& r) const = 0; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color) = 0; + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) = 0; + virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) = 0; + + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor) = 0; + 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) = 0; + virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) = 0; + + virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) = 0; + virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx) = 0; + virtual void DrawDrawingOp(const Rect& target, const Drawing& w); + virtual void DrawPaintingOp(const Rect& target, const Painting& w); + + virtual Size GetNativeDpi() const; + virtual void BeginNative(); + virtual void EndNative(); + + virtual int GetCloffLevel() const; + + virtual ~Draw(); + +// -------------- + Size GetPixelsPerInch() const; + Size GetPageMMs() const; + + bool Dots() const { return GetInfo() & DOTS; } + bool Pixels() const { return !Dots(); } + bool IsGui() const { return GetInfo() & GUI; } + bool IsPrinter() const { return GetInfo() & PRINTER; } + bool IsNative() const { return GetInfo() & NATIVE; } + + int GetNativeX(int x) const; + int GetNativeY(int x) const; + void Native(int& x, int& y) const; + void Native(Point& p) const; + void Native(Size& sz) const; + void Native(Rect& r) const; + + void Begin() { BeginOp(); } + void End() { EndOp(); } + void Offset(Point p) { OffsetOp(p); } + void Offset(int x, int y); + bool Clip(const Rect& r) { return ClipOp(r); } + bool Clip(int x, int y, int cx, int cy); + bool Clipoff(const Rect& r) { return ClipoffOp(r); } + bool Clipoff(int x, int y, int cx, int cy); + bool ExcludeClip(const Rect& r) { return ExcludeClipOp(r); } + bool ExcludeClip(int x, int y, int cx, int cy); + bool IntersectClip(const Rect& r) { return IntersectClipOp(r); } + bool IntersectClip(int x, int y, int cx, int cy); + bool IsPainting(const Rect& r) const { return IsPaintingOp(r); } + bool IsPainting(int x, int y, int cx, int cy) const; + + void DrawRect(int x, int y, int cx, int cy, Color color); + void DrawRect(const Rect& rect, Color color); + + void DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src); + void DrawImage(int x, int y, int cx, int cy, const Image& img); + void DrawImage(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + void DrawImage(int x, int y, int cx, int cy, const Image& img, Color color); + + void DrawImage(const Rect& r, const Image& img, const Rect& src); + void DrawImage(const Rect& r, const Image& img); + void DrawImage(const Rect& r, const Image& img, const Rect& src, Color color); + void DrawImage(const Rect& r, const Image& img, Color color); + + void DrawImage(int x, int y, const Image& img, const Rect& src); + void DrawImage(int x, int y, const Image& img); + void DrawImage(int x, int y, const Image& img, const Rect& src, Color color); + void DrawImage(int x, int y, const Image& img, Color color); + + void DrawData(int x, int y, int cx, int cy, const String& data, const char *type); + void DrawData(const Rect& r, const String& data, const char *type); + + void DrawLine(int x1, int y1, int x2, int y2, int width = 0, Color color = DefaultInk); + void DrawLine(Point p1, Point p2, int width = 0, Color color = DefaultInk); + + void DrawEllipse(const Rect& r, Color color = DefaultInk, + int pen = Null, Color pencolor = DefaultInk); + void DrawEllipse(int x, int y, int cx, int cy, Color color = DefaultInk, + int pen = Null, Color pencolor = DefaultInk); + + void DrawArc(const Rect& rc, Point start, Point end, int width = 0, Color color = DefaultInk); + + void DrawPolyPolyline(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width = 0, Color color = DefaultInk, Color doxor = Null); + void DrawPolyPolyline(const Vector& vertices, const Vector& counts, + int width = 0, Color color = DefaultInk, Color doxor = Null); + void DrawPolyline(const Point *vertices, int count, + int width = 0, Color color = DefaultInk, Color doxor = Null); + void DrawPolyline(const Vector& vertices, + int width = 0, Color color = DefaultInk, Color doxor = Null); + + void DrawPolyPolyPolygon(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 = DefaultInk, int width = 0, Color outline = Null, + uint64 pattern = 0, Color doxor = Null); + void DrawPolyPolyPolygon(const Vector& vertices, + const Vector& subpolygon_counts, + const Vector& disjunct_polygon_counts, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolyPolygon(const Point *vertices, int vertex_count, + const int *subpolygon_counts, int subpolygon_count_count, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolyPolygon(const Vector& vertices, const Vector& subpolygon_counts, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolygons(const Point *vertices, int vertex_count, + const int *polygon_counts, int polygon_count_count, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolygons(const Vector& vertices, const Vector& polygon_counts, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolygon(const Point *vertices, int vertex_count, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + void DrawPolygon(const Vector& vertices, + Color color = DefaultInk, int width = 0, Color outline = Null, uint64 pattern = 0, Color doxor = Null); + + void DrawDrawing(const Rect& r, const Drawing& iw) { DrawDrawingOp(r, iw); } + void DrawDrawing(int x, int y, int cx, int cy, const Drawing& iw); + + void DrawPainting(const Rect& r, const Painting& iw) { DrawPaintingOp(r, iw); } + void DrawPainting(int x, int y, int cx, int cy, const Painting& iw); + + void DrawText(int x, int y, int angle, const wchar *text, Font font = StdFont(), + Color ink = DefaultInk, int n = -1, const int *dx = NULL); + void DrawText(int x, int y, const wchar *text, Font font = StdFont(), + Color ink = DefaultInk, int n = -1, const int *dx = NULL); + + void DrawText(int x, int y, const WString& text, Font font = StdFont(), + Color ink = DefaultInk, const int *dx = NULL); + void DrawText(int x, int y, int angle, const WString& text, Font font = StdFont(), + Color ink = DefaultInk, const int *dx = NULL); + + void DrawText(int x, int y, int angle, const char *text, byte charset, + Font font = StdFont(), Color ink = DefaultInk, int n = -1, const int *dx = NULL); + void DrawText(int x, int y, const char *text, byte charset, Font font = StdFont(), + Color ink = DefaultInk, int n = -1, const int *dx = NULL); + + void DrawText(int x, int y, int angle, const char *text, + Font font = StdFont(), Color ink = DefaultInk, int n = -1, const int *dx = NULL); + void DrawText(int x, int y, const char *text, Font font = StdFont(), + Color ink = DefaultInk, int n = -1, const int *dx = NULL); + + void DrawText(int x, int y, const String& text, Font font = StdFont(), + Color ink = DefaultInk, const int *dx = NULL); + void DrawText(int x, int y, int angle, const String& text, Font font = StdFont(), + Color ink = DefaultInk, const int *dx = NULL); + + static void SinCos(int angle, double& sina, double& cosa); + + // deprecated: + static void SetStdFont(Font font) { UPP::SetStdFont(font); } + static Font GetStdFont() { return UPP::GetStdFont(); } + static Size GetStdFontSize() { return UPP::GetStdFontSize(); } + static int GetStdFontCy() { return GetStdFontSize().cy; } + + +#ifdef PLATFORM_WIN32_ + static void Flush(); + HDC BeginGdi(); + void EndGdi(); +#endif +}; + +void DrawImageBandRLE(Draw& w, int x, int y, const Image& m, int minp); + +class DataDrawer { + typedef DataDrawer *(*Factory)(); + template static DataDrawer *FactoryFn() { return new T; } + static void AddFormat(const char *id, Factory f); + static VectorMap& Map(); + +public: + virtual void Open(const String& data, int cx, int cy) = 0; + virtual void Render(ImageBuffer& ib) = 0; + virtual ~DataDrawer(); + + static One Create(const String& id); + + template static void Register(const char *id) { AddFormat(id, &DataDrawer::FactoryFn); } +}; + +class Drawing : AssignValueTypeNo > { + Size size; + String data; + ValueArray val; + + friend class DrawingDraw; + friend class Draw; + +public: + operator bool() const { return !data.IsEmpty(); } + Size GetSize() const { return size; } + void SetSize(Size sz) { size = sz; } + void SetSize(int cx, int cy) { size = Size(cx, cy); } + + Size RatioSize(int cx, int cy) const; + Size RatioSize(Size sz) const { return RatioSize(sz.cx, sz.cy); } + + void Clear() { data.Clear(); size = Null; } + + void Append(Drawing& dw); + + void Serialize(Stream& s); + + bool IsNullInstance() const { return data.IsEmpty(); } + bool operator==(const Drawing& b) const { return val == b.val && data == b.data && size == b.size; } + String ToString() const { return "drawing " + AsString(size); } + unsigned GetHashValue() const { return CombineHash(data, val); } + + operator Value() const { return RichValue(*this); } + Drawing(const Value& src); + + Drawing() { size = Null; } + Drawing(const Nuller&) { size = Null; } +}; + +class DrawingDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + virtual void BeginOp(); + virtual void EndOp(); + virtual void OffsetOp(Point p); + virtual bool ClipOp(const Rect& r); + virtual bool ClipoffOp(const Rect& r); + virtual bool ExcludeClipOp(const Rect& r); + virtual bool IntersectClipOp(const Rect& r); + virtual bool IsPaintingOp(const Rect& r) const; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor); + 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 DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor); + virtual void DrawArcOp(const Rect& rc, Point start, Point end, int pen, Color pencolor); + virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx); + + virtual void DrawDrawingOp(const Rect& target, const Drawing& w); + virtual void DrawPaintingOp(const Rect& target, const Painting& w); + +private: + Size size; + StringStream drawing; + ValueArray val; + + Stream& DrawingOp(int code); + +public: + void Create(int cx, int cy); + void Create(Size sz); + + Size GetSize() const { return size; } + + Drawing GetResult(); + operator Drawing() { return GetResult(); } + + DrawingDraw(); + DrawingDraw(int cx, int cy); + DrawingDraw(Size sz); +}; + +class NilDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + virtual void BeginOp(); + virtual void EndOp(); + virtual void OffsetOp(Point p); + virtual bool ClipOp(const Rect& r); + virtual bool ClipoffOp(const Rect& r); + virtual bool ExcludeClipOp(const Rect& r); + virtual bool IntersectClipOp(const Rect& r); + virtual bool IsPaintingOp(const Rect& r) const; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor); + 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 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 DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx); + virtual void DrawDrawingOp(const Rect& target, const Drawing& w); + virtual void DrawPaintingOp(const Rect& target, const Painting& w); +}; + +void AddNotEmpty(Vector& result, int left, int right, int top, int bottom); +bool Subtract(const Rect& r, const Rect& sub, Vector& result); +bool Subtract(const Vector& rr, const Rect& sub, Vector& result); +Vector Subtract(const Vector& rr, const Rect& sub, bool& changed); +Vector Intersect(const Vector& b, const Rect& a, bool& changed); + +void Subtract(Vector& rr, const Rect& sub); +void Union(Vector& rr, const Rect& add); + +void DrawRect(Draw& w, const Rect& rect, const Image& img, bool ralgn = false); //??? TODO +void DrawRect(Draw& w, int x, int y, int cx, int cy, const Image& img, bool ra = false); + +void DrawTiles(Draw& w, int x, int y, int cx, int cy, const Image& img); +void DrawTiles(Draw& w, const Rect& rect, const Image& img); + +void DrawFatFrame(Draw& w, int x, int y, int cx, int cy, Color color, int n); +void DrawFatFrame(Draw& w, const Rect& r, Color color, int n); + +void DrawFrame(Draw& w, int x, int y, int cx, int cy, + Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor); +void DrawFrame(Draw& w, const Rect& r, + Color leftcolor, Color topcolor, Color rightcolor, Color bottomcolor); +void DrawFrame(Draw& w, int x, int y, int cx, int cy, + Color topleftcolor, Color bottomrightcolor); +void DrawFrame(Draw& w, const Rect& r, + Color topleftcolor, Color bottomrightcolor); +void DrawFrame(Draw& w, int x, int y, int cx, int cy, Color color); +void DrawFrame(Draw& w, const Rect& r, Color color); + +void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *colors_ltrd); //TODO +void DrawBorder(Draw& w, const Rect& r, const ColorF *colors_ltrd); + +const ColorF *BlackBorder(); +const ColorF *ButtonPushBorder(); +const ColorF *EdgeButtonBorder(); +const ColorF *DefButtonBorder(); +const ColorF *ButtonBorder(); +const ColorF *InsetBorder(); +const ColorF *OutsetBorder(); +const ColorF *ThinOutsetBorder(); +const ColorF *ThinInsetBorder(); + +void DrawBorder(Draw& w, int x, int y, int cx, int cy, const ColorF *(*colors_ltrd)()); +void DrawBorder(Draw& w, const Rect& r, const ColorF *(*colors_ltrd)()); + +void DrawRectMinusRect(Draw& w, const Rect& rect, const Rect& inner, Color color); + +void DrawHighlightImage(Draw& w, int x, int y, const Image& img, bool highlight = true, + bool enabled = true, Color maskcolor = SColorPaper); + +Color GradientColor(Color fc, Color tc, int i, int n); + +void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, uint64 pattern); + +enum { + BUTTON_NORMAL, BUTTON_OK, BUTTON_HIGHLIGHT, BUTTON_PUSH, BUTTON_DISABLED, BUTTON_CHECKED, + BUTTON_VERTICAL = 0x100, + BUTTON_EDGE = 0x200, + BUTTON_TOOL = 0x400, + BUTTON_SCROLL = 0x800, +}; + +void DrawXPButton(Draw& w, Rect r, int type); + +void DrawTextEllipsis(Draw& w, int x, int y, int cx, const char *text, const char *ellipsis, + Font font = StdFont(), Color ink = SColorText(), int n = -1); +void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const char *ellipsis, + Font font = StdFont(), Color ink = SColorText(), int n = -1); +Size GetTLTextSize(const wchar *text, Font font = StdFont()); +int GetTLTextHeight(const wchar *s, Font font = StdFont()); +void DrawTLText(Draw& draw, int x, int y, int cx, const wchar *text, Font font = StdFont(), + Color ink = SColorText(), int accesskey = 0); + + +typedef String (*DrawingToPdfFnType)(const Array& report, Size pagesize, int margin); + +void SetDrawingToPdfFn(DrawingToPdfFnType Pdf); +DrawingToPdfFnType GetDrawingToPdfFn(); + +#ifdef PLATFORM_WIN32 +#include "DrawWin32.h" +#endif + +#ifdef PLATFORM_X11 +#include "DrawX11.h" +#endif + +#include "SystemDraw.h" + +#include "Display.h" +#include "Debug.h" +#include "Cham.h" + +typedef ImageDraw SystemImageDraw; + +END_UPP_NAMESPACE + +#endif diff --git a/newdraw/Draw/Draw.upp b/newdraw/Draw/Draw.upp index 5d1e2d567..22fce80fa 100644 --- a/newdraw/Draw/Draw.upp +++ b/newdraw/Draw/Draw.upp @@ -33,7 +33,7 @@ file Font.cpp, FontCR.cpp, FontWin32.cpp, - FontX11.cpp, + FontFc.cpp, Draw.cpp, DrawText.cpp, DrawData.cpp, diff --git a/newdraw/Draw/DrawText.cpp b/newdraw/Draw/DrawText.cpp index 8894cee93..66aba72f3 100644 --- a/newdraw/Draw/DrawText.cpp +++ b/newdraw/Draw/DrawText.cpp @@ -1,194 +1,195 @@ -#include "Draw.h" - -NAMESPACE_UPP - - -#define LLOG(x) // LOG(x) -#define LTIMING(x) // TIMING(x) - -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); -} - -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); - Std(font); - double sina; - double cosa; - int d = 0; - if(angle) - Draw::SinCos(angle, sina, cosa); //TODO global sin tables! - for(int i = 0; i < n; i++) { - wchar chr = text[i]; - GlyphInfo gi = GetGlyphInfo(font, chr); - if(gi.IsNormal()) - if(angle) - DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &chr, font, ink, 1, NULL); - else { - int c = 1; - int dd = 0; - if(!dx) - while(c < n) { - GlyphInfo gi2 = GetGlyphInfo(font, text[i + c]); - if(!gi2.IsNormal()) - break; - c++; - dd += gi.width; - gi = gi2; - } - DrawTextOp(x + d, y, 0, text + i, font, ink, c, NULL); - i += c - 1; - d += dd; - } - else - if(gi.IsReplaced()) { - Font fnt = font; - fnt.Face(gi.lspc); - fnt.Height(gi.rspc); - if(angle) - DrawTextOp(int(x + cosa * d), int(y - sina * (font.GetAscent() - fnt.GetAscent() + d)), - angle, &chr, fnt, ink, 1, NULL); - else - DrawTextOp(x + d, y + font.GetAscent() - fnt.GetAscent(), 0, &chr, fnt, ink, 1, NULL); - GlyphMetrics(gi, font, chr); - } - else - if(gi.IsComposed()) { - ComposedGlyph cg; - Compose(font, chr, cg); - if(angle) { - DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &cg.basic_char, font, ink, 1, NULL); - DrawTextOp(int(x + cosa * (d + cg.mark_pos.x)), int(y - sina * (cg.mark_pos.y + d)), angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); - } - else { - DrawTextOp(x + d, y, angle, &cg.basic_char, font, ink, 1, NULL); - DrawTextOp(x + cg.mark_pos.x + d, y + cg.mark_pos.y, angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); - } - GlyphMetrics(gi, font, chr); - } - if(dx) - d += *dx++; - else - d += gi.width; - } -} - -// ---------------------------- - -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()); -} - -END_UPP_NAMESPACE +#include "Draw.h" + +NAMESPACE_UPP + + +#define LLOG(x) // LOG(x) +#define LTIMING(x) // TIMING(x) + +WString TextUnicode(const char *s, int n, byte cs, Font font) +{ + if(n < 0) + n = (int)strlen(s); +#ifdef PLATFORM_WIN32 + if(font.GetFace() == Font::SYMBOL) { + WStringBuffer b(n); + wchar *t = b; + while(n > 0) { + *t++ = *s++; + n--; + } + return b; + } +#endif + return ToUnicode(s, n, cs); +} + +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); + Std(font); + double sina; + double cosa; + int d = 0; + if(angle) + Draw::SinCos(angle, sina, cosa); //TODO global sin tables! + for(int i = 0; i < n; i++) { + wchar chr = text[i]; + GlyphInfo gi = GetGlyphInfo(font, chr); + if(gi.IsNormal()) + if(angle) + DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &chr, font, ink, 1, NULL); + else { + int c = 1; + int dd = 0; + if(!dx) + while(c < n) { + GlyphInfo gi2 = GetGlyphInfo(font, text[i + c]); + if(!gi2.IsNormal()) + break; + c++; + dd += gi.width; + gi = gi2; + } + DrawTextOp(x + d, y, 0, text + i, font, ink, c, NULL); + i += c - 1; + d += dd; + } + else + if(gi.IsReplaced()) { + Font fnt = font; + fnt.Face(gi.lspc); + fnt.Height(gi.rspc); + if(angle) + DrawTextOp(int(x + cosa * d), int(y - sina * (font.GetAscent() - fnt.GetAscent() + d)), + angle, &chr, fnt, ink, 1, NULL); + else + DrawTextOp(x + d, y + font.GetAscent() - fnt.GetAscent(), 0, &chr, fnt, ink, 1, NULL); + GlyphMetrics(gi, font, chr); + } + else + if(gi.IsComposed()) { + ComposedGlyph cg; + Compose(font, chr, cg); + if(angle) { + DrawTextOp(int(x + cosa * d), int(y - sina * d), angle, &cg.basic_char, font, ink, 1, NULL); + DrawTextOp(int(x + cosa * (d + cg.mark_pos.x)), int(y - sina * (cg.mark_pos.y + d)), angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); + } + else { + DrawTextOp(x + d, y, angle, &cg.basic_char, font, ink, 1, NULL); + DrawTextOp(x + cg.mark_pos.x + d, y + cg.mark_pos.y, angle, &cg.mark_char, cg.mark_font, ink, 1, NULL); + } + GlyphMetrics(gi, font, chr); + } + if(dx) + d += *dx++; + else + d += gi.width; + } +} + +// ---------------------------- + +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()); +} + +END_UPP_NAMESPACE diff --git a/newdraw/Draw/DrawTextX11.cpp b/newdraw/Draw/DrawTextX11.cpp index 92740f832..f483cdbb4 100644 --- a/newdraw/Draw/DrawTextX11.cpp +++ b/newdraw/Draw/DrawTextX11.cpp @@ -7,20 +7,10 @@ NAMESPACE_UPP #define LTIMING(x) #define LLOG(x) -extern int gtk_antialias; -extern int gtk_hinting; -extern String gtk_hintstyle; -extern String gtk_rgba; - -void Std(Font& font) -{ - if(IsNull(font)) - font = StdFont(); - if(font.GetFace() == 0) - font.Face(GetStdFont().GetFace()); - if(font.GetHeight() == 0) - font.Height(GetStdFont().GetHeight()); -} +int gtk_antialias = -1; +int gtk_hinting = -1; +String gtk_hintstyle; +String gtk_rgba; XftFont *CreateXftFont(Font font, int angle) { @@ -124,8 +114,6 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon 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; @@ -207,11 +195,9 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon 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); + DrawRect(x, y + ascent + underline_position, cx, underline_thickness, ink); if(font.IsStrikeout()) - DrawRect(x, y + 2 * lastFont.GetAscent() / 3, - cx, lastFont.ptr->underline_thickness, ink); + DrawRect(x, y + 2 * ascent / 3, cx, underline_thickness, ink); } } } diff --git a/newdraw/Draw/DrawX11.cpp b/newdraw/Draw/DrawX11.cpp index 1c6f9a3a8..046745bbe 100644 --- a/newdraw/Draw/DrawX11.cpp +++ b/newdraw/Draw/DrawX11.cpp @@ -43,15 +43,9 @@ bool Xpalette; dword (*Xgetpixel)(int r, int g, int b); -void StaticExitDraw_() -{ - FontInfo::FreeFonts(); -} - EXITBLOCK { if(Xdisplay) { - StaticExitDraw_(); // No CloseDisplay for now... XCloseDisplay(Xdisplay); LLOG("Xdisplay closed"); @@ -223,7 +217,7 @@ void InitX11Draw(XDisplay *display) } // XFree(v); - FontInfo::SetStdFont(ScreenSans(12)); + Font::SetStdFont(ScreenSans(12)); } void InitX11Draw(const char *dispname) @@ -299,14 +293,6 @@ void SystemDraw::SetClip() { UPP::SetClip(gc, xftdraw, clip.Top()); } -void SystemDraw::SetFont(Font font, int angle) { - DrawLock __; - LLOG("Set font: " << font << " face: " << font.GetFaceName()); - if(lastFont && lastFont.IsEqual(CHARSET_UNICODE, font, angle)) - return; - lastFont = FontInfo::AcquireFontInfo(font, angle); -} - void SystemDraw::SetLineStyle(int width) { DrawLock __; @@ -340,7 +326,6 @@ void SystemDraw::Init() { DrawLock __; pageSize = Size(Xwidth, Xheight); - FontInfo::InitFonts(); cloff.Clear(); clip.Clear(); foreground = linewidth = Null; diff --git a/newdraw/Draw/DrawX11.h b/newdraw/Draw/DrawX11.h index 17e0a557b..047108272 100644 --- a/newdraw/Draw/DrawX11.h +++ b/newdraw/Draw/DrawX11.h @@ -1,5 +1,7 @@ #ifdef PLATFORM_X11 +void SetClip(GC gc, XftDraw *xftdraw, const Vector& cl); + class SystemDraw : public Draw { public: virtual dword GetInfo() const; @@ -93,7 +95,6 @@ public: void SetForeground(Color color); void SetLineStyle(int width); - void SetFont(Font font, int angle); void SetClip(); Drawable GetDrawable() const { return dw; } diff --git a/newdraw/Draw/Font.cpp b/newdraw/Draw/Font.cpp index f8da55569..bcd73c76a 100644 --- a/newdraw/Draw/Font.cpp +++ b/newdraw/Draw/Font.cpp @@ -1,326 +1,341 @@ -#include "Draw.h" - -#define LLOG(x) - -NAMESPACE_UPP - -CommonFontInfo GetFontInfoSys(Font font); -GlyphInfo GetGlyphInfoSys(Font font, int chr); -void GetStdFontSys(String& name, int& height); -Vector GetAllFacesSys(); - -bool Replace(Font fnt, int chr, Font& rfnt); - -void Std(Font& font) -{ - if(IsNull(font)) - font = StdFont(); - if(font.GetFace() == 0) - font.Face(GetStdFont().GetFace()); - if(font.GetHeight() == 0) - font.Height(GetStdFont().GetHeight()); -} - -Size Font::StdFontSize; -Font Font::AStdFont; - -INITBLOCK { - RichValue::Register(); -} - -const Vector& Font::List() -{ - static Vector *q; - ONCELOCK { - static Vector x; - x = GetAllFacesSys(); - q = &x; - } - return *q; -} - -void sInitFonts() -{ - Font::List(); -} - -INITBLOCK { - sInitFonts(); -} - -int Font::GetFaceCount() -{ - return List().GetCount(); -} - -String Font::GetFaceName(int index) -{ - const Vector& l = List(); - if(index >= 0 && index < l.GetCount()) - return l[index].name; - return Null; -} - -dword Font::GetFaceInfo(int index) -{ - const Vector& l = List(); - if(index >= 0 && index < l.GetCount()) - return l[index].info; - return 0; -} - -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 String& name) { - if(name == "STDFONT") - return 0; - 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; -} - -void Font::SyncStdFont() -{ - DrawLock __; - StdFontSize = Size(AStdFont.GetAveWidth(), AStdFont().Bold().GetCy()); -} - -void Font::SetStdFont(Font font) -{ - DrawLock __; - AStdFont = font; - SyncStdFont(); -} - -void Font::InitStdFont() -{ - ONCELOCK { - DrawLock __; - List(); - AStdFont = Arial(12); - String name; - int height = 0; - GetStdFontSys(name, height); - int q = FindFaceNameIndex(name); - if(q > 0) - SetStdFont(Font(q, max(height, 1))); - } -} - -Font Font::GetStdFont() -{ - InitStdFont(); - return AStdFont; -} - -Size Font::GetStdFontSize() -{ - InitStdFont(); - return StdFontSize; -} - -Font StdFont() -{ - return Font(0, Font::GetStdFont().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 % v.flags % v.height % v.width; -} - -template<> -String AsString(const Font& f) { - if(IsNull(f)) return ""; - 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 + '>'; -} - -struct CharEntry { - int64 font; - GlyphInfo info; - word chr; -}; - -CharEntry fc_cache_global[4093]; - -bool IsNormal(Font font, int chr) -{ - DrawLock __; - CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093]; - if(e.font == font.AsInt64() || e.chr == chr) - return e.info.IsNormal(); - return GetGlyphInfoSys(font, chr).IsNormal(); -} - -CharEntry GetGlyphEntry(Font font, int chr, unsigned hash) -{ - DrawLock __; - CharEntry& e = fc_cache_global[hash % 4093]; - if(e.font != font.AsInt64() || e.chr != chr) { - e.font = font.AsInt64(); - e.chr = chr; - e.info = GetGlyphInfoSys(font, chr); - if(!e.info.IsNormal()) { - ComposedGlyph cg; - Font rfnt; - if(Compose(font, chr, cg)) { - e.info.lspc = -1; - e.info.rspc = cg.basic_char; - } - else - if(Replace(font, chr, rfnt)) { - e.info.lspc = rfnt.GetFace(); - e.info.rspc = rfnt.GetHeight(); - } - else - e.info.lspc = -2; - } - } - return e; -} - -thread__ CharEntry fc_cache[512]; - -GlyphInfo GetGlyphInfo(Font font, int chr) -{ - Std(font); - unsigned hash = CombineHash(font.GetHashValue(), chr); - CharEntry& e = fc_cache[hash & 511]; - if(e.font != font.AsInt64() || e.chr != chr) - e = GetGlyphEntry(font, chr, hash); - return e.info; -} - -void GlyphMetrics(GlyphInfo& f, Font font, int chr) -{ - if(f.IsReplaced()) - f = GetGlyphInfo(font().Face(f.lspc).Height(f.rspc), chr); - if(f.IsComposed()) { - f = GetGlyphInfo(font, f.rspc); - if(f.IsComposedLM()) - f.rspc += f.width / 2; - } -} - -GlyphInfo GetGlyphMetrics(Font font, int chr) -{ - GlyphInfo f = GetGlyphInfo(font, chr); - if(f.IsMissing()) - f = GetGlyphInfo(font, '?'); - GlyphMetrics(f, font, chr); - return f; -} - -struct FontEntry { - CommonFontInfo info; - int64 font; -}; - -thread__ FontEntry fi_cache[64]; - -const CommonFontInfo& GetFontInfo(Font font) -{ - Std(font); - unsigned hash = font.GetHashValue() & 63; - FontEntry& e = fi_cache[hash]; - if(e.font != font.AsInt64()) { - DrawLock __; - e.font = font.AsInt64(); - e.info = GetFontInfoSys(font); - } - return e.info; -} - -int Font::GetWidth(int c) const { - return GetGlyphMetrics(*this, c).width; -} - -int Font::GetLeftSpace(int c) const { - return GetGlyphMetrics(*this, c).lspc; -} - -int Font::GetRightSpace(int c) const { - return GetGlyphMetrics(*this, c).rspc; -} - -thread__ int64 lastFiFont = INT_MIN; -thread__ CommonFontInfo lastFontInfo; - -const CommonFontInfo& Font::Fi() const -{ - if(AsInt64() == lastFiFont) - return lastFontInfo; - lastFontInfo = GetFontInfo(*this); - lastFiFont = AsInt64(); - return lastFontInfo; -} - -FontInfo Font::Info() const -{ - FontInfo h; - h.font = *this; - return h; -} - -END_UPP_NAMESPACE +#include "Draw.h" + +#define LLOG(x) + +NAMESPACE_UPP + +CommonFontInfo GetFontInfoSys(Font font); +GlyphInfo GetGlyphInfoSys(Font font, int chr); +void GetStdFontSys(String& name, int& height); +Vector GetAllFacesSys(); + +bool Replace(Font fnt, int chr, Font& rfnt); + +void Std(Font& font) +{ + if(IsNull(font)) + font = StdFont(); + if(font.GetFace() == 0) + font.Face(GetStdFont().GetFace()); + if(font.GetHeight() == 0) + font.Height(GetStdFont().GetHeight()); +} + +Size Font::StdFontSize; +Font Font::AStdFont; + +INITBLOCK { + RichValue::Register(); +} + +const Vector& Font::List() +{ + static Vector *q; + ONCELOCK { + static Vector x; + x = GetAllFacesSys(); + q = &x; + } + return *q; +} + +void sInitFonts() +{ + Font::List(); + GetStdFont(); +} + +INITBLOCK { + sInitFonts(); +} + +int Font::GetFaceCount() +{ + return List().GetCount(); +} + +String Font::GetFaceName(int index) +{ + if(index == 0) + return "STDFONT"; + const Vector& l = List(); + if(index >= 0 && index < l.GetCount()) + return l[index].name; + return Null; +} + +dword Font::GetFaceInfo(int index) +{ + const Vector& l = List(); + if(index >= 0 && index < l.GetCount()) + return l[index].info; + return 0; +} + +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 String& name) { + if(name == "STDFONT") + return 0; + 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; +} + +void Font::SyncStdFont() +{ + DrawLock __; + StdFontSize = Size(AStdFont.GetAveWidth(), AStdFont().Bold().GetCy()); +} + +void Font::SetStdFont(Font font) +{ + DrawLock __; + InitStdFont(); + AStdFont = font; + SyncStdFont(); + DLOG("SetStdFont " << font); +} + +void Font::InitStdFont() +{ + ONCELOCK { + DrawLock __; + List(); + AStdFont = Arial(12); + String name; + int height = 0; + GetStdFontSys(name, height); + int q = FindFaceNameIndex(name); + if(q > 0) + SetStdFont(Font(q, max(height, 1))); + } +} + +Font Font::GetStdFont() +{ + InitStdFont(); + return AStdFont; +} + +Size Font::GetStdFontSize() +{ + InitStdFont(); + return StdFontSize; +} + +Font StdFont() +{ + return Font(0, 0); +} + +int Font::GetHeight() const +{ + return v.height ? v.height : GetStdFont().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 % v.flags % v.height % v.width; +} + +template<> +String AsString(const Font& f) { + if(IsNull(f)) return ""; + 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 + '>'; +} + +struct CharEntry { + int64 font; + GlyphInfo info; + word chr; +}; + +CharEntry fc_cache_global[4093]; + +bool IsNormal(Font font, int chr) +{ + DrawLock __; + CharEntry& e = fc_cache_global[CombineHash(font.GetHashValue(), chr) % 4093]; + if(e.font == font.AsInt64() || e.chr == chr) + return e.info.IsNormal(); + return GetGlyphInfoSys(font, chr).IsNormal(); +} + +CharEntry GetGlyphEntry(Font font, int chr, unsigned hash) +{ + DrawLock __; + CharEntry& e = fc_cache_global[hash % 4093]; + if(e.font != font.AsInt64() || e.chr != chr) { + e.font = font.AsInt64(); + e.chr = chr; + e.info = GetGlyphInfoSys(font, chr); + if(!e.info.IsNormal()) { + ComposedGlyph cg; + Font rfnt; + if(Compose(font, chr, cg)) { + e.info.lspc = -1; + e.info.rspc = cg.basic_char; + } + else + if(Replace(font, chr, rfnt)) { + e.info.lspc = rfnt.GetFace(); + e.info.rspc = rfnt.GetHeight(); + } + else + e.info.lspc = -2; + } + } + return e; +} + +thread__ CharEntry fc_cache[512]; + +GlyphInfo GetGlyphInfo(Font font, int chr) +{ + Std(font); + unsigned hash = CombineHash(font.GetHashValue(), chr); + CharEntry& e = fc_cache[hash & 511]; + if(e.font != font.AsInt64() || e.chr != chr) + e = GetGlyphEntry(font, chr, hash); + return e.info; +} + +void GlyphMetrics(GlyphInfo& f, Font font, int chr) +{ + if(f.IsReplaced()) + f = GetGlyphInfo(font().Face(f.lspc).Height(f.rspc), chr); + if(f.IsComposed()) { + f = GetGlyphInfo(font, f.rspc); + if(f.IsComposedLM()) + f.rspc += f.width / 2; + } +} + +GlyphInfo GetGlyphMetrics(Font font, int chr) +{ + GlyphInfo f = GetGlyphInfo(font, chr); + if(f.IsMissing()) + f = GetGlyphInfo(font, '?'); + GlyphMetrics(f, font, chr); + return f; +} + +struct FontEntry { + CommonFontInfo info; + int64 font; +}; + +thread__ FontEntry fi_cache[64]; + +const CommonFontInfo& GetFontInfo(Font font) +{ + Std(font); + unsigned hash = font.GetHashValue() & 63; + FontEntry& e = fi_cache[hash]; + if(e.font != font.AsInt64()) { + DrawLock __; + e.font = font.AsInt64(); + e.info = GetFontInfoSys(font); + } + return e.info; +} + +int Font::GetWidth(int c) const { + return GetGlyphMetrics(*this, c).width; +} + +int Font::GetLeftSpace(int c) const { + return GetGlyphMetrics(*this, c).lspc; +} + +int Font::GetRightSpace(int c) const { + return GetGlyphMetrics(*this, c).rspc; +} + +thread__ int64 lastFiFont = INT_MIN; +thread__ CommonFontInfo lastFontInfo; +thread__ int64 lastStdFont = INT_MIN; + +const CommonFontInfo& Font::Fi() const +{ + if(lastStdFont != AStdFont.AsInt64()) { + lastFiFont = INT_MIN; + lastStdFont = AStdFont.AsInt64(); + } + if(AsInt64() == lastFiFont) + return lastFontInfo; + lastFontInfo = GetFontInfo(*this); + lastFiFont = AsInt64(); + return lastFontInfo; +} + +FontInfo Font::Info() const +{ + FontInfo h; + h.font = *this; + return h; +} + +END_UPP_NAMESPACE diff --git a/newdraw/Draw/FontFc.cpp b/newdraw/Draw/FontFc.cpp new file mode 100644 index 000000000..06b38b6f7 --- /dev/null +++ b/newdraw/Draw/FontFc.cpp @@ -0,0 +1,225 @@ +#include "Draw.h" + +NAMESPACE_UPP + +#ifdef PLATFORM_POSIX + +#define LLOG(x) // LOG(x) +#define LTIMING(x) // TIMING(x) + +void GetStdFontSys(String& name, int& height) +{ + name = "xxxx"; +} + +static FT_Library sFTlib; + +bool sInitFt(void) +{ + if(sFTlib) + return true; + return FT_Init_FreeType(&sFTlib) == 0; +} + +FcPattern *CreateFcPattern(Font font, int angle) +{ + LTIMING("CreateXftFont"); + double sina, cosa; + int hg = abs(font.GetHeight()); + if(hg == 0) hg = 10; + String n = font.GetFaceName(); + const char *face = n; + 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; + Draw::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); + FcPatternDestroy(p); + return m; +} + +FT_Face CreateFTFace(const FcPattern *pattern, String *rpath) { + FT_Face face = NULL; + + int id; + double dsize; + double aspect; + FcChar8 *filename; + + if(!sInitFt()) + return NULL; + + if(FcPatternGetString(pattern, FC_FILE, 0, &filename) != FcResultMatch) + return NULL; + + if(rpath) + *rpath = (const char *)filename; + + if(FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &dsize) != FcResultMatch) + dsize = 16; + + if (FcPatternGetDouble(pattern, FC_ASPECT, 0, &aspect) != FcResultMatch) + aspect = 1.0; + + FT_F26Dot6 ysize = (FT_F26Dot6) (dsize * 64.0); + FT_F26Dot6 xsize = (FT_F26Dot6) (dsize * aspect * 64.0); + + if(FT_New_Face (sFTlib, (const char *)filename, 0, &face)) + return NULL; + + FT_Set_Char_Size(face, xsize, ysize, 0, 0); + return face; +} + +#define FONTCACHE 37 + +struct FtFaceEntry { + Font font; + FT_Face face; + String path; +}; + +FT_Face FTFace(Font fnt, String *rpath = NULL) +{ + RTIMING("FTFace"); + static FtFaceEntry cache[FONTCACHE]; + ONCELOCK { + for(int i = 0; i < FONTCACHE; i++) + cache[i].font.Height(-30000); + } + FtFaceEntry be; + be = cache[0]; + for(int i = 0; i < FONTCACHE; i++) { + FtFaceEntry e = cache[i]; + if(i) + cache[i] = be; + if(e.font == fnt) { + if(rpath) + *rpath = e.path; + if(i) + cache[0] = e; + return e.face; + } + be = e; + } + RTIMING("FTFace2"); + if(be.face) { + LOG("Removing " << be.font << " - " << (void *)be.face); + FT_Done_Face(be.face); + } + be.font = fnt; + FcPattern *p = CreateFcPattern(fnt, 0); + be.face = CreateFTFace(p, &be.path); + FcPatternDestroy(p); + cache[0] = be; + if(rpath) + *rpath = be.path; + return be.face; +} + +CommonFontInfo GetFontInfoSys(Font font) +{ + CommonFontInfo fi; + + FT_Face face = FTFace(font, &fi.path); + if(face) { + fi.ascent = face->size->metrics.ascender >> 6; + fi.descent = -(face->size->metrics.descender >> 6); + fi.height = fi.ascent + fi.descent; + fi.lineheight = face->size->metrics.height >> 6; + fi.external = 0; + fi.internal = 0; + fi.overhang = 0; + fi.maxwidth = face->size->metrics.max_advance >> 6; + fi.avewidth = fi.maxwidth; + fi.default_char = '?'; + fi.fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH; + } + return fi; +} + +#define FLOOR(x) ((x) & -64) +#define CEIL(x) (((x)+63) & -64) +#define TRUNC(x) ((x) >> 6) +#define ROUND(x) (((x)+32) & -64) + +GlyphInfo GetGlyphInfoSys(Font font, int chr) +{ + RTIMING("GetGlyphInfoSys"); + GlyphInfo gi; + FT_Face face = FTFace(font, NULL); + gi.lspc = gi.rspc = 0; + gi.width = 0x8000; + if(face) { + RTIMING("GetGlyphInfoSys 2"); + int glyph_index = FT_Get_Char_Index(face, chr); + if(glyph_index && + (FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP) == 0 || + FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT) == 0)) { + FT_Glyph_Metrics& m = face->glyph->metrics; + int left = FLOOR(m.horiBearingX); + int width = TRUNC(CEIL(m.horiBearingX + m.width) - left); + gi.width = TRUNC(ROUND(face->glyph->advance.x)); + gi.lspc = TRUNC(left); + gi.rspc = gi.width - width - gi.lspc; + } + } + return gi; +} + +Vector GetAllFacesSys() +{ + static const char *basic_fonts[] = { + "sans-serif", + "serif", + "sans-serif", + "monospace", + "serif", + "sans-serif", + "monospace", + }; + + Vector list; + for(int i = 0; i < __countof(basic_fonts); i++) { + FaceInfo& fi = list.Add(); + fi.name = basic_fonts[i]; + fi.info = (i == 3 || i == 6) ? Font::SCALEABLE|Font::FIXEDPITCH : Font::SCALEABLE; + } + FcPattern *p = FcPatternCreate(); + FcObjectSet *os = FcObjectSetBuild(XFT_FAMILY, XFT_SPACING, XFT_SCALABLE, (void *)0); + FcFontSet *fs = FcFontList(NULL, p, os); + FcPatternDestroy(p); + FcObjectSetDestroy(os); + for(int i = 0; i < fs->nfont; i++) { + FcChar8 *family = NULL; + if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == 0 && family) { + FaceInfo& fi = list.Add(); + fi.name = (const char *)family; + fi.info = 0; + int iv; + if(FcPatternGetInteger(fs->fonts[i], FC_SPACING, 0, &iv) == 0 && iv == FC_MONO) + fi.info |= Font::FIXEDPITCH; + FcBool bv; + if(FcPatternGetBool(fs->fonts[i], FC_SCALABLE, 0, &bv) == 0 && bv) + fi.info |= Font::SCALEABLE; + } + } + FcFontSetDestroy(fs); + return list; +} + +#endif + +END_UPP_NAMESPACE diff --git a/newdraw/Draw/FontX11.cpp b/newdraw/Draw/FontX11.cpp deleted file mode 100644 index 6680de535..000000000 --- a/newdraw/Draw/FontX11.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include "Draw.h" - -NAMESPACE_UPP - -#ifdef PLATFORM_X11 - -#define LLOG(x) // LOG(x) -#define LTIMING(x) // TIMING(x) - -struct XFTFontFaceInfo { - String name; - bool fixed:1; - bool scaleable:1; - bool compose:1; - - XFTFontFaceInfo() - { - fixed = scaleable = false; - } -}; - -ArrayMap& XFTFontFace() -{ - static ArrayMap 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 FontInfo::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() -{ - ONCELOCK { - FontInfo::InitFonts(); - } - return XFTFontFace().GetCount(); -} - -String Font::GetFaceName(int index) -{ - ONCELOCK { - FontInfo::InitFonts(); - } - return index >= 0 && index < XFTFontFace().GetCount() ? XFTFontFace().GetKey(index) - : Null; -} - -dword Font::GetFaceInfo(int index) { - ONCELOCK { - FontInfo::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 *FontInfo::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; - Draw::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 FontInfo::AcquireFontInfo(Font font, int angle) -{ - 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) % (int)FONTHASH); - LLOG("Acquire " << font << " device: " << device); - for(;;) { - f = f->GetNext(HASH); - if(f == fh) break; - if(f->font == font && f->angle == angle) - { - 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; - 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) { - Draw::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; -} - -#endif - -END_UPP_NAMESPACE diff --git a/newdraw/Draw/Image.h b/newdraw/Draw/Image.h index 68e15b8db..304f7976f 100644 --- a/newdraw/Draw/Image.h +++ b/newdraw/Draw/Image.h @@ -1,342 +1,334 @@ -#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 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 > { -private: - struct Data : Link { - Atomic refcount; - int64 serial; - int paintcount; - - static Link ResData[1]; - static int ResCount; - - void Retain() { AtomicInc(refcount); } - void Release() { if(AtomicDec(refcount) == 0) delete this; } - - struct SystemData; - - void *system_buffer[6]; - SystemData& Sys() const; - -#ifdef PLATFORM_WIN32 - void CreateHBMP(HDC dc, const RGBA *data); - int GetResCount() const; -#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(SystemDraw& w, int x, int y, const Rect& src, Color c); - void PaintOnlyShrink(); - - Data(ImageBuffer& b); - ~Data(); - }; - - Data *data; - - static Link ResData[1]; - static int ResCount; - - void Set(ImageBuffer& b); - - friend class ImageBuffer; - friend struct Data; - - friend class SystemDraw; - - void PaintImage(SystemDraw& 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); - LPCSTR GetCursorCheat() const; - 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(*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 UnpackImlData(const void *ptr, int len); -Vector UnpackImlData(const String& d); - -class Iml { - struct IImage : Moveable { - bool loaded; - Image image; - - IImage() { loaded = false; } - }; - struct Data : Moveable { - const char *data; - int len, count; - }; - Vector data; - VectorMap 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 +#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 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 > { +private: + struct Data : Link { + Atomic refcount; + int64 serial; + int paintcount; + + static Link ResData[1]; + static int ResCount; + + void Retain() { AtomicInc(refcount); } + void Release() { if(AtomicDec(refcount) == 0) delete this; } + + struct SystemData; + + void *system_buffer[6]; + SystemData& Sys() const; + int GetResCount() const; + +#ifdef PLATFORM_WIN32 + void CreateHBMP(HDC dc, const RGBA *data); +#endif + + ImageBuffer buffer; + bool paintonly; + + void SysInit(); + void SysRelease(); + int GetKind(); + void Paint(SystemDraw& w, int x, int y, const Rect& src, Color c); + void PaintOnlyShrink(); + + Data(ImageBuffer& b); + ~Data(); + }; + + Data *data; + + static Link ResData[1]; + static int ResCount; + + void Set(ImageBuffer& b); + + friend class ImageBuffer; + friend struct Data; + + friend class SystemDraw; + + void PaintImage(SystemDraw& 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); + LPCSTR GetCursorCheat() const; + 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); + int GetCursorCheat() const; + 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(*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 UnpackImlData(const void *ptr, int len); +Vector UnpackImlData(const String& d); + +class Iml { + struct IImage : Moveable { + bool loaded; + Image image; + + IImage() { loaded = false; } + }; + struct Data : Moveable { + const char *data; + int len, count; + }; + Vector data; + VectorMap 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 diff --git a/newdraw/Draw/ImageX11.cpp b/newdraw/Draw/ImageX11.cpp index 427cdceb9..036f8c8e2 100644 --- a/newdraw/Draw/ImageX11.cpp +++ b/newdraw/Draw/ImageX11.cpp @@ -4,6 +4,28 @@ NAMESPACE_UPP #ifdef PLATFORM_X11 +struct Image::Data::SystemData { + int cursor_cheat; + XPicture picture; + XPicture picture8; +}; + +Image::Data::SystemData& Image::Data::Sys() const +{ + ASSERT(sizeof(system_buffer) >= sizeof(SystemData)); + return *(SystemData *)system_buffer; +} + +void Image::SetCursorCheat(int id) +{ + data->Sys().cursor_cheat = id; +} + +int Image::GetCursorCheat() const +{ + return data ? data->Sys().cursor_cheat : -1; +} + static void sInitXImage(XImage& ximg, Size sz) { Zero(ximg); @@ -51,26 +73,33 @@ void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) XRenderFreePicture(Xdisplay, picture); } +int Image::Data::GetResCount() const +{ + return !!Sys().picture + !!Sys().picture8; +} + void Image::Data::SysInit() { - picture = 0; - picture8 = 0; - cursor_cheat = -1; + SystemData& sd = Sys(); + sd.picture = 0; + sd.picture8 = 0; + sd.cursor_cheat = -1; } void Image::Data::SysRelease() { - if(picture) { + SystemData& sd = Sys(); + if(sd.picture) { DrawLock __; - if(Xdisplay) XRenderFreePicture(Xdisplay, picture); + if(Xdisplay) XRenderFreePicture(Xdisplay, sd.picture); ResCount -= !paintonly; - picture = 0; + sd.picture = 0; } - if(picture8) { + if(sd.picture8) { DrawLock __; - if(Xdisplay) XRenderFreePicture(Xdisplay, picture8); + if(Xdisplay) XRenderFreePicture(Xdisplay, sd.picture8); ResCount -= !paintonly; - picture8 = 0; + sd.picture8 = 0; } } @@ -119,6 +148,7 @@ static XPicture sGetSolidFill(Color c) void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) { DrawLock __; + SystemData& sd = Sys(); while(ResCount > 512) { Image::Data *l = ResData->GetPrev(); l->SysRelease(); @@ -146,10 +176,10 @@ void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) Unlink(); LinkAfter(ResData); if(IsNull(c)) { - if(!picture) { + if(!sd.picture) { bool opaque = GetKind() == IMAGE_OPAQUE; Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, opaque ? 24 : 32); - picture = XRenderCreatePicture( + sd.picture = XRenderCreatePicture( Xdisplay, pixmap, XRenderFindStandardFormat(Xdisplay, opaque ? PictStandardRGB24 : PictStandardARGB32), @@ -175,16 +205,16 @@ void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) PaintOnlyShrink(); } XRenderComposite(Xdisplay, PictOpOver, - picture, 0, XftDrawPicture(w.GetXftDraw()), + sd.picture, 0, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } else { ASSERT(!paintonly); - if(!picture8) { + if(!sd.picture8) { Pixmap pixmap = XCreatePixmap(Xdisplay, Xroot, sz.cx, sz.cy, 8); - picture8 = XRenderCreatePicture(Xdisplay, pixmap, - XRenderFindStandardFormat(Xdisplay, PictStandardA8), - 0, 0); + sd.picture8 = XRenderCreatePicture(Xdisplay, pixmap, + XRenderFindStandardFormat(Xdisplay, PictStandardA8), + 0, 0); ResCount++; Buffer ab(len); byte *t = ab; @@ -207,7 +237,7 @@ void Image::Data::Paint(SystemDraw& w, int x, int y, const Rect& src, Color c) XFreePixmap(Xdisplay, pixmap); } XRenderComposite(Xdisplay, PictOpOver, - sGetSolidFill(c), picture8, XftDrawPicture(w.GetXftDraw()), + sGetSolidFill(c), sd.picture8, XftDrawPicture(w.GetXftDraw()), sr.left, sr.top, 0, 0, x, y, ssz.cx, ssz.cy); } }