]> git.saurik.com Git - wxWidgets.git/commitdiff
Added alpha blending in prep for FreeType text to canvas.
authorRobert Roebling <robert@roebling.de>
Wed, 30 Aug 2000 13:05:24 +0000 (13:05 +0000)
committerRobert Roebling <robert@roebling.de>
Wed, 30 Aug 2000 13:05:24 +0000 (13:05 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8220 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

contrib/include/wx/canvas/canvas.h
contrib/samples/canvas/test/test.cpp
contrib/src/canvas/canvas.cpp

index b4a9b46dc88d0973d15a1a191c6e8d8c3a1b6e1f..b821ebef0c92b2e0ef1291cfe76d044cd6cf8b80 100644 (file)
@@ -91,6 +91,33 @@ private:
     wxWindow     *m_control;
 };
 
+//----------------------------------------------------------------------------
+// wxCanvasText
+//----------------------------------------------------------------------------
+
+class wxCanvasText: public wxCanvasObject
+{
+public:
+    wxCanvasText( const wxString &text, int x, int y );
+    ~wxCanvasText();
+    
+    virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
+    virtual void WriteSVG( wxTextOutputStream &stream );
+    
+    void CreateBuffer();
+    void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
+    void SetFlag( int flag );
+    
+private:
+    wxString        m_text;
+    unsigned char  *m_alpha;
+    void           *m_faceData;
+    int             m_flag;
+    int             m_red;
+    int             m_green;
+    int             m_blue;
+};
+
 //----------------------------------------------------------------------------
 // wxCanvas
 //----------------------------------------------------------------------------
index 1e17c1e748d548eeee31f5974ac193ea3ba37287..69c09ba7ae017e9e61c5fbe0cbc41c0d8c975ef2 100644 (file)
@@ -108,9 +108,11 @@ MyFrame::MyFrame()
   
   wxButton *button = new wxButton( m_canvas, -1, "Hello", wxPoint(130,50) );
   m_canvas->Append( new wxCanvasControl( button ) );
+
+  m_canvas->Append( new wxCanvasText( "Hello", 180, 50 ) );
   
   m_timer = new wxTimer( this );
-  m_timer->Start( 150, FALSE );
+  m_timer->Start( 100, FALSE );
 }
 
 MyFrame::~MyFrame()
index 3556034ad6ceda4f41d122d126cacd8f3c494f82..ada4ce48e454f64db4483554a8581b1e8ce988f0 100644 (file)
     #include "wx/gtk/win_gtk.h"
 #endif
 
-// WDR: class implementations
+#define USE_FREETYPE 0
+
+#if USE_FREETYPE
+#include <freetype/freetype.h>
+#endif
+
+//----------------------------------------------------------------------------
+// globals
+//----------------------------------------------------------------------------
+
+#if USE_FREETYPE
+FT_Library g_freetypeLibrary;
+#endif
 
 //----------------------------------------------------------------------------
 // wxCanvasObject
@@ -81,7 +93,27 @@ wxCanvasImage::wxCanvasImage( const wxImage &image, int x, int y )
 
 void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height )
 {
-    m_owner->GetBuffer()->Paste( m_image, m_area.x, m_area.y );
+    int start_x = wxMax( 0, clip_x-m_area.x );
+    int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x );
+    int start_y = wxMax( 0, clip_y-m_area.y );
+    int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y );
+    
+    if (end_x < start_x) return;
+    if (end_y < start_y) return;
+    
+    if ((start_x == 0) && 
+        (start_y == 0) && 
+        (end_x == m_area.width) &&
+        (end_y == m_area.height))
+    {
+        m_owner->GetBuffer()->Paste( m_image, m_area.x, m_area.y );
+    }
+    else
+    {
+        wxRect rect( start_x, start_y, end_x-start_x, end_y-start_y );
+        wxImage sub_image( m_image.GetSubImage( rect ) );
+        m_owner->GetBuffer()->Paste( sub_image, m_area.x+start_x, m_area.y+start_y );
+    }
 }
 
 void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
@@ -116,6 +148,147 @@ void wxCanvasControl::UpdateSize()
     m_control->GetPosition( &m_area.x, &m_area.y );
 }
 
