gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog backend/render_handler_ogl.cpp


From: Bastiaan Jacques
Subject: [Gnash-commit] gnash ChangeLog backend/render_handler_ogl.cpp
Date: Fri, 23 Nov 2007 22:55:17 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Bastiaan Jacques <bjacques>     07/11/23 22:55:17

Modified files:
        .              : ChangeLog 
        backend        : render_handler_ogl.cpp 

Log message:
        Implement nested masks. Also take advantage of changes to type 'point' 
in trace_curve.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4946&r2=1.4947
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/render_handler_ogl.cpp?cvsroot=gnash&r1=1.89&r2=1.90

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4946
retrieving revision 1.4947
diff -u -b -r1.4946 -r1.4947
--- ChangeLog   23 Nov 2007 22:23:24 -0000      1.4946
+++ ChangeLog   23 Nov 2007 22:55:16 -0000      1.4947
@@ -1,3 +1,8 @@
+2007-11-23 Bastiaan Jacques <address@hidden>
+
+       * backend/render_handler_ogl.cpp: Implement nested masks. Also take
+       advantage of changes to type 'point' in trace_curve.
+
 2007-11-23 Sandro Santilli <address@hidden>
 
        * server/: Makefile.am, impl.cpp, parser/sound_definition.{cpp,h}

Index: backend/render_handler_ogl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/render_handler_ogl.cpp,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- backend/render_handler_ogl.cpp      10 Nov 2007 14:39:52 -0000      1.89
+++ backend/render_handler_ogl.cpp      23 Nov 2007 22:55:17 -0000      1.90
@@ -42,6 +42,7 @@
 #include "render_handler_ogl.h"
 
 #include <boost/utility.hpp>
+#include <boost/bind.hpp>
 
 /// \file render_handler_ogl.cpp
 /// \brief The OpenGL renderer and related code.
@@ -83,9 +84,10 @@
 
 // TODO:
 // - Implement:
-// * Nested masks
 // * Alpha images
-// * Real antialiasing
+// * Real antialiasing: Currently, we just draw an anti-aliased outline around
+//   solid shapes and fonts. Besides not anti-aliasing other types of shapes,
+//   this makes fonts a bit bigger than intended.
 // 
 // - Profiling!
 // - Optimize code:
@@ -233,9 +235,7 @@
   // Midpoint on the curve.
   point q = middle(mid, controlP);
 
-  float dist = std::abs(mid.x - q.x) + std::abs(mid.y - q.y);
-
-  if (dist < 0.1 /*error tolerance*/) {
+  if (mid.distance(q) < 0.1 /*error tolerance*/) {
     coords.push_back(oglVertex(endP));
   } else {
     // Error is too large; subdivide.
@@ -534,7 +534,8 @@
 public: 
   render_handler_ogl()
     : _xscale(1.0),
-      _yscale(1.0)
+      _yscale(1.0),
+      _drawing_mask(false)
   {
   }
   
@@ -818,28 +819,79 @@
     
   virtual void begin_submit_mask()
   {
+    PathVec mask;
+    _masks.push_back(mask);
+    
+    _drawing_mask = true;
+  }
+  
+  virtual void end_submit_mask()
+  {
+    _drawing_mask = false;
+    
+    apply_mask();
+  }
+
+  /// Apply the current mask; nesting is supported.
+  ///
+  /// This method marks the stencil buffer by incrementing every stencil pixel
+  /// by one every time a solid from one of the current masks is drawn. When
+  /// all the mask solids are drawn, we change the stencil operation to permit
+  /// only drawing where all masks have drawn, in other words, where all masks
+  /// intersect, or in even other words, where the stencil pixel buffer equals
+  /// the number of masks.
+  void apply_mask()
+  {
+    if (_masks.empty()) {
+      return;
+    }
+    
     glEnable(GL_STENCIL_TEST); 
+
     glClearStencil(0x0); // FIXME: default is zero, methinks
     glClear(GL_STENCIL_BUFFER_BIT);
     
-    // Since we are marking the stencil, the stencil function test should
-    // always succeed.
+    // GL_NEVER means the stencil test will never succeed, so OpenGL wil never
+    // continue to the drawing stage.
     glStencilFunc (GL_NEVER, 0x1, 0x1);    
     
-    glStencilOp (GL_REPLACE /* Stencil test fails */ ,
-                 GL_ZERO /* Value is ignored */ ,
-                 GL_REPLACE /* Stencil test passes */);     
+    glStencilOp (GL_INCR /* Stencil test fails */,
+                 GL_KEEP /* ignored */,
+                 GL_KEEP /* Stencil test passes; never happens */);
+
+    // Call add_paths for each mask.
+    std::for_each(_masks.begin(), _masks.end(),
+      boost::bind(&render_handler_ogl::add_paths, boost::ref(this), _1));    
+          
+    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+    glStencilFunc(GL_EQUAL, _masks.size(), _masks.size());
   }
   
-  virtual void end_submit_mask()
+  void
+  add_paths(const PathVec& path_vec)
   {        
-    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
-    glStencilFunc(GL_EQUAL, 0x1, 0x1);
+    cxform dummy_cx;
+    std::vector<fill_style> dummy_fs;
+    
+    fill_style coloring;
+    coloring.setSolid(rgba(0,0,0,0));
+    
+    dummy_fs.push_back(coloring);
+    
+    std::vector<line_style> dummy_ls;
+    
+    draw_subshape(path_vec, matrix::identity, dummy_cx, 1.0, dummy_fs, 
dummy_ls);
   }
   
   virtual void disable_mask()
   {  
+    _masks.pop_back();
+    
+    if (_masks.empty()) {
     glDisable(GL_STENCIL_TEST);
+    } else {
+      apply_mask();
+    }
   }
 
 #if 0
@@ -1241,7 +1293,17 @@
   }
 
   
+  void draw_mask(const PathVec& path_vec)
+  {    
+    for (PathVec::const_iterator it = path_vec.begin(), end = path_vec.end();
+         it != end; ++it) {
+      const path& cur_path = *it;
   
+      if (cur_path.m_fill0 || cur_path.m_fill1) {
+        _masks.back().push_back(cur_path);     
+      }
+    }  
+  }
   
   PathPtrVec
   get_paths_by_style(const PathVec& path_vec, unsigned int style)
@@ -1290,6 +1352,51 @@
     return subshapes;
   }
   
