#include "CairoDraw.h" NAMESPACE_UPP void CairoDraw::BeginOp() { _cairo.Save(); _offsetStack.Add(actual_offset); _clipStack.Add(_actualClip); } void CairoDraw::EndOp() { _cairo.Restore(); actual_offset = _offsetStack.Pop(); _actualClip = _clipStack.Pop(); } void CairoDraw::OffsetOp(Point p) { Begin(); _cairo.Translate(p.x, p.y); actual_offset += p; _actualClip -= p; } bool CairoDraw::ClipOp(const Rect& r) { Begin(); _cairo.Rectangle(r.left, r.top, r.Width(), r.Height()); _cairo.Clip(); _actualClip &= r; return !_actualClip.IsEmpty(); } bool CairoDraw::ClipoffOp(const Rect& r) { Begin(); _cairo.Translate(r.left, r.top); _cairo.Rectangle(0, 0, r.Width(), r.Height()); _cairo.Clip(); actual_offset += r.TopLeft(); _actualClip &= r; _actualClip -= r.TopLeft(); return !_actualClip.IsEmpty(); } bool CairoDraw::ExcludeClipOp(const Rect& r) { _cairo.MoveTo(0, 0); _cairo.LineTo(_cairo.GetWidth(), 0); _cairo.LineTo(_cairo.GetWidth(), _cairo.GetHeight()); _cairo.LineTo(0, _cairo.GetHeight()); _cairo.LineTo(0, r.bottom); _cairo.LineTo(r.right, r.bottom); _cairo.LineTo(r.right, r.top); _cairo.LineTo(r.left, r.top); _cairo.LineTo(r.left, r.bottom); _cairo.LineTo(0, r.bottom); _cairo.ClosePath(); _cairo.Clip(); return !_actualClip.IsEmpty(); } bool CairoDraw::IntersectClipOp(const Rect& r) { _cairo.Rectangle(r.left, r.top, r.Width(), r.Height()); _cairo.Clip(); _actualClip &= r; return !_actualClip.IsEmpty(); } Rect CairoDraw::GetClipOp() const { return _actualClip; } bool CairoDraw::IsPaintingOp(const Rect& r) const { return true; } void CairoDraw::DrawRectOp(int x, int y, int cx, int cy, Color color) { _cairo.Rectangle(x, y, cx, cy); _cairo.SetSourceRGB(color); _cairo.Fill(); } void CairoDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) { _cairo.Save(); cairo_t *context = _cairo.GetContext(); ASSERT(context != NULL); cairo_surface_t *imgSurface = cairo_image_surface_create_for_data((unsigned char *)&(img[0]->b), CAIRO_FORMAT_ARGB32, img.GetWidth(), img.GetHeight(), img.GetWidth() * 4); _cairo.Translate(x, y); _cairo.Scale((double)cx / img.GetWidth(), (double)cy / img.GetHeight()); cairo_set_source_surface(context, imgSurface, 0, 0); cairo_rectangle(context, 0, 0, cx, cy); //todo: src rect _cairo.Fill(); cairo_surface_destroy(imgSurface); _cairo.Restore(); } void CairoDraw::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) { if (width == 0) width = 1; _cairo.SetLineCap(CAIRO_LINE_CAP_ROUND); _cairo.SetSourceRGB(color); _cairo.SetLineWidth(width); _cairo.MoveTo(x1 + 0.5, y1 + 0.5); _cairo.LineTo(x2 + 0.5, y2 + 0.5); _cairo.Stroke(); } void CairoDraw::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, int count_count, int width, Color color, Color doxor) { if (width == 0) width = 1; for (int i = 0; i < count_count; i++) { ASSERT(counts[i] >= 1); _cairo.MoveTo(vertices->x + 0.5, vertices->y + 0.5); vertices++; for (int j = 1; j < counts[i]; j++, vertices++) _cairo.LineTo(vertices->x + 0.5, vertices->y + 0.5); } _cairo.SetLineCap(CAIRO_LINE_CAP_ROUND); _cairo.SetLineJoin(CAIRO_LINE_JOIN_ROUND); _cairo.SetLineWidth(width); _cairo.SetSourceRGB(color); _cairo.Stroke(); } void CairoDraw::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) { if (width == 0) width = 1; for (int i = 0; i < scc; i++) { ASSERT(subpolygon_counts[i] >= 1); _cairo.MoveTo(vertices->x, vertices->y); vertices++; for (int j = 1; j < subpolygon_counts[i]; j++, vertices++) _cairo.LineTo(vertices->x, vertices->y); _cairo.ClosePath(); } _cairo.SetSourceRGB(color); _cairo.Fill(true); _cairo.SetLineCap(CAIRO_LINE_CAP_ROUND); _cairo.SetLineJoin(CAIRO_LINE_JOIN_ROUND); _cairo.SetLineWidth(width); _cairo.SetSourceRGB(outline); _cairo.Stroke(); } void CairoDraw::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) { if (pen == 0) pen = 1; _cairo.Save(); _cairo.Translate(r.left + (r.Width() / 2.0), r.top + (r.Height() / 2.0)); _cairo.Scale(r.Width() / 2.0, r.Height() / 2.0); _cairo.Arc(0.0, 0.0, 1.0, 0.0, 2 * M_PI); _cairo.Restore(); _cairo.SetSourceRGB(color); _cairo.Fill(pen != (int)Null); if (pen != (int)Null) { _cairo.SetLineWidth(pen); _cairo.SetSourceRGB(pencolor); _cairo.Stroke(); } } void CairoDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) { if (width == 0) width = 1; //TODO } void CairoDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { cairo_t *context = _cairo.GetContext(); ASSERT(context != NULL); /*HFONT hFont = CreateFont(font.GetHeight() ? -abs(font.GetHeight()) : -12, font.GetWidth(), angle, angle, font.IsBold() ? FW_BOLD : FW_NORMAL, font.IsItalic(), font.IsUnderline(), font.IsStrikeout(), Font::GetFaceInfo(font.GetFace()) & Font::SYMBOLTYPE ? SYMBOL_CHARSET : DEFAULT_CHARSET, font.IsTrueTypeOnly() ? OUT_TT_ONLY_PRECIS : OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, font.IsNonAntiAliased() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, Font::GetFaceName(font.GetFace())/*sFontFace().GetKey(font.GetFace())* /); cairo_font_face_t *fontFace = cairo_win32_font_face_create_for_hfont(hFont); cairo_set_font_face(context, fontFace);*/ cairo_set_font_size(context, font.GetHeight()); _cairo.Save(); _cairo.Translate(x, y + (font.GetHeight() ? abs(font.GetHeight()) : 12)); _cairo.Rotate(angle * (-3.14159 / 1800.0)); _cairo.SetSourceRGB(ink); WString tempWString = text; cairo_show_text(context, tempWString.ToString()); _cairo.NewPath(); _cairo.Restore(); /*cairo_font_face_destroy(fontFace);*/ } END_UPP_NAMESPACE