mirror of https://github.com/fltk/fltk
Android: Reinstated working simple cliping functionality based on an
improved Fl_Rect_Region class instead of Fl_Rect. Commented out complex clipping. Android lib and apps now use C++11 because they can (and I like it). git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12741 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
371cfd1476
commit
1b52ead802
35
FL/Fl_Rect.H
35
FL/Fl_Rect.H
|
@ -40,42 +40,29 @@ public:
|
|||
|
||||
/** The default constructor creates an empty rectangle (x = y = w = h = 0). */
|
||||
Fl_Rect()
|
||||
: x_(0), y_(0), w_(0), h_(0) {}
|
||||
: x_(0), y_(0), w_(0), h_(0) {}
|
||||
|
||||
/** This constructor creates a rectangle with x = y = 0 and
|
||||
the given width and height. */
|
||||
Fl_Rect(int W, int H)
|
||||
: x_(0), y_(0), w_(W), h_(H) {}
|
||||
: x_(0), y_(0), w_(W), h_(H) {}
|
||||
|
||||
/** This constructor creates a rectangle with the given x,y coordinates
|
||||
and the given width and height. */
|
||||
Fl_Rect(int X, int Y, int W, int H)
|
||||
: x_(X), y_(Y), w_(W), h_(H) {}
|
||||
: x_(X), y_(Y), w_(W), h_(H) {}
|
||||
|
||||
/** This constructor creates a rectangle based on a widget's position and size. */
|
||||
/** Copy constructor. */
|
||||
Fl_Rect (const Fl_Rect& r)
|
||||
: x_(r.x()), y_(r.y()), w_(r.w()), h_(r.h()) {}
|
||||
|
||||
/** This constructor creates a rectangle based a widget's position and size. */
|
||||
Fl_Rect (const Fl_Widget& widget)
|
||||
: x_(widget.x()), y_(widget.y()), w_(widget.w()), h_(widget.h()) {}
|
||||
: x_(widget.x()), y_(widget.y()), w_(widget.w()), h_(widget.h()) {}
|
||||
|
||||
/** This constructor creates a rectangle based on a widget's position and size. */
|
||||
/** This constructor creates a rectangle based a widget's position and size. */
|
||||
Fl_Rect (const Fl_Widget* const widget)
|
||||
: x_(widget->x()), y_(widget->y()), w_(widget->w()), h_(widget->h()) {}
|
||||
|
||||
virtual ~Fl_Rect() { }
|
||||
|
||||
/** Return 1 if the rectangle is empty, width or height are 0 */
|
||||
int is_empty() { return (w_<=0)||(h_<=0); }
|
||||
|
||||
/** Set the position and size */
|
||||
virtual void set(int x, int y, int w, int h) { x_=x; y_=y; w_=w; h_=h; }
|
||||
|
||||
/** Clone another rectangle */
|
||||
virtual void set(Fl_Rect *r) { x_=r->x_; y_=r->y_; w_=r->w_; h_=r->h_; }
|
||||
|
||||
/** return 0 if the rectangles are different, or 1 if they are the same */
|
||||
int equals(int x, int y, int w, int h) { return ( (x_==x) && (y_==y) && (w_==w) && (h_==h) ); }
|
||||
|
||||
/** Set the position and size to zero, making this rect empty */
|
||||
void clear() { x_ = y_ = w_ = h_ = 0; }
|
||||
: x_(widget->x()), y_(widget->y()), w_(widget->w()), h_(widget->h()) {}
|
||||
|
||||
int x() const { return x_; } ///< gets the x coordinate (left edge)
|
||||
int y() const { return y_; } ///< gets the y coordinate (top edge)
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
set(FLTK_DIR ../../../../../..)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
|
||||
# FIXME: add as a second argument the binary build dir
|
||||
# so that the first argument can link directly to FLTK
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <FL/fl_draw.H>
|
||||
|
||||
|
||||
Fl_Window *win, *win2, *win3;
|
||||
Fl_Window *win;
|
||||
Fl_Button *btn;
|
||||
|
||||
|
||||
|
@ -31,30 +31,20 @@ class MyButton : public Fl_Button
|
|||
public:
|
||||
MyButton(int x, int y, int w, int h, const char *l) : Fl_Button(x, y, w, h, l) { }
|
||||
void draw() {
|
||||
fl_push_clip(x(), y(), w()*2/3, h()*2/3);
|
||||
//fl_push_clip(x(), y(), w()*2/3, h()*2/3);
|
||||
Fl_Button::draw();
|
||||
fl_pop_clip();
|
||||
//fl_pop_clip();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
win2 = new Fl_Window(100, 50, 150, 200, "on bottom");
|
||||
win2->color(FL_BLUE);
|
||||
win2->end();
|
||||
win2->show();
|
||||
|
||||
win = new Fl_Window(50, 150, 500, 400, "Hallo");
|
||||
btn = new MyButton((win->w()-280)/2, 200, 280, 35, "Hello, Android!");
|
||||
btn->color(FL_LIGHT2);
|
||||
win->show(argc, argv);
|
||||
/*
|
||||
win3 = new Fl_Window(300, 50, 150, 200, "on top");
|
||||
win3->color(FL_RED);
|
||||
win3->end();
|
||||
win3->show();
|
||||
*/
|
||||
|
||||
Fl::run();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -296,6 +296,8 @@ elseif (ANDROID)
|
|||
|
||||
# Android
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set (DRIVER_FILES
|
||||
drivers/Android/Fl_Android_Application.cxx
|
||||
drivers/Android/Fl_Android_System_Driver.cxx
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define FL_ANDROID_GRAPHICS_DRIVER_H
|
||||
|
||||
#include <FL/Fl_Graphics_Driver.H>
|
||||
#include <FL/Fl_Rect.H>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
|
@ -34,34 +33,53 @@ class Fl_Android_Window_Driver;
|
|||
|
||||
|
||||
/**
|
||||
* The Fl_Rect_Region is based on Fl_Rect with additional functionality for clipping.
|
||||
* The Fl_Rect_Region describes a rectangular clipping region.
|
||||
*
|
||||
* Contrary to common FLTK convention, rectangles are stored with coordinates
|
||||
* instead of their width and height to accelerate calculations. The discreet
|
||||
* constructor however uses the old convention for convenience.
|
||||
*/
|
||||
class Fl_Rect_Region : public Fl_Rect
|
||||
class Fl_Rect_Region
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
EMPTY = 0, SAME, LESS, MORE
|
||||
enum Type {
|
||||
EMPTY = 0, SAME, LESS, MORE, INFINITE
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty clipping region.
|
||||
*/
|
||||
Fl_Rect_Region() {}
|
||||
Fl_Rect_Region();
|
||||
Fl_Rect_Region(int x, int y, int w, int h);
|
||||
Fl_Rect_Region(const Fl_Rect_Region&);
|
||||
Fl_Rect_Region(enum Type what);
|
||||
virtual ~Fl_Rect_Region() { }
|
||||
|
||||
/**
|
||||
* Create a clipping region based on position and size.
|
||||
* @param x, y position
|
||||
* @param w, h size
|
||||
*/
|
||||
Fl_Rect_Region(int x, int y, int w, int h) : Fl_Rect(x, y, w, h) {}
|
||||
int intersect_with(Fl_Rect_Region *r);
|
||||
virtual void print();
|
||||
int x() const { return pLeft; }
|
||||
int y() const { return pTop; }
|
||||
int w() const { return pRight - pLeft; }
|
||||
int h() const { return pBottom - pTop; }
|
||||
|
||||
static int min(int a, int b) { return (a<b) ? a : b; }
|
||||
static int max(int a, int b) { return (a>b) ? a : b; }
|
||||
int left() const { return pLeft; }
|
||||
int top() const { return pTop; }
|
||||
int right() const { return pRight; }
|
||||
int bottom() const { return pBottom; }
|
||||
|
||||
bool is_empty() const;
|
||||
bool is_infinite() const;
|
||||
|
||||
void set_empty();
|
||||
void set(int x, int y, int w, int h);
|
||||
void set(const Fl_Rect_Region &r);
|
||||
int intersect_with(const Fl_Rect_Region &r);
|
||||
|
||||
virtual void print(const char*) const;
|
||||
|
||||
protected:
|
||||
int pLeft, pTop, pRight, pBottom;
|
||||
|
||||
private:
|
||||
Fl_Rect_Region& operator = (const Fl_Rect_Region& other);
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* The Fl_Complex_Region represents a clipping region of any shape.
|
||||
*
|
||||
|
@ -85,9 +103,9 @@ public:
|
|||
Fl_Complex_Region(int x, int y, int w, int h) : Fl_Rect_Region(x, y, w, h), pSubregion(0L), pNext(0L) { }
|
||||
~Fl_Complex_Region();
|
||||
virtual void set(int x, int y, int w, int h);
|
||||
virtual void set(Fl_Rect *rect);
|
||||
void subtract(Fl_Rect*);
|
||||
void intersect(Fl_Rect*);
|
||||
virtual void set(Fl_Rect_Region*);
|
||||
void subtract(Fl_Rect_Region*);
|
||||
void intersect(Fl_Rect_Region*);
|
||||
void clone(Fl_Complex_Region*);
|
||||
char is_simple() { return pSubregion==0; }
|
||||
char is_complex() { return pSubregion!=0; }
|
||||
|
@ -97,6 +115,7 @@ protected:
|
|||
Fl_Complex_Region *pSubregion;
|
||||
Fl_Complex_Region *pNext;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -244,10 +263,8 @@ protected:
|
|||
int32_t pStride;
|
||||
uint16_t *pBits;
|
||||
|
||||
// Fl_Rect_Region pScreenRegion;
|
||||
Fl_Rect_Region *pWindowRegion;
|
||||
Fl_Complex_Region *pDesktopRegion;
|
||||
Fl_Complex_Region *pClippingRegion;
|
||||
Fl_Rect_Region pWindowRegion;
|
||||
Fl_Rect_Region pClippingRegion;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,10 +37,7 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
|
|||
|
||||
|
||||
Fl_Android_Graphics_Driver::Fl_Android_Graphics_Driver() :
|
||||
pStride(0), pBits(0),
|
||||
pWindowRegion(new Fl_Rect_Region()),
|
||||
pDesktopRegion(new Fl_Complex_Region()),
|
||||
pClippingRegion(new Fl_Complex_Region())
|
||||
pStride(0), pBits(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -52,8 +49,6 @@ Fl_Android_Graphics_Driver::~Fl_Android_Graphics_Driver()
|
|||
|
||||
void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
|
||||
{
|
||||
Fl_Android_Application::log_i("------------ make current \"%s\"", win->label());
|
||||
|
||||
// The Stride is the offset between lines in the graphics buffer
|
||||
pStride = Fl_Android_Application::graphics_buffer().stride;
|
||||
// Bits is the memory address of the top left corner of the window
|
||||
|
@ -62,13 +57,10 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
|
|||
|
||||
// TODO: set the clipping area
|
||||
// set the clipping area to the physical screen size in window coordinates
|
||||
pWindowRegion->set(-win->x(), -win->y(), 600, 800);
|
||||
Fl_Rect_Region wr(0, 0, win->w(), win->h());
|
||||
pWindowRegion->intersect_with(&wr);
|
||||
pWindowRegion->print();
|
||||
|
||||
pDesktopRegion->set(pWindowRegion);
|
||||
pWindowRegion.set(-win->x(), -win->y(), 600, 800);
|
||||
pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h()));
|
||||
|
||||
#if 0
|
||||
// remove all window rectangles that are positioned on top of this window
|
||||
// TODO: this region is expensive to calculate. Cache it for each window and recalculate when windows move, show, hide, or change order
|
||||
Fl_Window *wTop = Fl::first_window();
|
||||
|
@ -78,11 +70,9 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
|
|||
pDesktopRegion->subtract(&r);
|
||||
wTop = Fl::next_window(wTop);
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: we can optimize this by using some "copy on write" system
|
||||
pClippingRegion->clone(pDesktopRegion);
|
||||
pClippingRegion->print();
|
||||
Fl_Android_Application::log_i("------------ make current done");
|
||||
pClippingRegion.set(pWindowRegion);
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,7 +96,7 @@ static uint16_t make565(Fl_Color crgba)
|
|||
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h)
|
||||
{
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with((Fl_Rect_Region*)pClippingRegion)) {
|
||||
if (r.intersect_with(pClippingRegion)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
// TODO: create a complex region by intersecting r with the pClippingRegion
|
||||
|
@ -135,8 +125,8 @@ void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float
|
|||
*/
|
||||
}
|
||||
|
||||
void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, float h) {
|
||||
Fl_Android_Application::log_w("rectf unclipped %g %g %g %g", x, y, w, h);
|
||||
void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, float h)
|
||||
{
|
||||
if (w<=0 || h<=0) return;
|
||||
|
||||
// TODO: clip the rectangle to the window outline
|
||||
|
|
|
@ -23,41 +23,132 @@
|
|||
#include <FL/platform.H>
|
||||
|
||||
|
||||
// return 0 for empty, 1 for same, 2 if intersecting
|
||||
int Fl_Rect_Region::intersect_with(Fl_Rect_Region *a)
|
||||
/**
|
||||
* Create an empty clipping region.
|
||||
*/
|
||||
Fl_Rect_Region::Fl_Rect_Region() :
|
||||
pLeft(0), pTop(0), pRight(0), pBottom(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clipping region based on position and size.
|
||||
* @param x, y position
|
||||
* @param w, h size
|
||||
*/
|
||||
Fl_Rect_Region::Fl_Rect_Region(int x, int y, int w, int h) :
|
||||
pLeft(x), pTop(y), pRight(x+w), pBottom(y+h)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a clipping rectangle.
|
||||
*/
|
||||
Fl_Rect_Region::Fl_Rect_Region(const Fl_Rect_Region &r) :
|
||||
pLeft(r.pLeft), pTop(r.pTop),
|
||||
pRight(r.pRight), pBottom(r.pBottom)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a clipping rectangle.
|
||||
* The pointer can be NULL if an empty rectangle is needed.
|
||||
*/
|
||||
Fl_Rect_Region::Fl_Rect_Region(enum Type what)
|
||||
{
|
||||
if (what==INFINITE) {
|
||||
pLeft = pTop = INT_MIN;
|
||||
pRight = pBottom = INT_MAX;
|
||||
} else {
|
||||
pLeft = pTop = pRight = pBottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the rectangle has no width or height, it's considered empty.
|
||||
* @return true, if everything will be clipped and there is nothing to draw
|
||||
*/
|
||||
bool Fl_Rect_Region::is_empty() const
|
||||
{
|
||||
return (pRight<=pLeft || pBottom<=pTop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the rectangle is of unlimited size and nothing should be clipped.
|
||||
* @return treu, if there is no clipping
|
||||
*/
|
||||
bool Fl_Rect_Region::is_infinite() const
|
||||
{
|
||||
return (pLeft==INT_MIN);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Rect_Region::set_empty()
|
||||
{
|
||||
pLeft = pTop = pRight = pBottom = 0;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Rect_Region::set(int x, int y, int w, int h)
|
||||
{
|
||||
pLeft = x;
|
||||
pTop = y;
|
||||
pRight = x+w;
|
||||
pBottom = y+h;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Rect_Region::set(const Fl_Rect_Region &r)
|
||||
{
|
||||
pLeft = r.pLeft;
|
||||
pTop = r.pTop;
|
||||
pRight = r.pRight;
|
||||
pBottom = r.pBottom;
|
||||
}
|
||||
|
||||
|
||||
int Fl_Rect_Region::intersect_with(const Fl_Rect_Region &r)
|
||||
{
|
||||
if (is_empty()) {
|
||||
return EMPTY;
|
||||
}
|
||||
if (a->is_empty()) {
|
||||
clear();
|
||||
if (r.is_empty()) {
|
||||
set_empty();
|
||||
return EMPTY;
|
||||
}
|
||||
int lx = max(x(), a->x());
|
||||
int ly = max(y(), a->y());
|
||||
int lr = min(r(), a->r());
|
||||
int lb = min(b(), a->b());
|
||||
int lw = lr-lx;
|
||||
int lh = lb-ly;
|
||||
if (equals(lx, ly, lw, lh)) {
|
||||
bool same = true;
|
||||
if ( pLeft != r.pLeft ) {
|
||||
same = false;
|
||||
if ( r.pLeft > pLeft ) pLeft = r.pLeft;
|
||||
}
|
||||
if ( pTop != r.pTop ) {
|
||||
same = false;
|
||||
if ( r.pTop > pTop ) pTop = r.pTop;
|
||||
}
|
||||
if ( pRight != r.pRight ) {
|
||||
same = false;
|
||||
if ( r.pRight < pRight ) pRight = r.pRight;
|
||||
}
|
||||
if ( pBottom != r.pBottom ) {
|
||||
same = false;
|
||||
if ( r.pBottom < pBottom ) pBottom = r.pBottom;
|
||||
}
|
||||
if (same)
|
||||
return SAME;
|
||||
}
|
||||
set(lx, ly, lw, lh);
|
||||
if ( (w()<=0) || (h()<=0) ) {
|
||||
clear();
|
||||
if (is_empty())
|
||||
return EMPTY;
|
||||
}
|
||||
return LESS;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Rect_Region::print()
|
||||
void Fl_Rect_Region::print(const char *label) const
|
||||
{
|
||||
Fl_Android_Application::log_i("-------- begin rect");
|
||||
Fl_Android_Application::log_i("---> Fl_Rect_Region: %s", label);
|
||||
Fl_Android_Application::log_i("Rect %d %d %d %d", x(), y(), w(), h());
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
Fl_Complex_Region::~Fl_Complex_Region()
|
||||
{
|
||||
|
@ -151,6 +242,7 @@ void Fl_Complex_Region::print()
|
|||
print_data(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -158,18 +250,12 @@ void Fl_Android_Graphics_Driver::restore_clip()
|
|||
{
|
||||
fl_clip_state_number++;
|
||||
|
||||
// TODO: we can optimize this by using some "copy on write" system
|
||||
Fl_Android_Application::log_i("------------ restore_clip");
|
||||
pDesktopRegion->print();
|
||||
//pClippingRegion->set(pWindowRegion);
|
||||
pClippingRegion->clone(pDesktopRegion);
|
||||
pClippingRegion.set(pWindowRegion);
|
||||
|
||||
Fl_Region b = rstack[rstackptr];
|
||||
if (b) {
|
||||
pClippingRegion->intersect_with(b);
|
||||
pClippingRegion->print();
|
||||
pClippingRegion.intersect_with(*b);
|
||||
}
|
||||
Fl_Android_Application::log_i("------------ restore_clip done");
|
||||
}
|
||||
|
||||
|
||||
|
@ -193,10 +279,10 @@ void Fl_Android_Graphics_Driver::push_clip(int x, int y, int w, int h)
|
|||
{
|
||||
Fl_Region r;
|
||||
if (w > 0 && h > 0) {
|
||||
r = new Fl_Rect_Region(x,y,w,h);
|
||||
r = new Fl_Rect_Region(x, y, w, h);
|
||||
Fl_Region current = rstack[rstackptr];
|
||||
if (current) {
|
||||
r->intersect_with(current);
|
||||
r->intersect_with(*current);
|
||||
}
|
||||
} else { // make empty clip region:
|
||||
r = new Fl_Rect_Region();
|
||||
|
@ -239,19 +325,18 @@ void Fl_Android_Graphics_Driver::pop_clip()
|
|||
int Fl_Android_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H)
|
||||
{
|
||||
Fl_Region r = rstack[rstackptr];
|
||||
if (!r) {
|
||||
if (r) {
|
||||
Fl_Rect_Region a(x, y, w, h);
|
||||
int ret = a.intersect_with(*r);
|
||||
X = a.x();
|
||||
Y = a.y();
|
||||
W = a.w();
|
||||
H = a.h();
|
||||
return (ret!=Fl_Rect_Region::SAME);
|
||||
} else {
|
||||
X = x; Y = y; W = w; H = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Fl_Rect_Region a(x, y, w, h);
|
||||
int ret = a.intersect_with(r); // return 0 for empty, 1 for same, 2 if intersecting
|
||||
X = a.x();
|
||||
Y = a.y();
|
||||
W = a.w();
|
||||
H = a.h();
|
||||
|
||||
return (ret!=1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -264,72 +349,19 @@ int Fl_Android_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int
|
|||
Under X this returns 2 if the rectangle is partially clipped,
|
||||
and 1 if it is entirely inside the clip region.
|
||||
*/
|
||||
int Fl_Android_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
|
||||
if (x+w <= 0 || y+h <= 0) return 0;
|
||||
int Fl_Android_Graphics_Driver::not_clipped(int x, int y, int w, int h)
|
||||
{
|
||||
if (w <= 0 || h <= 0) return 0;
|
||||
Fl_Region r = rstack[rstackptr];
|
||||
if (!r) return 1;
|
||||
|
||||
Fl_Rect_Region a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting
|
||||
return a.intersect_with(r);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// --- clipping
|
||||
|
||||
int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
|
||||
X = x; Y = y; W = w; H = h;
|
||||
Fl_Region r = rstack[rstackptr];
|
||||
if (!r) return 0;
|
||||
// The win32 API makes no distinction between partial and complete
|
||||
// intersection, so we have to check for partial intersection ourselves.
|
||||
// However, given that the regions may be composite, we have to do
|
||||
// some voodoo stuff...
|
||||
Fl_Region rr = XRectangleRegion(x,y,w,h);
|
||||
Fl_Region temp = CreateRectRgn(0,0,0,0);
|
||||
int ret;
|
||||
if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
|
||||
W = H = 0;
|
||||
ret = 2;
|
||||
} else if (EqualRgn(temp, rr)) { // complete
|
||||
ret = 0;
|
||||
} else { // partial intersection
|
||||
RECT rect;
|
||||
GetRgnBox(temp, &rect);
|
||||
if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // if print context, convert coords from device to logical
|
||||
POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} };
|
||||
DPtoLP(gc_, pt, 2);
|
||||
X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y;
|
||||
}
|
||||
else {
|
||||
X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
DeleteObject(temp);
|
||||
DeleteObject(rr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
|
||||
if (x+w <= 0 || y+h <= 0) return 0;
|
||||
Fl_Region r = rstack[rstackptr];
|
||||
if (!r) return 1;
|
||||
RECT rect;
|
||||
if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // in case of print context, convert coords from logical to device
|
||||
POINT pt[2] = { {x, y}, {x + w, y + h} };
|
||||
LPtoDP(gc_, pt, 2);
|
||||
rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y;
|
||||
if (r) {
|
||||
Fl_Rect_Region a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting
|
||||
return a.intersect_with(*r);
|
||||
} else {
|
||||
rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
|
||||
return 1;
|
||||
}
|
||||
return RectInRegion(r,&rect);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue