Files
ResInsight/ThirdParty/custom-clipper/clipper/cpp_cairo/main.cpp

183 lines
5.1 KiB
C++

//---------------------------------------------------------------------------
#include <windows.h>
#include <cstring>
#include <cmath>
#include <sstream>
#pragma hdrstop
#include "clipper.hpp"
#include "cairo.h"
#include "cairo-win32.h"
#include "cairo_clipper.hpp"
//---------------------------------------------------------------------------
int offsetVal;
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WCHAR* ClsName = L"CairoApp";
WCHAR* WndName = L"A Simple Cairo Clipper Demo";
offsetVal = 0;
MSG Msg;
HWND hWnd;
WNDCLASSEX WndClsEx;
// Create the application window
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the application
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow(ClsName, WndName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL, hInstance, NULL);
if( !hWnd ) return 0;
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
while( GetMessage(&Msg, NULL, 0, 0) )
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
//------------------------------------------------------------------------------
void OnPaint(HWND hWnd, HDC dc)
{
RECT rec;
GetClientRect(hWnd, &rec);
cairo_surface_t* surface = cairo_win32_surface_create(dc);
cairo_t* cr = cairo_create(surface);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
cairo_set_line_width (cr, 2.0);
//fill background with white ...
cairo_rectangle(cr, 0, 0, rec.right, rec.bottom);
cairo_set_source_rgba(cr, 1, 1, 1, 1);
cairo_fill(cr);
using namespace ClipperLib;
const int scaling = 2;
Clipper clpr; //clipper class
Paths pg; //std::vector for polygon(s) storage
//create a circular pattern, add the path to clipper and then draw it ...
cairo_arc(cr, 170,110,70,0,2*3.1415926);
cairo_close_path(cr);
cairo::cairo_to_clipper(cr, pg, scaling);
clpr.AddPaths(pg, ptSubject, true);
cairo_set_source_rgba(cr, 0, 0, 1, 0.25);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
//draw a star and another circle, add them to clipper and draw ...
cairo_move_to(cr, 60,110);
cairo_line_to (cr, 240,70);
cairo_line_to (cr, 110,210);
cairo_line_to (cr, 140,25);
cairo_line_to (cr, 230,200);
cairo_close_path(cr);
cairo_new_sub_path(cr);
cairo_arc(cr, 190,50,20,0,2*3.1415926);
cairo_close_path(cr);
cairo::cairo_to_clipper(cr, pg, scaling);
clpr.AddPaths(pg, ptClip, true);
cairo_set_source_rgba(cr, 1, 0, 0, 0.25);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
clpr.Execute(ctIntersection, pg, pftNonZero, pftNonZero);
//now do something fancy with the returned polygons ...
OffsetPaths(pg, pg, offsetVal * std::pow((double)10,scaling), jtMiter, etClosed);
//finally copy the clipped path back to the cairo context and draw it ...
cairo::clipper_to_cairo(pg, cr, scaling);
cairo_set_source_rgba(cr, 1, 1, 0, 1);
cairo_fill_preserve (cr);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_stroke (cr);
cairo_text_extents_t extent;
cairo_set_font_size(cr,11);
std::stringstream ss;
ss << "Polygon offset = " << offsetVal << ". (Adjust with arrow keys)";
std::string s = ss.str();
cairo_text_extents(cr, s.c_str(), &extent);
cairo_move_to(cr, 10, rec.bottom - extent.height);
cairo_show_text(cr, s.c_str());
cairo_destroy (cr);
cairo_surface_destroy (surface);
}
//------------------------------------------------------------------------------
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC Handle;
switch(Msg)
{
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
return 0;
case WM_PAINT:
Handle = BeginPaint(hWnd, &ps);
OnPaint(hWnd, Handle);
EndPaint(hWnd, &ps);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
case VK_RIGHT:
case VK_UP:
if (offsetVal < 20) offsetVal++;
InvalidateRect(hWnd, 0, false);
return 0;
case VK_LEFT:
case VK_DOWN:
if (offsetVal > -20) offsetVal--;
InvalidateRect(hWnd, 0, false);
return 0;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
}
//---------------------------------------------------------------------------