Added the Fl_Shaped_Window class to support windows of arbitrary shapes.
The new class is fully Doxygen-documented. Added an example program (example/shapedwindow.cxx) that exercises the new class. Modified all IDE-supporting files accordingly. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10255 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
22beee52af
commit
8997131377
78
FL/Fl_Shaped_Window.H
Normal file
78
FL/Fl_Shaped_Window.H
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// "$Id"
|
||||
//
|
||||
// Fl_Shaped_Window header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems to:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#ifndef Fl_Shaped_Window_H
|
||||
#define Fl_Shaped_Window_H
|
||||
|
||||
#include <FL/Fl_Window.H>
|
||||
#if defined(__APPLE__)
|
||||
#include <FL/x.H>
|
||||
#endif
|
||||
|
||||
|
||||
class Fl_Bitmap;
|
||||
class Fl_Pixmap;
|
||||
|
||||
/**
|
||||
The Fl_Shaped_Window is an Fl_Window that can take an arbitrary shape (not just a rectangular region).
|
||||
The window shape is determined by the argument of the Fl_Shaped_Window::shape(const Fl_Image*)
|
||||
member function.
|
||||
An Fl_Image of any dimension can be used as mask; it is rescaled to the window's dimension as needed.
|
||||
|
||||
The layout and widgets inside are unaware of the mask shape, and most will act as though the window's
|
||||
rectangular bounding box is available
|
||||
to them. It is up to you to make sure they adhere to the bounds of their masking shape.
|
||||
|
||||
On the Mac platform, OS version 10.4 or above is required.
|
||||
On the unix/linux platform, the SHAPE extension of the X server is required.
|
||||
|
||||
The window borders and caption created by the window system are turned off by default. They
|
||||
can be re-enabled by calling void Fl_Window::border(1).
|
||||
|
||||
A usage example is found at example/shapedwindow.cxx.
|
||||
*/
|
||||
class FL_EXPORT Fl_Shaped_Window : public Fl_Window {
|
||||
private:
|
||||
int lw_, lh_;
|
||||
Fl_Image* shape_;
|
||||
#if defined(__APPLE__)
|
||||
CGImageRef mask;
|
||||
#endif
|
||||
Fl_Bitmap *todelete_;
|
||||
void shape_bitmap_(Fl_Bitmap*);
|
||||
void shape_pixmap_(Fl_Pixmap*);
|
||||
void shape_alpha_(Fl_RGB_Image* img, int offset);
|
||||
protected:
|
||||
virtual void draw();
|
||||
public:
|
||||
Fl_Shaped_Window(int w, int h, const char* l = 0);
|
||||
Fl_Shaped_Window(int x, int y, int w, int h, const char* l = 0);
|
||||
~Fl_Shaped_Window();
|
||||
void shape(const Fl_Image*);
|
||||
/** Set the window's shape with an Fl_Image */
|
||||
inline void shape(const Fl_Image& b) { shape(&b); }
|
||||
#if ! (defined(WIN32) || defined(__APPLE__) || defined(FL_DOXYGEN))
|
||||
void combine_mask(void);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // Fl_Shaped_Window_H
|
||||
|
||||
//
|
||||
// End of "$Id".
|
||||
//
|
||||
@ -16,7 +16,7 @@
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
/* \file
|
||||
/** \file
|
||||
Fl_Window widget . */
|
||||
|
||||
#ifndef Fl_Window_H
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this
|
||||
#define FL_DOUBLE_WINDOW 0xF1 ///< double window type id
|
||||
#define FL_SHAPED_WINDOW 0xF2 ///< shaped window type id
|
||||
|
||||
class Fl_X;
|
||||
class Fl_RGB_Image;
|
||||
|
||||
125
examples/shapedwindow.cxx
Normal file
125
examples/shapedwindow.cxx
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// "$Id"
|
||||
//
|
||||
// shapedwindow example source file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems to:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Shaped_Window.H>
|
||||
#include <FL/Fl_Image.H>
|
||||
#include <FL/Fl_Tiled_Image.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include "test/pixmaps/tile.xpm"
|
||||
|
||||
|
||||
void cb(Fl_Widget *w, void *) {
|
||||
w->window()->hide();
|
||||
}
|
||||
|
||||
class dragbox : public Fl_Box {
|
||||
public:
|
||||
dragbox(int x, int y, int w, int h, const char *t=0) : Fl_Box(x,y,w,h,t) {};
|
||||
int handle(int event) {
|
||||
static int fromx, fromy, winx, winy;
|
||||
if (event == FL_PUSH) {
|
||||
fromx = Fl::event_x_root();
|
||||
fromy = Fl::event_y_root();
|
||||
winx = window()->x_root();
|
||||
winy = window()->y_root();
|
||||
return 1;
|
||||
}
|
||||
else if (event == FL_DRAG) {
|
||||
int deltax = Fl::event_x_root() - fromx;
|
||||
int deltay = Fl::event_y_root() - fromy;
|
||||
window()->resize(winx + deltax, winy + deltay, window()->w(), window()->h());
|
||||
return 1;
|
||||
}
|
||||
return Fl_Box::handle(event);
|
||||
}
|
||||
};
|
||||
|
||||
const float factor = 1.3;
|
||||
|
||||
void shrink(Fl_Widget *wdgt, void *data)
|
||||
{
|
||||
Fl_Window *win = wdgt->window();
|
||||
int old = win->w();
|
||||
win->size(old/factor, old/factor);
|
||||
if (win->w() <= *(int*)data) wdgt->deactivate();
|
||||
}
|
||||
|
||||
void enlarge(Fl_Widget *wdgt, void *data)
|
||||
{
|
||||
Fl_Window *win = wdgt->window();
|
||||
int old = win->w();
|
||||
win->size(old*factor, old*factor);
|
||||
((Fl_Widget*)data)->activate();
|
||||
}
|
||||
|
||||
Fl_RGB_Image* prepare_shape(int w)
|
||||
{
|
||||
// draw a white circle with a hole in it on black background
|
||||
Fl_Image_Surface *surf = new Fl_Image_Surface(w, w);
|
||||
Fl_Surface_Device* current = Fl_Surface_Device::surface();
|
||||
surf->set_current();
|
||||
fl_color(FL_BLACK);
|
||||
fl_rectf(-1, -1, w+2, w+2);
|
||||
fl_color(FL_WHITE);
|
||||
fl_pie(2,2,w-4,w-4,0,360);
|
||||
fl_color(FL_BLACK);
|
||||
fl_pie(0.7*w,w/2,w/4,w/4,0,360);
|
||||
Fl_RGB_Image* img = surf->image();
|
||||
delete surf;
|
||||
current->set_current();
|
||||
return img; // return depth-3 white image on black background
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int dim = 200;
|
||||
Fl_Shaped_Window *win = new Fl_Shaped_Window(100, 100, dim, dim, "Testing1");
|
||||
Fl_RGB_Image *img = prepare_shape(dim);
|
||||
win->shape(img);
|
||||
dragbox *box = new dragbox(0, 0, win->w(), win->h());
|
||||
box->image(new Fl_Tiled_Image(new Fl_Pixmap((const char * const *)tile_xpm)));
|
||||
Fl_Group *g = new Fl_Group(10, 20, 80, 20);
|
||||
g->box(FL_NO_BOX);
|
||||
Fl_Button *b = new Fl_Button(10, 20, 80, 20, "Close");
|
||||
b->callback(cb);
|
||||
g->end();
|
||||
g->resizable(NULL);
|
||||
g = new Fl_Group(60, 70, 80, 40, "Drag me");
|
||||
g->box(FL_NO_BOX);
|
||||
g->align(FL_ALIGN_TOP);
|
||||
Fl_Button *bs = new Fl_Button(60, 70, 80, 20, "Shrink");
|
||||
bs->callback(shrink, &dim);
|
||||
bs->deactivate();
|
||||
Fl_Button *be = new Fl_Button(60, 90, 80, 20, "Enlarge");
|
||||
be->callback(enlarge, bs);
|
||||
g->end();
|
||||
g->resizable(NULL);
|
||||
win->end();
|
||||
win->resizable(win);
|
||||
win->show(argc, argv);
|
||||
Fl::run();
|
||||
delete win;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id".
|
||||
//
|
||||
@ -655,6 +655,10 @@
|
||||
RelativePath="..\..\FL\Fl_Select_Browser.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FL\Fl_Shaped_Window.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\FL\Fl_Shared_Image.H"
|
||||
>
|
||||
@ -5340,7 +5344,53 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
<File
|
||||
RelativePath="..\..\src\Fl_Shaped_Window.cxx"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
FavorSizeOrSpeed="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Cairo|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BrowseInformation="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Cairo|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
FavorSizeOrSpeed="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Fl_Shared_Image.cxx"
|
||||
>
|
||||
<FileConfiguration
|
||||
|
||||
@ -5005,6 +5005,48 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Fl_Shaped_Window.cxx"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN;$(NoInherit)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN;$(NoInherit)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Cairo|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN;$(NoInherit)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Cairo|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN;$(NoInherit)"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Fl_Shared_Image.cxx"
|
||||
>
|
||||
|
||||
@ -256,6 +256,7 @@
|
||||
<ClInclude Include="..\..\FL\Fl_Scrollbar.H" />
|
||||
<ClInclude Include="..\..\FL\Fl_Secret_Input.H" />
|
||||
<ClInclude Include="..\..\FL\Fl_Select_Browser.H" />
|
||||
<ClInclude Include="..\..\FL\Fl_Shaped_Window.H" />
|
||||
<ClInclude Include="..\..\FL\Fl_Shared_Image.H" />
|
||||
<ClInclude Include="..\..\FL\fl_show_colormap.H" />
|
||||
<ClInclude Include="..\..\FL\fl_show_input.H" />
|
||||
@ -1855,7 +1856,23 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Fl_Shared_Image.cxx">
|
||||
<ClCompile Include="..\..\src\Fl_Shaped_Window.cxx">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">true</BrowseInformation>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release Cairo|Win32'">Neither</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Cairo|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Neither</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Fl_Shared_Image.cxx">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
||||
@ -268,6 +268,9 @@
|
||||
<ClInclude Include="..\..\FL\Fl_Select_Browser.H">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FL\Fl_Shaped_Window.H">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FL\Fl_Shared_Image.H">
|
||||
<Filter>Headers</Filter>
|
||||
</ClInclude>
|
||||
@ -481,6 +484,7 @@
|
||||
<ClCompile Include="..\..\src\fl_set_font.cxx" />
|
||||
<ClCompile Include="..\..\src\fl_set_fonts.cxx" />
|
||||
<ClCompile Include="..\..\src\fl_shadow_box.cxx" />
|
||||
<ClCompile Include="..\..\src\Fl_Shaped_Window.cxx" />
|
||||
<ClCompile Include="..\..\src\Fl_Shared_Image.cxx" />
|
||||
<ClCompile Include="..\..\src\fl_shortcut.cxx" />
|
||||
<ClCompile Include="..\..\src\fl_show_colormap.cxx" />
|
||||
|
||||
@ -1552,6 +1552,18 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Fl_Shaped_Window.cxx">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN</PreprocessorDefinitions>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Cairo|Win32'">_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_CRT_SECURE_NO_DEPRECATE;FL_DLL;FL_LIBRARY;WIN32;NDEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Fl_Shared_Image.cxx">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug Cairo|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
||||
@ -515,6 +515,10 @@ SOURCE=..\..\src\fl_shadow_box.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Fl_Shaped_Window.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Fl_Shared_Image.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -533,6 +533,10 @@ SOURCE=..\..\src\fl_shadow_box.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Fl_Shaped_Window.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Fl_Shared_Image.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -331,6 +331,7 @@
|
||||
7F74F393190D7F0500C56950 /* fl_gleam.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 299E717718BC503400FF83F2 /* fl_gleam.cxx */; };
|
||||
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E015192FAD420071728B /* Fl_Copy_Surface.cxx */; };
|
||||
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7F76E017192FAD590071728B /* Fl_Image_Surface.cxx */; };
|
||||
7FD807F719ADD610007622B2 /* Fl_Shaped_Window.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */; };
|
||||
7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */; };
|
||||
812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; };
|
||||
812761E94039F13357F56EE6 /* fltk_png.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; };
|
||||
@ -4347,6 +4348,8 @@
|
||||
7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; };
|
||||
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
||||
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7FD807F419ADD5F4007622B2 /* Fl_Shaped_Window.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Shaped_Window.H; path = ../../FL/Fl_Shaped_Window.H; sourceTree = SOURCE_ROOT; };
|
||||
7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Shaped_Window.cxx; path = ../../src/Fl_Shaped_Window.cxx; sourceTree = SOURCE_ROOT; };
|
||||
7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
|
||||
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; };
|
||||
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Group.cxx; path = ../../src/Fl_Group.cxx; sourceTree = SOURCE_ROOT; };
|
||||
@ -5505,6 +5508,7 @@
|
||||
13BCF00369D5254F0CE49599 /* Fl_Round_Button.cxx */,
|
||||
3F60A41762817C834FF38947 /* Fl_Scroll.cxx */,
|
||||
A5B9A5CE605BB8A57F66A2E6 /* Fl_Scrollbar.cxx */,
|
||||
7FD807F619ADD610007622B2 /* Fl_Shaped_Window.cxx */,
|
||||
57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */,
|
||||
9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */,
|
||||
5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */,
|
||||
@ -6293,6 +6297,7 @@
|
||||
28F3E4EBB6E5F8420624A5DA /* Fl_Scrollbar.H */,
|
||||
42FEA3A2967D04217C27FA61 /* Fl_Secret_Input.H */,
|
||||
9DA766AE10DC532F3D0401A2 /* Fl_Select_Browser.H */,
|
||||
7FD807F419ADD5F4007622B2 /* Fl_Shaped_Window.H */,
|
||||
A46A39199806D09CE0ABEE59 /* Fl_Shared_Image.H */,
|
||||
9B57B581401BD8575BFAF2F1 /* Fl_Simple_Counter.H */,
|
||||
0EC11A5CAD4E3607A72BEF84 /* Fl_Single_Window.H */,
|
||||
@ -9527,6 +9532,7 @@
|
||||
01C68DB0192C6089000BD75C /* Fl_sleep.cxx in Sources */,
|
||||
7F76E016192FAD420071728B /* Fl_Copy_Surface.cxx in Sources */,
|
||||
7F76E018192FAD590071728B /* Fl_Image_Surface.cxx in Sources */,
|
||||
7FD807F719ADD610007622B2 /* Fl_Shaped_Window.cxx in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@ -330,6 +330,7 @@
|
||||
7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; };
|
||||
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BD192FAEBB00519823 /* Fl_Copy_Surface.cxx */; };
|
||||
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5C2BF192FAECA00519823 /* Fl_Image_Surface.cxx */; };
|
||||
7FD8085119ADD6F2007622B2 /* Fl_Shaped_Window.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */; };
|
||||
7FDBB8F416B2D1EA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032516B1A90A000FC50F /* Localizable.strings */; };
|
||||
7FDBB8F516B2D1EE00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92032216B1A909000FC50F /* Localizable.strings */; };
|
||||
7FDBB8F616B2D1FA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031F16B1A909000FC50F /* Localizable.strings */; };
|
||||
@ -4342,6 +4343,8 @@
|
||||
7FA5C2C2192FAEF200519823 /* Fl_Copy_Surface.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Copy_Surface.H; path = ../../FL/Fl_Copy_Surface.H; sourceTree = SOURCE_ROOT; };
|
||||
7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; };
|
||||
7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7FD8084F19ADD6DE007622B2 /* Fl_Shaped_Window.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Shaped_Window.H; path = ../../FL/Fl_Shaped_Window.H; sourceTree = SOURCE_ROOT; };
|
||||
7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Shaped_Window.cxx; path = ../../src/Fl_Shaped_Window.cxx; sourceTree = SOURCE_ROOT; };
|
||||
7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; };
|
||||
800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; };
|
||||
806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Group.cxx; path = ../../src/Fl_Group.cxx; sourceTree = SOURCE_ROOT; };
|
||||
@ -5499,6 +5502,7 @@
|
||||
13BCF00369D5254F0CE49599 /* Fl_Round_Button.cxx */,
|
||||
3F60A41762817C834FF38947 /* Fl_Scroll.cxx */,
|
||||
A5B9A5CE605BB8A57F66A2E6 /* Fl_Scrollbar.cxx */,
|
||||
7FD8085019ADD6F2007622B2 /* Fl_Shaped_Window.cxx */,
|
||||
57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */,
|
||||
9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */,
|
||||
5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */,
|
||||
@ -6332,6 +6336,7 @@
|
||||
28F3E4EBB6E5F8420624A5DA /* Fl_Scrollbar.H */,
|
||||
42FEA3A2967D04217C27FA61 /* Fl_Secret_Input.H */,
|
||||
9DA766AE10DC532F3D0401A2 /* Fl_Select_Browser.H */,
|
||||
7FD8084F19ADD6DE007622B2 /* Fl_Shaped_Window.H */,
|
||||
A46A39199806D09CE0ABEE59 /* Fl_Shared_Image.H */,
|
||||
9B57B581401BD8575BFAF2F1 /* Fl_Simple_Counter.H */,
|
||||
0EC11A5CAD4E3607A72BEF84 /* Fl_Single_Window.H */,
|
||||
@ -9564,6 +9569,7 @@
|
||||
299CB8A2848CB844BCEC7829 /* Fl_Paged_Device.cxx in Sources */,
|
||||
7FA5C2BE192FAEBB00519823 /* Fl_Copy_Surface.cxx in Sources */,
|
||||
7FA5C2C0192FAECA00519823 /* Fl_Image_Surface.cxx in Sources */,
|
||||
7FD8085119ADD6F2007622B2 /* Fl_Shaped_Window.cxx in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@ -55,6 +55,7 @@ set(CPPFILES
|
||||
Fl_Round_Button.cxx
|
||||
Fl_Scroll.cxx
|
||||
Fl_Scrollbar.cxx
|
||||
Fl_Shaped_Window.cxx
|
||||
Fl_Shared_Image.cxx
|
||||
Fl_Single_Window.cxx
|
||||
Fl_Slider.cxx
|
||||
|
||||
369
src/Fl_Shaped_Window.cxx
Normal file
369
src/Fl_Shaped_Window.cxx
Normal file
@ -0,0 +1,369 @@
|
||||
//
|
||||
// "$Id"
|
||||
//
|
||||
// Fl_Shaped_Window source file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2010-2014 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// http://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please report all bugs and problems to:
|
||||
//
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
|
||||
#include <FL/x.H>
|
||||
#include <FL/Fl_Shaped_Window.H>
|
||||
#include <FL/Fl_Bitmap.H>
|
||||
#include <FL/Fl_Pixmap.H>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <malloc.h> // needed for VisualC2010
|
||||
#elif !defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
#define ShapeBounding 0
|
||||
#define ShapeSet 0
|
||||
#endif
|
||||
|
||||
/** Create a shaped window with the given size and title */
|
||||
Fl_Shaped_Window::Fl_Shaped_Window(int w, int h, const char* title)
|
||||
: Fl_Window(w, h, title), lw_(0), lh_(0), shape_(0), todelete_(0) {
|
||||
type(FL_SHAPED_WINDOW);
|
||||
border(false);
|
||||
#if defined(__APPLE__)
|
||||
mask = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Create a shaped window with the given position, size and title */
|
||||
Fl_Shaped_Window::Fl_Shaped_Window(int x, int y, int w, int h, const char* title)
|
||||
: Fl_Window(x, y, w, h, title), lw_(0), lh_(0), shape_(0), todelete_(0) {
|
||||
type(FL_SHAPED_WINDOW);
|
||||
border(false);
|
||||
#if defined(__APPLE__)
|
||||
mask = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Destroys the shaped window but not its associated Fl_Image */
|
||||
Fl_Shaped_Window::~Fl_Shaped_Window() {
|
||||
if (todelete_) delete todelete_;
|
||||
#if defined(__APPLE__)
|
||||
if (mask) {
|
||||
CGImageRelease(mask);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
static void MyProviderReleaseData (void *info, const void *data, size_t size) {
|
||||
delete[] (uchar*)data;
|
||||
}
|
||||
|
||||
// bitwise inversion of all 4-bit quantities
|
||||
static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
|
||||
|
||||
static inline uchar swap_byte(const uchar b) {
|
||||
// reverse the order of bits of byte b: 1->8 becomes 8->1
|
||||
return (swapped[b & 0xF] << 4) | swapped[b >> 4];
|
||||
}
|
||||
|
||||
void Fl_Shaped_Window::draw() {
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
if (mask && (CGContextClipToMask != NULL)) CGContextClipToMask(fl_gc, CGRectMake(0,0,w(),h()), mask); // requires Mac OS 10.4
|
||||
CGContextSaveGState(fl_gc);
|
||||
# endif
|
||||
Fl_Window::draw();
|
||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
CGContextRestoreGState(fl_gc);
|
||||
# endif
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
|
||||
static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); }
|
||||
|
||||
static HRGN bitmap2region(Fl_Bitmap* image) {
|
||||
HRGN hRgn = 0;
|
||||
/* Does this need to be dynamically determined, perhaps? */
|
||||
const int ALLOC_UNIT = 100;
|
||||
DWORD maxRects = ALLOC_UNIT;
|
||||
|
||||
RGNDATA* pData = (RGNDATA*)malloc(sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects));
|
||||
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
|
||||
pData->rdh.iType = RDH_RECTANGLES;
|
||||
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
|
||||
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
|
||||
|
||||
const int bytesPerLine = (image->w() + 7)/8;
|
||||
BYTE* p, *data = (BYTE*)image->array;
|
||||
for (int y = 0; y < image->h(); y++) {
|
||||
// each row, left to right
|
||||
for (int x = 0; x < image->w(); x++) {
|
||||
int x0 = x;
|
||||
while (x < image->w()) {
|
||||
p = data + x / 8;
|
||||
if (!((*p) & bit(x))) break; // transparent pixel
|
||||
x++;
|
||||
}
|
||||
if (x > x0) {
|
||||
RECT *pr;
|
||||
/* Add the pixels (x0, y) to (x, y+1) as a new rectangle
|
||||
* in the region
|
||||
*/
|
||||
if (pData->rdh.nCount >= maxRects) {
|
||||
maxRects += ALLOC_UNIT;
|
||||
pData = (RGNDATA*)realloc(pData, sizeof(RGNDATAHEADER)
|
||||
+ (sizeof(RECT)*maxRects));
|
||||
}
|
||||
pr = (RECT*)&pData->Buffer;
|
||||
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
|
||||
if (x0 < pData->rdh.rcBound.left)
|
||||
pData->rdh.rcBound.left = x0;
|
||||
if (y < pData->rdh.rcBound.top)
|
||||
pData->rdh.rcBound.top = y;
|
||||
if (x > pData->rdh.rcBound.right)
|
||||
pData->rdh.rcBound.right = x;
|
||||
if (y+1 > pData->rdh.rcBound.bottom)
|
||||
pData->rdh.rcBound.bottom = y+1;
|
||||
pData->rdh.nCount++;
|
||||
/* On Windows98, ExtCreateRegion() may fail if the
|
||||
* number of rectangles is too large (ie: >
|
||||
* 4000). Therefore, we have to create the region by
|
||||
* multiple steps.
|
||||
*/
|
||||
if (pData->rdh.nCount == 2000) {
|
||||
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
|
||||
+ (sizeof(RECT)*maxRects), pData);
|
||||
if (hRgn) {
|
||||
CombineRgn(hRgn, hRgn, h, RGN_OR);
|
||||
DeleteObject(h);
|
||||
} else
|
||||
hRgn = h;
|
||||
pData->rdh.nCount = 0;
|
||||
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Go to next row */
|
||||
data += bytesPerLine;
|
||||
}
|
||||
/* Create or extend the region with the remaining rectangles*/
|
||||
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
|
||||
+ (sizeof(RECT)*maxRects), pData);
|
||||
if (hRgn) {
|
||||
CombineRgn(hRgn, hRgn, h, RGN_OR);
|
||||
DeleteObject(h);
|
||||
} else hRgn = h;
|
||||
free(pData); // I've created the region so I can free this now, right?
|
||||
return hRgn;
|
||||
}
|
||||
|
||||
void Fl_Shaped_Window::draw() {
|
||||
if ((lw_ != w() || lh_ != h()) && shape_) {
|
||||
// size of window has changed since last time
|
||||
lw_ = w();
|
||||
lh_ = h();
|
||||
Fl_Bitmap* temp = (Fl_Bitmap*)shape_->copy(lw_, lh_);
|
||||
HRGN region = bitmap2region(temp);
|
||||
SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
|
||||
delete temp;
|
||||
}
|
||||
Fl_Window::draw();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
void Fl_Shaped_Window::combine_mask()
|
||||
{
|
||||
typedef void (*XShapeCombineMask_type)(Display*, int, int, int, int, Pixmap, int);
|
||||
static XShapeCombineMask_type XShapeCombineMask_f = NULL;
|
||||
static int beenhere = 0;
|
||||
typedef Bool (*XShapeQueryExtension_type)(Display*, int*, int*);
|
||||
int error_base, shapeEventBase;
|
||||
if (!beenhere) {
|
||||
beenhere = 1;
|
||||
fl_open_display();
|
||||
void *handle = dlopen(NULL, RTLD_LAZY); // search symbols in executable
|
||||
XShapeQueryExtension_type XShapeQueryExtension_f = (XShapeQueryExtension_type)dlsym(handle, "XShapeQueryExtension");
|
||||
XShapeCombineMask_f = (XShapeCombineMask_type)dlsym(handle, "XShapeCombineMask");
|
||||
// make sure that the X server has the SHAPE extension
|
||||
if ( !( XShapeQueryExtension_f && XShapeCombineMask_f &&
|
||||
XShapeQueryExtension_f(fl_display, &shapeEventBase, &error_base) ) ) XShapeCombineMask_f = NULL;
|
||||
}
|
||||
if (!XShapeCombineMask_f) return;
|
||||
lw_ = w();
|
||||
lh_ = h();
|
||||
Fl_Bitmap* temp = (Fl_Bitmap*)shape_->copy(lw_, lh_);
|
||||
Pixmap pbitmap = XCreateBitmapFromData(fl_display, fl_xid(this),
|
||||
(const char*)temp->array,
|
||||
temp->w(), temp->h());
|
||||
XShapeCombineMask_f(fl_display, fl_xid(this), ShapeBounding, 0, 0, pbitmap, ShapeSet);
|
||||
if (pbitmap != None) XFreePixmap(fl_display, pbitmap);
|
||||
delete temp;
|
||||
}
|
||||
#endif // !FL_DOXYGEN
|
||||
|
||||
void Fl_Shaped_Window::draw() {
|
||||
if (( lw_ != w() || lh_ != h() ) && shape_) {
|
||||
// size of window has changed since last time
|
||||
combine_mask();
|
||||
}
|
||||
Fl_Window::draw();
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
|
||||
void Fl_Shaped_Window::shape_bitmap_(Fl_Bitmap* b) {
|
||||
if (todelete_) { delete todelete_; todelete_ = NULL; }
|
||||
shape_ = b;
|
||||
lw_ = lh_ = 0; // so change in mask is detected
|
||||
#if defined(__APPLE__)
|
||||
if (mask) {
|
||||
CGImageRelease(mask);
|
||||
mask = NULL;
|
||||
}
|
||||
if (b) {
|
||||
// complement mask bits and perform bitwise inversion of all bytes and also reverse top and bottom
|
||||
int bytes_per_row = (b->w() + 7)/8;
|
||||
uchar *from = new uchar[bytes_per_row * b->h()];
|
||||
for (int i = 0; i < b->h(); i++) {
|
||||
uchar *p = (uchar*)b->array + bytes_per_row * i;
|
||||
uchar *last = p + bytes_per_row;
|
||||
uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
|
||||
while (p < last) {
|
||||
*q++ = swap_byte(~*p++);
|
||||
}
|
||||
}
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, bytes_per_row * b->h(), MyProviderReleaseData);
|
||||
mask = CGImageMaskCreate(b->w(), b->h(), 1, 1, bytes_per_row, provider, NULL, false);
|
||||
CFRelease(provider);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(__APPLE__) // on the mac, use an 8-bit mask
|
||||
/* the image can be of any depth
|
||||
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
||||
*/
|
||||
void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
||||
int i, d = img->d(), w = img->w(), h = img->h();
|
||||
if (todelete_) { delete todelete_; todelete_ = NULL; }
|
||||
shape_ = img;
|
||||
lw_ = lh_ = 0; // so change in mask is detected
|
||||
if (mask) {
|
||||
CGImageRelease(mask);
|
||||
mask = NULL;
|
||||
}
|
||||
if (shape_) {
|
||||
// reverse top and bottom and convert to gray scale if img->d() == 3 and complement bits
|
||||
int bytes_per_row = w * d;
|
||||
uchar *from = new uchar[w * h];
|
||||
for ( i = 0; i < h; i++) {
|
||||
uchar *p = (uchar*)img->array + bytes_per_row * i + offset;
|
||||
uchar *last = p + bytes_per_row;
|
||||
uchar *q = from + (h - 1 - i) * w;
|
||||
while (p < last) {
|
||||
if (d == 3) {
|
||||
unsigned u = *p++;
|
||||
u += *p++;
|
||||
u += *p++;
|
||||
*q++ = ~(u/3);
|
||||
}
|
||||
else {
|
||||
*q++ = ~(*p);
|
||||
p += d;
|
||||
}
|
||||
}
|
||||
}
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, w * h, MyProviderReleaseData);
|
||||
mask = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false);
|
||||
CFRelease(provider);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* the img image can be of any depth
|
||||
offset gives the byte offset from the pixel start to the byte used to construct the shape
|
||||
*/
|
||||
void Fl_Shaped_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
|
||||
int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8;
|
||||
unsigned u;
|
||||
uchar byte, onebit;
|
||||
// build an Fl_Bitmap covering the non-fully transparent/black part of the image
|
||||
const uchar* bits = new uchar[h*bytesperrow]; // to store the bitmap
|
||||
const uchar* alpha = img->array + offset; // points to alpha value of rgba pixels
|
||||
for (i = 0; i < h; i++) {
|
||||
uchar *p = (uchar*)bits + i * bytesperrow;
|
||||
byte = 0;
|
||||
onebit = 1;
|
||||
for (j = 0; j < w; j++) {
|
||||
if (d == 3) {
|
||||
u = *alpha;
|
||||
u += *(alpha+1);
|
||||
u += *(alpha+2);
|
||||
}
|
||||
else u = *alpha;
|
||||
if (u > 0) { // if the pixel is not fully transparent/black
|
||||
byte |= onebit; // turn on the corresponding bit of the bitmap
|
||||
}
|
||||
onebit = onebit << 1; // move the single set bit one position to the left
|
||||
if (onebit == 0 || j == w-1) {
|
||||
onebit = 1;
|
||||
*p++ = byte; // store in bitmap one pack of bits
|
||||
byte = 0;
|
||||
}
|
||||
alpha += d; // point to alpha value of next pixel
|
||||
}
|
||||
}
|
||||
Fl_Bitmap* bitmap = new Fl_Bitmap(bits, w, h);
|
||||
bitmap->alloc_array = 1;
|
||||
shape_bitmap_(bitmap);
|
||||
todelete_ = bitmap;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void Fl_Shaped_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
|
||||
Fl_RGB_Image* rgba = new Fl_RGB_Image(pixmap);
|
||||
shape_alpha_(rgba, 3);
|
||||
delete rgba;
|
||||
}
|
||||
|
||||
/** Set the window's shape with an image.
|
||||
The \p img argument can be an Fl_Bitmap, Fl_Pixmap or Fl_RGB_Image.
|
||||
\li With Fl_Bitmap or Fl_Pixmap, the shaped window covers the image part where bitmap bits equal one,
|
||||
or where the pixmap is not fully transparent.
|
||||
\li With an Fl_RGB_Image with an alpha channel (depths 2 or 4), the shaped window covers the image part
|
||||
that is not fully transparent.
|
||||
\li With an Fl_RGB_Image of depth 1 (gray-scale) or 3 (RGB), the shaped window covers the non-black image part.
|
||||
|
||||
On some platforms, an 8-bit shape-mask is used when \p img is an Fl_RGB_Image:
|
||||
with depths 2 or 4, the image alpha channel becomes the shape mask such that areas with alpha = 0
|
||||
are out of the shaped window;
|
||||
with depths 1 or 3, white and black are in and out of the
|
||||
shaped window, respectively, and other colors give intermediate masking scores.
|
||||
*/
|
||||
void Fl_Shaped_Window::shape(const Fl_Image* img) {
|
||||
int d = img->d();
|
||||
if (d && img->count() >= 2) shape_pixmap_((Fl_Pixmap*)img);
|
||||
else if (d == 0) shape_bitmap_((Fl_Bitmap*)img);
|
||||
else if (d == 2 || d == 4) shape_alpha_((Fl_RGB_Image*)img, d - 1);
|
||||
else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_RGB_Image*)img, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id".
|
||||
//
|
||||
@ -2361,6 +2361,7 @@ void Fl_X::flush()
|
||||
fl_x_to_redraw = NULL;
|
||||
}
|
||||
|
||||
//bool Fl_X::make_shaped = false;
|
||||
|
||||
/*
|
||||
* go ahead, create that (sub)window
|
||||
@ -2517,6 +2518,10 @@ void Fl_X::make(Fl_Window* w)
|
||||
[cw setFrameOrigin:crect.origin];
|
||||
[cw setHasShadow:YES];
|
||||
[cw setAcceptsMouseMovedEvents:YES];
|
||||
if (w->type() == FL_SHAPED_WINDOW) {
|
||||
[cw setOpaque:NO]; // shaped windows must be non opaque
|
||||
[cw setBackgroundColor:[NSColor clearColor]]; // and with transparent background color
|
||||
}
|
||||
x->xid = cw;
|
||||
x->w = w; w->i = x;
|
||||
x->wait_for_expose = 1;
|
||||
@ -2645,7 +2650,7 @@ void Fl_Window::show() {
|
||||
labeltype(FL_NO_LABEL);
|
||||
}
|
||||
Fl_Tooltip::exit(this);
|
||||
if (!shown() || !i) {
|
||||
if (!shown()) {
|
||||
Fl_X::make(this);
|
||||
} else {
|
||||
if ( !parent() ) {
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
# include <FL/fl_draw.H>
|
||||
# include <FL/Fl_Paged_Device.H>
|
||||
# include <FL/Fl_Shared_Image.H>
|
||||
# include <FL/Fl_Shaped_Window.H>
|
||||
# include <FL/fl_ask.H>
|
||||
# include <FL/filename.H>
|
||||
# include <stdio.h>
|
||||
@ -2511,6 +2512,9 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (win->type() == FL_SHAPED_WINDOW) {
|
||||
((Fl_Shaped_Window*)win)->combine_mask();
|
||||
}
|
||||
XMapWindow(fl_display, xp->xid);
|
||||
if (showit) {
|
||||
win->set_visible();
|
||||
@ -2836,7 +2840,7 @@ void Fl_Window::show() {
|
||||
if (!shown()) {
|
||||
fl_open_display();
|
||||
// Don't set background pixel for double-buffered windows...
|
||||
if (type() == FL_WINDOW && can_boxcheat(box())) {
|
||||
if (type() != FL_DOUBLE_WINDOW && can_boxcheat(box())) {
|
||||
fl_background_pixel = int(fl_xpixel(color()));
|
||||
}
|
||||
Fl_X::make_xid(this);
|
||||
|
||||
@ -71,6 +71,7 @@ CPPFILES = \
|
||||
Fl_Round_Button.cxx \
|
||||
Fl_Scroll.cxx \
|
||||
Fl_Scrollbar.cxx \
|
||||
Fl_Shaped_Window.cxx \
|
||||
Fl_Shared_Image.cxx \
|
||||
Fl_Single_Window.cxx \
|
||||
Fl_Slider.cxx \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user