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_agg.cpp


From: Udo Giacomozzi
Subject: [Gnash-commit] gnash ChangeLog backend/render_handler_agg.cpp
Date: Tue, 08 May 2007 17:05:54 +0000

CVSROOT:        /cvsroot/gnash
Module name:    gnash
Changes by:     Udo Giacomozzi <udog>   07/05/08 17:05:53

Modified files:
        .              : ChangeLog 
        backend        : render_handler_agg.cpp 

Log message:
        backend/render_handler_agg.cpp: Fix vector alignment ("pixel hinting"). 
Fixes bug #19775.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3125&r2=1.3126
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/render_handler_agg.cpp?cvsroot=gnash&r1=1.77&r2=1.78

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/gnash/gnash/ChangeLog,v
retrieving revision 1.3125
retrieving revision 1.3126
diff -u -b -r1.3125 -r1.3126
--- ChangeLog   8 May 2007 09:39:25 -0000       1.3125
+++ ChangeLog   8 May 2007 17:05:53 -0000       1.3126
@@ -1,3 +1,8 @@
+2007-05-08 Udo Giacomozzi <address@hidden>
+
+       * backend/render_handler_agg.cpp: Fix vector alignment ("pixel
+         hinting"). Fixes bug #19775. 
+
 2007-05-07 Sandro Santilli <address@hidden>
 
        * libbase/LoadThread.h: threading enabled by default.

Index: backend/render_handler_agg.cpp
===================================================================
RCS file: /cvsroot/gnash/gnash/backend/render_handler_agg.cpp,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -b -r1.77 -r1.78
--- backend/render_handler_agg.cpp      3 May 2007 10:07:44 -0000       1.77
+++ backend/render_handler_agg.cpp      8 May 2007 17:05:53 -0000       1.78
@@ -16,7 +16,7 @@
 
  
 
-/* $Id: render_handler_agg.cpp,v 1.77 2007/05/03 10:07:44 udog Exp $ */
+/* $Id: render_handler_agg.cpp,v 1.78 2007/05/08 17:05:53 udog Exp $ */
 
 // Original version by Udo Giacomozzi and Hannes Mayr, 
 // INDUNET GmbH (www.indunet.it)
@@ -176,7 +176,7 @@
 #endif
 
 #ifndef round
-#define round rint
+#define round(x) rint(x+0.5f)
 #endif
 
 using namespace gnash;
@@ -963,18 +963,12 @@
 
     std::vector< path > paths;
     std::vector< agg::path_storage > agg_paths;
-    std::vector< agg::path_storage > agg_paths_rounded;
     apply_matrix_to_path(def->get_paths(), paths, mat);
-    if (have_shape)
+    if (have_outline)
+      build_agg_paths_rounded(agg_paths, paths);
+    else
       build_agg_paths(agg_paths, paths);
       
-    // <Udo>: not sure if the anchor points of the *shape* edges should be
-    // rounded too...
-    
-    if (have_outline) {
-      agg_paths_rounded.reserve(agg_paths.size());
-      build_agg_paths_rounded(agg_paths_rounded, paths);
-    }
     
     if (m_drawing_mask) {
       
@@ -1009,7 +1003,7 @@
         if (have_shape)
           draw_shape(subshape, paths, agg_paths, sh, true);    
         if (have_outline)      
-          draw_outlines(subshape, paths, agg_paths_rounded, line_styles, cx, 
mat);
+          draw_outlines(subshape, paths, agg_paths, line_styles, cx, mat);
       }
       
     } // if not drawing mask
@@ -1165,15 +1159,11 @@
   // lines and looking blurry). The proprietary player does this too.  
   // Remember the middle of a pixel is at .5 / .5 (at it's subpixel center).
   //