+  /// Takes a path and translates it using the given matrix. The new path
+  /// is stored in paths_out.
+  /// Taken from render_handler_agg.cpp.  
+  void apply_matrix_to_paths(const std::vector<path> &paths_in, 
+    std::vector<path> &paths_out, const matrix& mat) {
+    
+    int pcount, ecount;
+    int pno, eno;
+    
+    // copy path
+    paths_out = paths_in;    
+    pcount = paths_out.size();        
+    
+    for (pno=0; pno<pcount; pno++) {
+    
+      path &the_path = paths_out[pno];     
+      point oldpnt(the_path.ap.x, the_path.ap.y);
+      point newpnt;
+      mat.transform(&newpnt, oldpnt);
+      the_path.ap.x = newpnt.x;    
+      the_path.ap.y = newpnt.y;
+      
+      ecount = the_path.m_edges.size();
+      for (eno=0; eno<ecount; eno++) {
+      
+        edge &the_edge = the_path.m_edges[eno];
+        
+        oldpnt.x = the_edge.ap.x;
+        oldpnt.y = the_edge.ap.y;
+        mat.transform(&newpnt, oldpnt);
+        the_edge.ap.x = newpnt.x;
+        the_edge.ap.y = newpnt.y;
+        
+        oldpnt.x = the_edge.cp.x;
+        oldpnt.y = the_edge.cp.y;
+        mat.transform(&newpnt, oldpnt);
+        the_edge.cp.x = newpnt.x;
+        the_edge.cp.y = newpnt.y;
+      
+      }          
+      
+    } 
+    
+  }
+  
   
   void
   draw_subshape(const PathVec& path_vec,
@@ -1391,6 +1498,14 @@
       return;
     }
     
+    if (_drawing_mask) {
+      PathVec scaled_path_vec;
+      
+      apply_matrix_to_paths(path_vec, scaled_path_vec, mat);
+      draw_mask(scaled_path_vec); 
+      return;
+    }    
+    
     bool have_shape, have_outline;
     
     analyze_paths(path_vec, have_shape, have_outline);
@@ -1423,6 +1538,7 @@
   virtual void draw_glyph(shape_character_def *def, const matrix& mat,
     const rgba& c, float pixel_scale)
   {
+    if (_drawing_mask) abort();
     cxform dummy_cx;
     std::vector<fill_style> glyph_fs;
     
@@ -1484,6 +1600,10 @@
   Tesselator _tesselator;
   float _xscale;
   float _yscale;
+  
+  std::vector<PathVec> _masks;
+  bool _drawing_mask;
+  
 #ifdef OSMESA_TESTING
   std::auto_ptr<OSRenderMesa> _offscreen;
 #endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]