diff --git a/include/ege.h b/include/ege.h index 7361c42..e72eb07 100644 --- a/include/ege.h +++ b/include/ege.h @@ -434,6 +434,14 @@ enum text_just BOTTOM_TEXT = 2 }; +enum font_styles +{ + FONTSTYLE_BOLD = 1, + FONTSTYLE_ITALIC = 2, + FONTSTYLE_UNDERLINE = 4, + FONTSTYLE_STRIKEOUT = 8, +}; + /* Line styles for get/setlinestyle */ enum line_styles { @@ -731,6 +739,30 @@ typedef struct ege_colpoint color_t color; } ege_colpoint; +// matrix for transformation +typedef struct ege_transform_matrix +{ + float m11, m12; + float m21, m22; + float m31, m32; +} ege_transform_matrix; + +struct ege_path +{ +private: + void* m_data; + +public: + ege_path(); + ege_path(const ege_point* points, const unsigned char* types, int count); + ege_path(const ege_path& path); + virtual ~ege_path(); + + const void* data() const; + void* data(); + ege_path& operator=(const ege_path& path); +}; + struct MOUSEMSG { UINT uMsg; @@ -1072,13 +1104,49 @@ void EGEAPI ege_puttexture(PCIMAGE imgSrc, ege_rect dest, ege_rect src, PIMAGE p void EGEAPI ege_drawimage(PCIMAGE imgSrc,int xDest, int yDest, PIMAGE pimg = NULL); void EGEAPI ege_drawimage(PCIMAGE imgSrc,int xDest, int yDest, int widthDest, int heightDest, int xSrc, int ySrc, int widthSrc, int heightSrc,PIMAGE pimg = NULL); -// matrix for transformation -typedef struct ege_transform_matrix -{ - float m11, m12; - float m21, m22; - float m31, m32; -} ege_transform_matrix; +void ege_drawpath(const ege_path* path, PIMAGE pimg = NULL); +void ege_fillpath(const ege_path* path, PIMAGE pimg = NULL); +void ege_drawpath(const ege_path* path, float x, float y, PIMAGE pimg = NULL); +void ege_fillpath(const ege_path* path, float x, float y, PIMAGE pimg = NULL); + +ege_path* ege_path_create (); +ege_path* ege_path_clone (const ege_path* path); +void ege_path_destroy (const ege_path* path); +void ege_path_start (ege_path* path); +void ege_path_close (ege_path* path); +void ege_path_closeall (ege_path* path); +void ege_path_reset (ege_path* path); +void ege_path_reverse (ege_path* path); + +ege_point ege_path_lastpoint (ege_path* path); +int ege_path_pointcount (ege_path* path); +void ege_path_getbounds (ege_path* path, ege_point* points, const ege_transform_matrix* matrix = NULL); +ege_point* ege_path_getpathpoints(ege_path* path, ege_point* points); +unsigned char* ege_path_getpathtypes (ege_path* path, unsigned char* types); + +void ege_path_transform (ege_path* path, const ege_transform_matrix* matrix); + +// Adds a non-closed figure to path +void ege_path_addpath (ege_path* dstPath, const ege_path* srcPath, bool connect); +void ege_path_addline (ege_path* path, float x1, float y1, float x2, float y2); +void ege_path_addarc (ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle); +void ege_path_addpolyline (ege_path* path, int numOfPoints, const ege_point* points); +void ege_path_addbezier (ege_path* path, int numOfPoints, const ege_point* points); +void ege_path_addbezier (ege_path* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); +void ege_path_addcurve (ege_path* path, int numOfPoints, const ege_point* points); +void ege_path_addcurve (ege_path* path, int numOfPoints, const ege_point* points, float tension); + +// Adds a closed figure to path +void ege_path_addcircle (ege_path* path, float x, float y, float radius); +void ege_path_addrect (ege_path* path, float x, float y, float width, float height); +void ege_path_addellipse (ege_path* path, float x, float y, float width, float height); +void ege_path_addpie (ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle); +void ege_path_addstring (ege_path* path, float x, float y, const char* text, float height, int length = -1, const char* typeface = NULL, int fontStyle = 0); +void ege_path_addstring (ege_path* path, float x, float y, const wchar_t* text, float height, int length = -1, const wchar_t* typeface = NULL, int fontStyle = 0); +void ege_path_addpolygon (ege_path* path, int numOfPoints, const ege_point* points); +void ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point* points); +void ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point* points, float tension); + // transforms void EGEAPI ege_transform_rotate(float angle, PIMAGE pimg = NULL); @@ -1090,6 +1158,8 @@ void EGEAPI ege_set_transform(const ege_transform_matrix* matrix, PIMAGE pimg = ege_point EGEAPI ege_transform_calc(ege_point p, PIMAGE pimg = NULL); // Calculate transformed coordination of p; ege_point EGEAPI ege_transform_calc(float x, float y, PIMAGE pimg = NULL); // Calculate transformed coordination of point(x,y); + + // #endif diff --git a/src/egegapi.cpp b/src/egegapi.cpp index 695a778..ec9e73e 100644 --- a/src/egegapi.cpp +++ b/src/egegapi.cpp @@ -2144,6 +2144,425 @@ void EGEAPI ege_drawimage(PCIMAGE srcimg, CONVERT_IMAGE_END; } + +ege_path::ege_path() +{ + gdipluinit(); + m_data = new Gdiplus::GraphicsPath; +} + +ege_path::ege_path(const ege_point *points, const unsigned char *types, int count) +{ + gdipluinit(); + m_data = new Gdiplus::GraphicsPath((const Gdiplus::PointF*)points, (const BYTE*)types, count); +} + +ege_path::ege_path(const ege_path &path) +{ + const Gdiplus::GraphicsPath* graphicsPath = (const Gdiplus::GraphicsPath*)path.m_data; + m_data = (graphicsPath != NULL) ? graphicsPath->Clone() : NULL; +} + +ege_path::~ege_path() +{ + if (m_data != NULL) { + delete (Gdiplus::GraphicsPath*)m_data; + } +} + +const void* ege_path::data() const +{ + return m_data; +} + +void* ege_path::data() +{ + return m_data; +} + +ege_path& ege_path::operator=(const ege_path& path) +{ + if (this != &path) { + if (m_data != NULL) { + delete (Gdiplus::GraphicsPath*)m_data; + } + + const Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path.m_data; + m_data = (graphicsPath != NULL) ? graphicsPath->Clone() : NULL; + } + + return *this; +} + +void ege_drawpath(const ege_path* path, PIMAGE pimg) +{ + PIMAGE img = CONVERT_IMAGE(pimg); + if ((img != NULL) && (path != NULL)) { + Gdiplus::Graphics* graphics = img->getGraphics(); + graphics->DrawPath(img->getPen(), (Gdiplus::GraphicsPath*)path->data()); + } + CONVERT_IMAGE_END; +} + +void ege_fillpath(const ege_path* path, PIMAGE pimg) +{ + PIMAGE img = CONVERT_IMAGE(pimg); + if ((img != NULL) && (path != NULL)) { + const Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + Gdiplus::Graphics* graphics = img->getGraphics(); + graphics->FillPath(img->getBrush(), graphicsPath); + } + } + CONVERT_IMAGE_END; +} + +void ege_drawpath(const ege_path* path, float x, float y, PIMAGE pimg) +{ + PIMAGE img = CONVERT_IMAGE(pimg); + if ((img != NULL) && (path != NULL)) { + const Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + Gdiplus::Graphics* graphics = img->getGraphics(); + graphics->TranslateTransform(x, y); + graphics->DrawPath(img->getPen(), graphicsPath); + graphics->TranslateTransform(-x, -y); + } + } + CONVERT_IMAGE_END; +} + +void ege_fillpath(const ege_path* path, float x, float y, PIMAGE pimg) +{ + PIMAGE img = CONVERT_IMAGE(pimg); + if ((img != NULL) && (path != NULL)) { + const Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + Gdiplus::Graphics* graphics = img->getGraphics(); + graphics->FillPath(img->getBrush(), graphicsPath); + } + } + CONVERT_IMAGE_END; +} + +ege_path* ege_path_create() +{ + return new ege_path; +} + +ege_path* ege_path_clone(const ege_path* path) +{ + if (path == NULL) { + return NULL; + } + return new ege_path(*path); +} + +void ege_path_destroy(const ege_path* path) +{ + delete path; +} + +void ege_path_start(ege_path* path) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->StartFigure(); + } + } +} + +void ege_path_close(ege_path* path) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->CloseFigure(); + } + } +} + +void ege_path_closeall(ege_path* path) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->CloseAllFigures(); + } + } +} + +void ege_path_reset(ege_path* path) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->Reset(); + } + } +} + +void ege_path_reverse(ege_path* path) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->Reverse(); + } + } +} + +ege_point ege_path_lastpoint(ege_path* path) +{ + ege_point lastPoint = {0.0f, 0.0f}; + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->GetLastPoint((Gdiplus::PointF*)&lastPoint); + } + } + return lastPoint; +} + +int ege_path_pointcount(ege_path* path) +{ + int pointCount = 0; + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + pointCount = graphicsPath->GetPointCount(); + } + } + return pointCount; +} + +void ege_path_getbounds(ege_path* path, ege_rect* bounds, const ege_transform_matrix* matrix) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->GetBounds((Gdiplus::RectF*)bounds, (const Gdiplus::Matrix*)matrix); + } + } +} + +ege_point* ege_path_getpathpoints(ege_path* path, ege_point* points) +{ + if ((path != NULL)) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + int pointCount = graphicsPath->GetPointCount(); + + if (points == NULL) { + points = new ege_point[pointCount]; + } + + graphicsPath->GetPathPoints((Gdiplus::PointF*)points, pointCount); + return points; + } + } + + return NULL; +} + +void ege_path_transform(ege_path* path, const ege_transform_matrix *matrix) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->Transform((const Gdiplus::Matrix*)matrix); + } + } +} + +void ege_path_addpath(ege_path* dstPath, const ege_path* srcPath, bool connect) +{ + if ((dstPath != NULL) && (srcPath != NULL)) { + Gdiplus::GraphicsPath* dstGraphicsPath = (Gdiplus::GraphicsPath*)dstPath->data(); + const Gdiplus::GraphicsPath* srcGraphicsPath = (Gdiplus::GraphicsPath*)srcPath->data(); + if ((dstGraphicsPath != NULL) && (srcGraphicsPath != NULL)) { + dstGraphicsPath->AddPath(srcGraphicsPath, connect); + } + } +} + +void ege_path_addline(ege_path* path, float x1, float y1, float x2, float y2) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddLine(x1, y1, x2, y2); + } + } +} + +void ege_path_addarc(ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddArc(x, y, width, height, startAngle, sweepAngle); + } + } +} + +void ege_path_addpolyline(ege_path* path, int numOfPoints, const ege_point *points) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddLines((const Gdiplus::PointF*)points, numOfPoints); + } + } +} + +void ege_path_addbezier(ege_path* path, int numOfPoints, const ege_point *points) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddBeziers((const Gdiplus::PointF*)points, numOfPoints); + } + } +} + +void ege_path_addbezier(ege_path* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddBezier(x1, y1, x2, y2, x3, y3, x4, y4); + } + } +} + +void ege_path_addcurve(ege_path* path, int numOfPoints, const ege_point *points) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddCurve((const Gdiplus::PointF*)points, numOfPoints); + } + } +} + +void ege_path_addcurve(ege_path* path, int numOfPoints, const ege_point *points, float tension) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddCurve((const Gdiplus::PointF*)points, numOfPoints, tension); + } + } +} + +void ege_path_addcircle(ege_path* path, float x, float y, float radius) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddEllipse(x - radius, y - radius, radius * 2.0f, radius * 2.0f); + } + } +} + +void ege_path_addrect(ege_path* path, float x, float y, float width, float height) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + Gdiplus::RectF rect(x, y, width, height); + graphicsPath->AddRectangle(rect); + } + } +} + +void ege_path_addellipse(ege_path* path, float x, float y, float width, float height) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddEllipse(x, y, width, height); + } + } +} + +void ege_path_addpie(ege_path* path, float x, float y, float width, float height, float startAngle, float sweepAngle) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddPie(x, y, width, height, startAngle, sweepAngle); + } + } +} + +void ege_path_addstring(ege_path* path, float x, float y, const char* text, float height, int length, + const char* typeface, int fontStyle) +{ + ege_path_addstring(path, x, y, mb2w(text).c_str(), height, length, mb2w(typeface).c_str(), fontStyle); +} + +void ege_path_addstring(ege_path* path, float x, float y, const wchar_t* text, float height, int length, + const wchar_t* typeface, int fontStyle) +{ + if ((path != NULL) && (text != NULL) && (length != 0)) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + + Gdiplus::REAL emSize = height; + Gdiplus::PointF origin(x, y); + const Gdiplus::StringFormat* format = Gdiplus::StringFormat::GenericTypographic(); + + if ((typeface == NULL) || (typeface[0] == L'\0')) { + typeface = L"SimSun"; + } + + Gdiplus::FontFamily fontFamliy(typeface); + + INT style = 0; + if (fontStyle & FONTSTYLE_BOLD) style |= Gdiplus::FontStyleBold; + if (fontStyle & FONTSTYLE_ITALIC) style |= Gdiplus::FontStyleItalic; + if (fontStyle & FONTSTYLE_UNDERLINE) style |= Gdiplus::FontStyleUnderline; + if (fontStyle & FONTSTYLE_STRIKEOUT) style |= Gdiplus::FontStyleStrikeout; + + graphicsPath->AddString(text, length, &fontFamliy, style, emSize, origin, format); + } + } +} + +void ege_path_addpolygon(ege_path* path, int numOfPoints, const ege_point *points) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddPolygon((const Gdiplus::PointF*)points, numOfPoints); + } + } +} + +void ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point *points) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddClosedCurve((const Gdiplus::PointF*)points, numOfPoints); + } + } +} + +void ege_path_addclosedcurve(ege_path* path, int numOfPoints, const ege_point *points, float tension) +{ + if (path != NULL) { + Gdiplus::GraphicsPath* graphicsPath = (Gdiplus::GraphicsPath*)path->data(); + if (graphicsPath != NULL) { + graphicsPath->AddClosedCurve((const Gdiplus::PointF*)points, numOfPoints, tension); + } + } +} + + void EGEAPI ege_transform_rotate(float angle, PIMAGE pimg) { PIMAGE img = CONVERT_IMAGE(pimg); diff --git a/src/image.cpp b/src/image.cpp index 9936921..f0a9af4 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -239,7 +239,7 @@ Gdiplus::Graphics* IMAGE::getGraphics() { if (NULL == m_graphics) { m_graphics = new Gdiplus::Graphics(m_hDC); - m_graphics->SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); + m_graphics->SetPixelOffsetMode(Gdiplus::PixelOffsetModeNone); m_graphics->SetSmoothingMode(m_aa ? Gdiplus::SmoothingModeAntiAlias : Gdiplus::SmoothingModeNone); m_graphics->SetTextRenderingHint( m_aa ? Gdiplus::TextRenderingHintAntiAlias : Gdiplus::TextRenderingHintSystemDefault);