-  // TODO:
-  // For "correct" results alignment should be done only in these cases:
-  //   - the line is straight and pure horizontal or vertical
-  //   - the line width on screen is 1.0
-  // However this leads to awful rounded rectangles, but the MM player 
-  // does it that way... :(
-  // BTW, most probably this is for speed reasons (those lines are most
-  // probably implemented without anti-aliasing calculations, like a 
-  // Bresenham line). 
+  // Not all points are aligned, only those lines that:
+  //   - are straight
+  //   - are pure horizontal or vertical
+  // Also, single segments of a path may be aligned or not depending on 
+  // the segment properties (this matches MM player behaviour)  
   void build_agg_paths_rounded(std::vector<agg::path_storage>& dest, 
     const std::vector<path>& paths) {
   
@@ -1187,8 +1177,10 @@
       const gnash::path& this_path = paths[pno];
       agg::path_storage& new_path = dest[pno];
       
-      new_path.move_to(round(this_path.m_ax*xscale)+0.5f, 
-        round(this_path.m_ay*yscale)+0.5f);
+      float prev_ax = this_path.m_ax*xscale;
+      float prev_ay = this_path.m_ay*yscale;  
+      bool prev_align_x = true;
+      bool prev_align_y = true;
       
       int ecount = this_path.m_edges.size();
       
@@ -1196,18 +1188,88 @@
         
         const edge& this_edge = this_path.m_edges[eno];
         
-        if (this_edge.is_straight())
-          new_path.line_to(round(this_edge.m_ax*xscale)+0.5f, 
-            round(this_edge.m_ay*yscale)+0.5f);
-        else
-          new_path.curve3(round(this_edge.m_cx*xscale)+0.5f, 
-            round(this_edge.m_cy*yscale)+0.5f,
-            round(this_edge.m_ax*xscale)+0.5f, 
-            round(this_edge.m_ay*yscale)+0.5f);
+        float this_ax = this_edge.m_ax*xscale;  
+        float this_ay = this_edge.m_ay*yscale;  
+        
+        if (this_edge.is_straight()) {
+        
+          // candidate for alignment?
+          bool align_x = prev_ax == this_ax;
+          bool align_y = prev_ay == this_ay;
+          
+          if (align_x) 
+            this_ax = round(this_ax) - 0.5f;
+          
+          if (align_y)
+            this_ay = round(this_ay) - 0.5f;
+          
+          // first line?
+          if (eno==0) {
+          
+            if (align_x) 
+              prev_ax = round(prev_ax) - 0.5f;
+              
+            if (align_y)
+              prev_ay = round(prev_ay) - 0.5f;
+              
+            new_path.move_to(prev_ax, prev_ay);
+            
+          } else {
+          
+            // not the first line, but the previous anchor point
+            // might belong to a curve and thus may not be aligned.
+            // We need to have both anchors of this new line to be
+            // aligned, so it may be neccesary to add a line
+            if ((align_x && !prev_align_x) || (align_y && !prev_align_y)) {
         
+              if (align_x) 
+                prev_ax = round(prev_ax) - 0.5f;
+                
+              if (align_y)
+                prev_ay = round(prev_ay) - 0.5f;
+                
+              new_path.line_to(prev_ax, prev_ay);
+              
+            }
+            
+            // TODO: (minor flaw) Flash player never aligns anchor points
+            // of curves, even if they are attached to straight vertical
+            // or horizontal lines. It can be seen easily with rounded
+            // rectangles, where the curves are never aligned and all 
+            // straight lines are. AGG backend will align the curve anchor
+            // point that follows the straight line. It's not a big problem
+            // but it's not exact...
         
       }
     
+          new_path.line_to(this_ax, this_ay);
+          
+          prev_align_x = align_x;
+          prev_align_y = align_y;  
+          
+          
+        } else {
+          
+          // first line?
+          if (eno==0) 
+            new_path.move_to(prev_ax, prev_ay);
+        
+          // never align curves!
+          new_path.curve3(this_edge.m_cx*xscale, 
+            this_edge.m_cy*yscale,
+            this_ax, 
+            this_ay);
+            
+          prev_align_x = false;
+          prev_align_y = false;  
+            
+        }
+        
+        prev_ax = this_ax;
+        prev_ay = this_ay;    
+        
+      } //for
+    
     }
         
   } //build_agg_paths_rounded




reply via email to

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