+//----------------------------------------------------------------------------
+// wxCanvasText
+//----------------------------------------------------------------------------
+
+class wxFaceData
+{
+public:
+#if USE_FREETYPE
+     FT_Face   m_face;
+#else
+     void     *m_dummy;
+#endif    
+};
+
+wxCanvasText::wxCanvasText( const wxString &text, int x, int y )
+   : wxCanvasObject( x, y, -1, -1 )
+{
+    m_text = text;
+    m_alpha = NULL;
+    
+    m_red = 255;
+    m_green = 0;
+    m_blue = 0;
+    
+    // test
+    m_area.width = 128;
+    m_area.height = 128;
+    m_alpha = new unsigned char[128*128];
+    for (int y = 0; y < m_area.height; y++)
+        for (int x = 0; x < m_area.width; x++)
+            m_alpha[y*m_area.width + x] = x;
+    
+#if USE_FREETYPE    
+    CreateBuffer();
+    wxFaceData *data = new wxFaceData;
+    m_faceData = data;
+    
+    int error = FT_New_Face( g_freetypeLibrary,
+                             "~/TrueType/times.ttf",
+                             0,
+                             &(data->m_face) );
+                             
+    error = FT_Set_Char_Size( data->m_face,
+                              0,
+                              16*64,
+                              96,
+                              96 );
+#endif
+}
+
+wxCanvasText::~wxCanvasText()
+{
+#if USE_FREETYPE    
+    wxFaceData *data = (wxFaceData*) m_faceData;
+    delete data;
+#endif
+
+    if (m_alpha) delete [] m_alpha;
+}
+
+void wxCanvasText::SetRGB( unsigned char red, unsigned char green, unsigned char blue )
+{
+    m_red = red;
+    m_green = green;
+    m_blue = blue;
+}
+
+void wxCanvasText::SetFlag( int flag )
+{
+    m_flag = flag;
+}
+
+void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_height )
+{
+    if (!m_alpha) return;
+    
+    wxImage *image = m_owner->GetBuffer();
+
+    int start_x = wxMax( 0, clip_x-m_area.x );
+    int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x );
+    int start_y = wxMax( 0, clip_y-m_area.y );
+    int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y );
+    
+    for (int y = start_y; y < end_y; y++)
+        for (int x = start_x; x < end_x; x++)
+        {
+            int alpha = m_alpha[y*m_area.width + x];
+            if (alpha)
+            {
+                int image_x = m_area.x+x;
+                int image_y = m_area.y+y;
+                if (alpha == 128)
+                {
+                    image->SetRGB( image_x, image_y, m_red, m_green, m_blue );
+                    continue;
+                }
+                int red1 = (m_red * alpha) / 128;
+                int green1 = (m_green * alpha) / 128;
+                int blue1 = (m_blue * alpha) / 128;
+                
+                alpha = 128-alpha;
+                int red2 = image->GetRed( image_x, image_y );
+                int green2 = image->GetGreen( image_x, image_y );
+                int blue2 = image->GetBlue( image_x, image_y );
+                red2 = (red2 * alpha) / 128;
+                green2 = (green2 * alpha) / 128;
+                blue2 = (blue2 * alpha) / 128;
+                
+                image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
+            }
+        }
+}
+
+void wxCanvasText::WriteSVG( wxTextOutputStream &stream )
+{
+}
+
+void wxCanvasText::CreateBuffer()
+{
+#if USE_FREETYPE    
+    FT_Face face = ((wxFaceData*)m_faceData)->m_face;
+    FT_GlyphSlot slot = face->glyph;
+    int pen_x = 0;
+    int pen_y = 0;
+    
+    for (int n = 0; n < m_text.Len(); n++)
+    {
+        FT_UInt index = FT_Get_Char_Index( face, m_text[n] );
+        
+        int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
+        if (error) continue;
+        
+        error = FT_Render_Glyph( face->glyph, ft_render_antialias );
+        if (error) continue;
+        
+        pen_x += slot->advance.x >> 6;
+        pen_y += slot->advance.y >> 6;
+    }    
+#endif
+}
+
 //----------------------------------------------------------------------------
 // wxCanvas
 //----------------------------------------------------------------------------
@@ -165,7 +338,7 @@ void wxCanvas::Update( int x, int y, int width, int height )
     m_updateRects.Append(
         (wxObject*) new wxRect( x,y,width,height ) );
     
-    // speed up with direct access
+    // speed up with direct access, maybe add wxImage::Clear(x,y,w,h)
     int xx,yy,ww,hh;
     for (yy = y; yy < y+height; yy++)
         for (xx = x; xx < x+width; xx++)
@@ -180,7 +353,7 @@ void wxCanvas::Update( int x, int y, int width, int height )
         ww = obj->GetWidth();
         hh = obj->GetHeight();
             
-        if (!obj->IsControl())
+        if (!obj->IsControl())  // calc intersection !
         {
             obj->Render( x, y, width, height );
         }
@@ -356,4 +529,35 @@ void wxCanvas::OnChar(wxKeyEvent &event)
     event.Skip();
 }
 
+//--------------------------------------------------------------------
+// wxCanvasModule
+//--------------------------------------------------------------------
+
+class wxCanvasModule : public wxModule
+{
+public:
+    virtual bool OnInit();
+    virtual void OnExit();
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxCanvasModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule, wxModule)
 
+bool wxCanvasModule::OnInit()
+{
+#if USE_FREETYPE
+    int error = FT_Init_FreeType( &g_freetypeLibrary );
+    if (error) return FALSE;
+#endif
+
+    return TRUE;
+}
+
+void wxCanvasModule::OnExit()
+{
+#if USE_FREETYPE
+   // Close FreeType
+#endif
+}