gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/Makefile.am server/style...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/Makefile.am server/style...
Date: Tue, 13 Feb 2007 15:19:33 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/02/13 15:19:32

Modified files:
        .              : ChangeLog 
        server         : Makefile.am styles.cpp styles.h 
Added files:
        server         : fill_style.cpp fill_style.h 

Log message:
                * server/: Makefile.am, fill_style.{cpp,h},
                  styles.{cpp,h}: moved fill_style class in its
                  own file. Removeod unused code, provided
                  a fill_style constructor for creating clipped
                  bitmap fills.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2344&r2=1.2345
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.102&r2=1.103
http://cvs.savannah.gnu.org/viewcvs/gnash/server/styles.cpp?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/server/styles.h?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/server/fill_style.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/fill_style.h?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2344
retrieving revision 1.2345
diff -u -b -r1.2344 -r1.2345
--- ChangeLog   13 Feb 2007 14:24:25 -0000      1.2344
+++ ChangeLog   13 Feb 2007 15:19:32 -0000      1.2345
@@ -1,5 +1,10 @@
 2007-02-13 Sandro Santilli <address@hidden>
 
+       * server/: Makefile.am, fill_style.{cpp,h},
+         styles.{cpp,h}: moved fill_style class in its
+         own file. Removeod unused code, provided 
+         a fill_style constructor for creating clipped
+         bitmap fills.
        * server/render.h: had doxygen comments point
          to the correct place (render_handler).
 

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -b -r1.102 -r1.103
--- server/Makefile.am  13 Feb 2007 13:35:34 -0000      1.102
+++ server/Makefile.am  13 Feb 2007 15:19:32 -0000      1.103
@@ -18,7 +18,7 @@
 # 
 #
 
-# $Id: Makefile.am,v 1.102 2007/02/13 13:35:34 strk Exp $
+# $Id: Makefile.am,v 1.103 2007/02/13 15:19:32 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -73,6 +73,7 @@
        array.cpp \
        button_character_instance.cpp \
        dlist.cpp \
+       fill_style.cpp \
        font.cpp \
        fontlib.cpp \
        impl.cpp \
@@ -113,6 +114,7 @@
        edit_text_character.h \
        event_id.h \
        execute_tag.h \
+       fill_style.h \
        font.h \
        fontlib.h \
        generic_character.h \

Index: server/styles.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/styles.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- server/styles.cpp   7 Feb 2007 08:43:33 -0000       1.30
+++ server/styles.cpp   13 Feb 2007 15:19:32 -0000      1.31
@@ -17,418 +17,6 @@
 
 namespace gnash {
 
-//
-// gradient_record
-//
-
-gradient_record::gradient_record()
-    :
-    m_ratio(0)
-{
-}
-
-
-void
-gradient_record::read(stream* in, int tag_type)
-{
-    m_ratio = in->read_u8();
-    m_color.read(in, tag_type);
-}
-
-
-//
-// fill_style
-//
-
-
-fill_style::fill_style()
-    :
-    m_type(0),
-    m_gradient_bitmap_info(0),
-    m_bitmap_character(0)
-{
-    assert(m_gradients.size() == 0);
-}
-
-
-fill_style::~fill_style()
-{
-}
-
-void
-fill_style::read(stream* in, int tag_type, movie_definition* md)
-{
-    m_type = in->read_u8();
-
-               IF_VERBOSE_PARSE
-               (
-    log_parse("  fill_style read type = 0x%X", m_type);
-               );
-
-    if (m_type == SWF::FILL_SOLID)
-    {
-        // 0x00: solid fill
-        if ( tag_type == SWF::DEFINESHAPE3 )
-        {
-            m_color.read_rgba(in);
-        }
-        else 
-        {
-            // For DefineMorphShape tags we should use morph_fill_style 
-            assert( tag_type == SWF::DEFINESHAPE
-               || tag_type == SWF::DEFINESHAPE2 );
-            m_color.read_rgb(in);
-        }
-
-               IF_VERBOSE_PARSE
-               (
-        log_parse("  color: %s", m_color.toString().c_str());
-               );
-    }
-    else if (m_type == SWF::FILL_LINEAR_GRADIENT
-            || m_type == SWF::FILL_RADIAL_GRADIENT)
-    {
-        // 0x10: linear gradient fill
-        // 0x12: radial gradient fill
-
-        matrix input_matrix;
-        input_matrix.read(in);
-
-        // shouldn't this be in initializer's list ?
-        m_gradient_matrix.set_identity();
-        if (m_type == SWF::FILL_LINEAR_GRADIENT)
-        {
-            m_gradient_matrix.concatenate_translation(128.f, 0.f);
-            m_gradient_matrix.concatenate_scale(1.0f / 128.0f);
-        }
-        else
-        {
-            m_gradient_matrix.concatenate_translation(32.f, 32.f);
-            m_gradient_matrix.concatenate_scale(1.0f / 512.0f);
-        }
-
-        matrix m;
-        m.set_inverse(input_matrix);
-        m_gradient_matrix.concatenate(m);
-                               
-        // GRADIENT
-        uint8_t num_gradients = in->read_u8();
-        if ( ! num_gradients )
-       {
-               IF_VERBOSE_MALFORMED_SWF(
-                       log_swferror("num gradients 0");
-               );
-               return;
-       }
-
-        if ( num_gradients > 8 ) // SWF::DEFINESHAPE4 should support up to 15 !
-                                // and we don't have this limitation anyway
-        {
-            // see: http://sswf.sourceforge.net/SWFalexref.html#swf_gradient
-            log_warning("Unexpected num gradients (%d), expected 1 to 8",
-                    num_gradients);
-        }                      
-
-        m_gradients.resize(num_gradients);
-        for (int i = 0; i < num_gradients; i++)        {
-            m_gradients[i].read(in, tag_type);
-        }
-
-               IF_VERBOSE_PARSE
-               (
-        log_parse("  gradients: num_gradients = %d", num_gradients);
-               );
-
-        // @@ hack.
-        if (num_gradients > 0) {
-            m_color = m_gradients[0].m_color;
-        }
-
-        if (md->get_create_bitmaps() == DO_LOAD_BITMAPS) {
-            m_gradient_bitmap_info = create_gradient_bitmap();
-        // Make sure our movie_def_impl knows about this bitmap.
-        md->add_bitmap_info(m_gradient_bitmap_info.get());
-        }
-    }
-    else if (m_type == SWF::FILL_TILED_BITMAP
-          || m_type == SWF::FILL_CLIPPED_BITMAP
-          || m_type == SWF::FILL_TILED_BITMAP_HARD
-          || m_type == SWF::FILL_CLIPPED_BITMAP_HARD)
-    {
-        // 0x40: tiled bitmap fill
-        // 0x41: clipped bitmap fill
-        // 0x42: tiled bitmap fill with hard edges
-        // 0x43: clipped bitmap fill with hard edges
-
-        int    bitmap_char_id = in->read_u16();
-       IF_VERBOSE_PARSE
-       (
-               log_parse("  bitmap_char = %d", bitmap_char_id);
-       );
-
-        // Look up the bitmap character.
-        m_bitmap_character = md->get_bitmap_character_def(bitmap_char_id);
-       IF_VERBOSE_MALFORMED_SWF(
-       if ( m_bitmap_character == NULL )
-       {
-               static bool warned_about_invalid_char=false;
-               if ( ! warned_about_invalid_char )
-               {
-                       log_swferror("Bitmap fill specifies '%d' as associated"
-                               " bitmap character id,"
-                               " but that character is not found"
-                               " in the Characters Dictionary."
-                               " It seems common to find such "
-                               " malformed SWF, so we'll only warn once "
-                               "about this.",
-                               bitmap_char_id);
-                       warned_about_invalid_char=true;
-               }
-       }
-       );
-
-        matrix m;
-        m.read(in);
-
-        // For some reason, it looks like they store the inverse of the
-        // TWIPS-to-texcoords matrix.
-        m_bitmap_matrix.set_inverse(m);
-
-        IF_VERBOSE_PARSE(
-            m_bitmap_matrix.print();
-        );
-    }
-    else
-    {
-        log_error("Unsupported fill style type: 0x%X", m_type);
-        // This is a fatal error, we'll be leaving the stream
-        // read pointer in an unknown position.
-        throw ParserException("Unsupported fill style (Malformed SWF?)");
-    }
-}
-
-
-bitmap_info* 
-fill_style::get_bitmap_info() const 
-{    
-  assert(m_type != SWF::FILL_SOLID);
-  
-  if (m_type == SWF::FILL_TILED_BITMAP
-   || m_type == SWF::FILL_CLIPPED_BITMAP
-   || m_type == SWF::FILL_TILED_BITMAP_HARD
-   || m_type == SWF::FILL_CLIPPED_BITMAP_HARD) {
-
-   if (m_bitmap_character!=NULL)
-     return m_bitmap_character->get_bitmap_info();
-   else
-     return NULL;
-   
-  } else
-  if (m_type == SWF::FILL_LINEAR_GRADIENT
-   || m_type == SWF::FILL_RADIAL_GRADIENT) {
-   
-   return need_gradient_bitmap();
-   
-  } else {
-    log_msg("Unknown fill style");
-    assert(0);
-  }  
-}
-
-matrix
-fill_style::get_bitmap_matrix() const 
-{
-  assert(m_type != SWF::FILL_SOLID);
-  return m_bitmap_matrix;
-}
-
-matrix
-fill_style::get_gradient_matrix() const 
-{
-  // TODO: Why do we separate bitmap and gradient matrices? 
-  return m_gradient_matrix;
-}
-
-rgba
-fill_style::sample_gradient(uint8_t ratio) const
-{
-       assert(m_type == SWF::FILL_LINEAR_GRADIENT
-               || m_type == SWF::FILL_RADIAL_GRADIENT);
-
-       assert(m_gradients.size());
-
-       // By specs, first gradient should *always* be 0, 
-       // anyway a malformed SWF could break this,
-       // so we cannot rely on that information...
-       if (ratio < m_gradients[0].m_ratio)
-       {
-               IF_VERBOSE_MALFORMED_SWF(
-                       static bool warned=false;
-                       if ( ! warned ) {
-                       log_swferror(
-                               "First gradient in a fill_style "
-                               "have position==%d (expected 0)."
-                               " This seems to be common, so will"
-                               " warn only once."
-                               ,
-                               m_gradients[0].m_ratio);
-                       warned=true;
-                       }
-               );
-               return m_gradients[0].m_color;
-       }
-
-       if ( ratio >= m_gradients.back().m_ratio )
-       {
-               return m_gradients.back().m_color;
-       }
-               
-       for (size_t i = 1, n = m_gradients.size(); i < n; ++i)
-       {
-               const gradient_record& gr1 = m_gradients[i];
-               if (gr1.m_ratio < ratio) continue;
-
-               const gradient_record& gr0 = m_gradients[i - 1];
-               if (gr0.m_ratio > ratio) continue;
-
-               float f = 0.0f;
-
-               if ( gr0.m_ratio != gr1.m_ratio )
-               {
-                       f = (ratio - gr0.m_ratio) / float(gr1.m_ratio - 
gr0.m_ratio);
-               }
-               else
-               {
-                       // Ratios are equal IFF first and second gradient_record
-                       // have the same ratio. This would be a malformed SWF.
-                       IF_VERBOSE_MALFORMED_SWF(
-                               log_swferror(
-                                       "two gradients in a fill_style "
-                                       "have the same position/ratio: %d",
-                                       gr0.m_ratio);
-                       );
-               }
-
-               rgba    result;
-               result.set_lerp(gr0.m_color, gr1.m_color, f);
-               return result;
-       }
-
-       // Assuming gradients are ordered by m_ratio? see start comment
-       return m_gradients.back().m_color;
-}
-
-gnash::bitmap_info*
-fill_style::create_gradient_bitmap() const
-{
-    assert(m_type == SWF::FILL_LINEAR_GRADIENT
-        || m_type == SWF::FILL_RADIAL_GRADIENT);
-
-    image::rgba*       im = NULL;
-
-    if (m_type == SWF::FILL_LINEAR_GRADIENT)
-    {
-        // Linear gradient.
-        im = image::create_rgba(256, 1);
-
-        for (int i = 0; i < im->m_width; i++) {
-            rgba       sample = sample_gradient(i);
-            im->set_pixel(i, 0, sample.m_r, sample.m_g, sample.m_b, 
sample.m_a);
-        }
-    }
-    else if (m_type == SWF::FILL_RADIAL_GRADIENT)
-    {
-        // Radial gradient.
-        im = image::create_rgba(64, 64);
-
-        for (int j = 0; j < im->m_height; j++) {
-            for (int i = 0; i < im->m_width; i++) {
-                float  radius = (im->m_height - 1) / 2.0f;
-                float  y = (j - radius) / radius;
-                float  x = (i - radius) / radius;
-                int    ratio = (int) floorf(255.5f * sqrt(x * x + y * y));
-                if (ratio > 255) {
-                    ratio = 255;
-                }
-                rgba   sample = sample_gradient( ratio );
-                im->set_pixel(i, j, sample.m_r, sample.m_g, sample.m_b, 
sample.m_a);
-            }
-        }
-    }
-    gnash::bitmap_info*        bi = gnash::render::create_bitmap_info_rgba(im);
-    delete im;
-
-    return bi;
-}
-
-
-gnash::bitmap_info*
-fill_style::need_gradient_bitmap() const 
-{
-
-  if (m_gradient_bitmap_info==NULL) {
-    fill_style*        this_non_const = const_cast<fill_style*>(this);
-    this_non_const->m_gradient_bitmap_info = create_gradient_bitmap();
-  }
-  
-  return m_gradient_bitmap_info.get();
-
-}
-
-
-void
-fill_style::set_lerp(const fill_style& a, const fill_style& b, float t)
-    // Sets this style to a blend of a and b.  t = [0,1]
-{
-    assert(t >= 0 && t <= 1);
-
-    // fill style type
-    m_type = a.get_type();
-    assert(m_type == b.get_type());
-
-    // fill style color
-    m_color.set_lerp(a.get_color(), b.get_color(), t);
-
-    // fill style gradient matrix
-    //
-    // @@ TODO morphed gradients don't come out exactly
-    // right; they shift around some.  Not sure where the
-    // problem is.
-    m_gradient_matrix.set_lerp(a.m_gradient_matrix, b.m_gradient_matrix, t);
-
-    // fill style gradients
-    assert(m_gradients.size() == a.m_gradients.size());
-    assert(m_gradients.size() == b.m_gradients.size());
-    for (size_t j=0, nj=m_gradients.size(); j<nj; ++j)
-    {
-        m_gradients[j].m_ratio =
-            (uint8_t) frnd(
-                flerp(a.m_gradients[j].m_ratio, b.m_gradients[j].m_ratio, t)
-                );
-        m_gradients[j].m_color.set_lerp(a.m_gradients[j].m_color, 
b.m_gradients[j].m_color, t);
-    }
-    m_gradient_bitmap_info = NULL;
-
-    // fill style bitmap ID
-    m_bitmap_character = a.m_bitmap_character;
-    assert(m_bitmap_character == b.m_bitmap_character);
-
-    // fill style bitmap matrix
-    m_bitmap_matrix.set_lerp(a.m_bitmap_matrix, b.m_bitmap_matrix, t);
-}
-
-
-int 
-fill_style::get_color_stop_count() const 
-{
-  return m_gradients.size();
-}
-
-const gradient_record& 
-fill_style::get_color_stop(int index) const
-{
-  return m_gradients[index];
-}
 
 //
 // line_style

Index: server/styles.h
===================================================================
RCS file: /sources/gnash/gnash/server/styles.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- server/styles.h     4 Jan 2007 04:03:33 -0000       1.17
+++ server/styles.h     13 Feb 2007 15:19:32 -0000      1.18
@@ -3,9 +3,9 @@
 // This source code has been donated to the Public Domain.  Do
 // whatever you want with it.
 
-// Fill and line style types.
+// line style types.
 
-/* $Id: styles.h,v 1.17 2007/01/04 04:03:33 strk Exp $ */
+/* $Id: styles.h,v 1.18 2007/02/13 15:19:32 strk Exp $ */
 
 #ifndef GNASH_STYLES_H
 #define GNASH_STYLES_H
@@ -13,134 +13,12 @@
 #include "impl.h"
 #include "types.h"
 #include "bitmap_character_def.h"
+#include "fill_style.h"
 
 namespace gnash {
 
 class stream;
 
-class gradient_record
-{
-public:
-       gradient_record();
-       void    read(stream* in, int tag_type);
-       
-       //data:
-       uint8_t m_ratio;
-       rgba    m_color;
-};
-
-class DSOLOCAL base_fill_style
-{
-public:
-       virtual ~base_fill_style() {};
-};
-
-/// For the interior of outline shapes.
-class DSOEXPORT fill_style : public base_fill_style
-{
-public:
-
-       fill_style();
-
-       virtual ~fill_style();
-       
-       void    read(stream* in, int tag_type, movie_definition* m);
-
-
-    /// \brief
-    /// Make a bitmap_info* corresponding to our gradient.
-    /// We can use this to set the gradient fill style.
-       gnash::bitmap_info*     create_gradient_bitmap() const;
-       
-       /// \brief
-       /// Makes sure that m_gradient_bitmap_info is not NULL. Calls 
-  /// create_gradient_bitmap() if necessary and returns m_gradient_bitmap_info.
-       gnash::bitmap_info* need_gradient_bitmap() const; 
-       
-       rgba    get_color() const { return m_color; }
-
-       void    set_color(rgba new_color) { m_color = new_color; }
-
-       int     get_type() const { return m_type; }
-       
-    /// Sets this style to a blend of a and b.  t = [0,1] (for shape morphing)
-       void    set_lerp(const fill_style& a, const fill_style& b, float t);
-       
-       /// Returns the bitmap info for all styles except solid fills
-       //
-       /// NOTE: calling this method against a solid fill style will
-       ///       result in a failed assertion.
-       /// 
-       /// NOTE2: this function can return NULL if the character_id
-       ///        specified for the style in the SWF does not resolve
-       ///        to a character defined in the characters dictionary.
-       ///        (it happens..)
-       ///
-       bitmap_info* get_bitmap_info() const;
-       
-       /// Returns the bitmap transformation matrix
-       matrix get_bitmap_matrix() const; 
-       
-       /// Returns the gradient transformation matrix
-       matrix get_gradient_matrix() const; 
-       
-       /// Returns the number of color stops in the gradient
-       int get_color_stop_count() const;
-       
-       /// Returns the color stop value at a specified index
-       const gradient_record& get_color_stop(int index) const;
-       
-private:
-
-       /// Return the color at the specified ratio into our gradient.
-       //
-       /// @param ratio
-       ///     Ratio is in the range [0, 255].
-       ///
-       rgba sample_gradient(uint8_t ratio) const;
-
-       friend class morph2_character_def;
-       friend class triangulating_render_handler;
-       
-       int     m_type;
-       rgba    m_color;
-       matrix  m_gradient_matrix;
-       std::vector<gradient_record>    m_gradients;
-       boost::intrusive_ptr<gnash::bitmap_info>        m_gradient_bitmap_info;
-       boost::intrusive_ptr<bitmap_character_def>      m_bitmap_character;
-       matrix  m_bitmap_matrix;
-};
-
-
-class morph_fill_style : public base_fill_style
-{
-
-public:
-
-       morph_fill_style();
-
-       morph_fill_style(stream* in, movie_definition* m);
-
-       virtual ~morph_fill_style();
-       
-       void read(stream* in, movie_definition* m);
-
-       rgba sample_gradient(int ratio, float morph);
-
-       bitmap_info* create_gradient_bitmap(float morph) const;
-
-       //virtual void apply(int fill_side, float morph) const;
-       rgba get_color(float morph) const;
-       void set_colors(rgba new_color_orig, rgba new_color_target);
-private:
-       int m_type;
-       rgba m_color[2];
-       matrix m_gradient_matrix[2];
-       std::vector<gradient_record> m_gradients[2];
-       boost::intrusive_ptr<bitmap_info> m_gradient_bitmap_info[2];
-       boost::intrusive_ptr<bitmap_character_def> m_bitmap_character;
-       matrix m_bitmap_matrix[2];
-};
 
 class base_line_style
 {

Index: server/fill_style.cpp
===================================================================
RCS file: server/fill_style.cpp
diff -N server/fill_style.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/fill_style.cpp       13 Feb 2007 15:19:32 -0000      1.1
@@ -0,0 +1,457 @@
+// 
+//   Copyright (C) 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Based on work of Thatcher Ulrich <address@hidden> 2003
+
+
+#include "fill_style.h"
+#include "impl.h"
+#include "log.h"
+#include "render.h"
+#include "stream.h"
+#include "movie_definition.h"
+#include "swf.h"
+#include "GnashException.h"
+
+namespace gnash {
+
+//
+// gradient_record
+//
+
+gradient_record::gradient_record()
+    :
+    m_ratio(0)
+{
+}
+
+
+void
+gradient_record::read(stream* in, int tag_type)
+{
+    m_ratio = in->read_u8();
+    m_color.read(in, tag_type);
+}
+
+
+//
+// fill_style
+//
+
+
+fill_style::fill_style()
+    :
+    m_type(0),
+    m_gradient_bitmap_info(0),
+    m_bitmap_character(0)
+{
+    assert(m_gradients.size() == 0);
+}
+
+
+fill_style::~fill_style()
+{
+}
+
+void
+fill_style::read(stream* in, int tag_type, movie_definition* md)
+{
+    m_type = in->read_u8();
+
+               IF_VERBOSE_PARSE
+               (
+    log_parse("  fill_style read type = 0x%X", m_type);
+               );
+
+    if (m_type == SWF::FILL_SOLID)
+    {
+        // 0x00: solid fill
+        if ( tag_type == SWF::DEFINESHAPE3 )
+        {
+            m_color.read_rgba(in);
+        }
+        else 
+        {
+            // For DefineMorphShape tags we should use morph_fill_style 
+            assert( tag_type == SWF::DEFINESHAPE
+               || tag_type == SWF::DEFINESHAPE2 );
+            m_color.read_rgb(in);
+        }
+
+               IF_VERBOSE_PARSE
+               (
+        log_parse("  color: %s", m_color.toString().c_str());
+               );
+    }
+    else if (m_type == SWF::FILL_LINEAR_GRADIENT
+            || m_type == SWF::FILL_RADIAL_GRADIENT)
+    {
+        // 0x10: linear gradient fill
+        // 0x12: radial gradient fill
+
+        matrix input_matrix;
+        input_matrix.read(in);
+
+        // shouldn't this be in initializer's list ?
+        m_gradient_matrix.set_identity();
+        if (m_type == SWF::FILL_LINEAR_GRADIENT)
+        {
+            m_gradient_matrix.concatenate_translation(128.f, 0.f);
+            m_gradient_matrix.concatenate_scale(1.0f / 128.0f);
+        }
+        else
+        {
+            m_gradient_matrix.concatenate_translation(32.f, 32.f);
+            m_gradient_matrix.concatenate_scale(1.0f / 512.0f);
+        }
+
+        matrix m;
+        m.set_inverse(input_matrix);
+        m_gradient_matrix.concatenate(m);
+                               
+        // GRADIENT
+        uint8_t num_gradients = in->read_u8();
+        if ( ! num_gradients )
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+                       log_swferror("num gradients 0");
+               );
+               return;
+       }
+
+        if ( num_gradients > 8 ) // SWF::DEFINESHAPE4 should support up to 15 !
+                                // and we don't have this limitation anyway
+        {
+            // see: http://sswf.sourceforge.net/SWFalexref.html#swf_gradient
+            log_warning("Unexpected num gradients (%d), expected 1 to 8",
+                    num_gradients);
+        }                      
+
+        m_gradients.resize(num_gradients);
+        for (int i = 0; i < num_gradients; i++)        {
+            m_gradients[i].read(in, tag_type);
+        }
+
+               IF_VERBOSE_PARSE
+               (
+        log_parse("  gradients: num_gradients = %d", num_gradients);
+               );
+
+        // @@ hack.
+        if (num_gradients > 0) {
+            m_color = m_gradients[0].m_color;
+        }
+
+        if (md->get_create_bitmaps() == DO_LOAD_BITMAPS) {
+            m_gradient_bitmap_info = create_gradient_bitmap();
+        // Make sure our movie_def_impl knows about this bitmap.
+        md->add_bitmap_info(m_gradient_bitmap_info.get());
+        }
+    }
+    else if (m_type == SWF::FILL_TILED_BITMAP
+          || m_type == SWF::FILL_CLIPPED_BITMAP
+          || m_type == SWF::FILL_TILED_BITMAP_HARD
+          || m_type == SWF::FILL_CLIPPED_BITMAP_HARD)
+    {
+        // 0x40: tiled bitmap fill
+        // 0x41: clipped bitmap fill
+        // 0x42: tiled bitmap fill with hard edges
+        // 0x43: clipped bitmap fill with hard edges
+
+        int    bitmap_char_id = in->read_u16();
+       IF_VERBOSE_PARSE
+       (
+               log_parse("  bitmap_char = %d", bitmap_char_id);
+       );
+
+        // Look up the bitmap character.
+        m_bitmap_character = md->get_bitmap_character_def(bitmap_char_id);
+       IF_VERBOSE_MALFORMED_SWF(
+       if ( m_bitmap_character == NULL )
+       {
+               static bool warned_about_invalid_char=false;
+               if ( ! warned_about_invalid_char )
+               {
+                       log_swferror("Bitmap fill specifies '%d' as associated"
+                               " bitmap character id,"
+                               " but that character is not found"
+                               " in the Characters Dictionary."
+                               " It seems common to find such "
+                               " malformed SWF, so we'll only warn once "
+                               "about this.",
+                               bitmap_char_id);
+                       warned_about_invalid_char=true;
+               }
+       }
+       );
+
+        matrix m;
+        m.read(in);
+
+        // For some reason, it looks like they store the inverse of the
+        // TWIPS-to-texcoords matrix.
+        m_bitmap_matrix.set_inverse(m);
+
+        IF_VERBOSE_PARSE(
+            m_bitmap_matrix.print();
+        );
+    }
+    else
+    {
+        log_error("Unsupported fill style type: 0x%X", m_type);
+        // This is a fatal error, we'll be leaving the stream
+        // read pointer in an unknown position.
+        throw ParserException("Unsupported fill style (Malformed SWF?)");
+    }
+}
+
+
+bitmap_info* 
+fill_style::get_bitmap_info() const 
+{    
+  assert(m_type != SWF::FILL_SOLID);
+  
+  if (m_type == SWF::FILL_TILED_BITMAP
+   || m_type == SWF::FILL_CLIPPED_BITMAP
+   || m_type == SWF::FILL_TILED_BITMAP_HARD
+   || m_type == SWF::FILL_CLIPPED_BITMAP_HARD) {
+
+   if (m_bitmap_character!=NULL)
+     return m_bitmap_character->get_bitmap_info();
+   else
+     return NULL;
+   
+  } else
+  if (m_type == SWF::FILL_LINEAR_GRADIENT
+   || m_type == SWF::FILL_RADIAL_GRADIENT) {
+   
+   return need_gradient_bitmap();
+   
+  } else {
+    log_msg("Unknown fill style");
+    assert(0);
+  }  
+}
+
+matrix
+fill_style::get_bitmap_matrix() const 
+{
+  assert(m_type != SWF::FILL_SOLID);
+  return m_bitmap_matrix;
+}
+
+matrix
+fill_style::get_gradient_matrix() const 
+{
+  // TODO: Why do we separate bitmap and gradient matrices? 
+  return m_gradient_matrix;
+}
+
+rgba
+fill_style::sample_gradient(uint8_t ratio) const
+{
+       assert(m_type == SWF::FILL_LINEAR_GRADIENT
+               || m_type == SWF::FILL_RADIAL_GRADIENT);
+
+       assert(m_gradients.size());
+
+       // By specs, first gradient should *always* be 0, 
+       // anyway a malformed SWF could break this,
+       // so we cannot rely on that information...
+       if (ratio < m_gradients[0].m_ratio)
+       {
+               IF_VERBOSE_MALFORMED_SWF(
+                       static bool warned=false;
+                       if ( ! warned ) {
+                       log_swferror(
+                               "First gradient in a fill_style "
+                               "have position==%d (expected 0)."
+                               " This seems to be common, so will"
+                               " warn only once."
+                               ,
+                               m_gradients[0].m_ratio);
+                       warned=true;
+                       }
+               );
+               return m_gradients[0].m_color;
+       }
+
+       if ( ratio >= m_gradients.back().m_ratio )
+       {
+               return m_gradients.back().m_color;
+       }
+               
+       for (size_t i = 1, n = m_gradients.size(); i < n; ++i)
+       {
+               const gradient_record& gr1 = m_gradients[i];
+               if (gr1.m_ratio < ratio) continue;
+
+               const gradient_record& gr0 = m_gradients[i - 1];
+               if (gr0.m_ratio > ratio) continue;
+
+               float f = 0.0f;
+
+               if ( gr0.m_ratio != gr1.m_ratio )
+               {
+                       f = (ratio - gr0.m_ratio) / float(gr1.m_ratio - 
gr0.m_ratio);
+               }
+               else
+               {
+                       // Ratios are equal IFF first and second gradient_record
+                       // have the same ratio. This would be a malformed SWF.
+                       IF_VERBOSE_MALFORMED_SWF(
+                               log_swferror(
+                                       "two gradients in a fill_style "
+                                       "have the same position/ratio: %d",
+                                       gr0.m_ratio);
+                       );
+               }
+
+               rgba    result;
+               result.set_lerp(gr0.m_color, gr1.m_color, f);
+               return result;
+       }
+
+       // Assuming gradients are ordered by m_ratio? see start comment
+       return m_gradients.back().m_color;
+}
+
+gnash::bitmap_info*
+fill_style::create_gradient_bitmap() const
+{
+    assert(m_type == SWF::FILL_LINEAR_GRADIENT
+        || m_type == SWF::FILL_RADIAL_GRADIENT);
+
+    image::rgba*       im = NULL;
+
+    if (m_type == SWF::FILL_LINEAR_GRADIENT)
+    {
+        // Linear gradient.
+        im = image::create_rgba(256, 1);
+
+        for (int i = 0; i < im->m_width; i++) {
+            rgba       sample = sample_gradient(i);
+            im->set_pixel(i, 0, sample.m_r, sample.m_g, sample.m_b, 
sample.m_a);
+        }
+    }
+    else if (m_type == SWF::FILL_RADIAL_GRADIENT)
+    {
+        // Radial gradient.
+        im = image::create_rgba(64, 64);
+
+        for (int j = 0; j < im->m_height; j++) {
+            for (int i = 0; i < im->m_width; i++) {
+                float  radius = (im->m_height - 1) / 2.0f;
+                float  y = (j - radius) / radius;
+                float  x = (i - radius) / radius;
+                int    ratio = (int) floorf(255.5f * sqrt(x * x + y * y));
+                if (ratio > 255) {
+                    ratio = 255;
+                }
+                rgba   sample = sample_gradient( ratio );
+                im->set_pixel(i, j, sample.m_r, sample.m_g, sample.m_b, 
sample.m_a);
+            }
+        }
+    }
+    gnash::bitmap_info*        bi = gnash::render::create_bitmap_info_rgba(im);
+    delete im;
+
+    return bi;
+}
+
+
+gnash::bitmap_info*
+fill_style::need_gradient_bitmap() const 
+{
+
+  if (m_gradient_bitmap_info==NULL) {
+    fill_style*        this_non_const = const_cast<fill_style*>(this);
+    this_non_const->m_gradient_bitmap_info = create_gradient_bitmap();
+  }
+  
+  return m_gradient_bitmap_info.get();
+
+}
+
+
+void
+fill_style::set_lerp(const fill_style& a, const fill_style& b, float t)
+    // Sets this style to a blend of a and b.  t = [0,1]
+{
+    assert(t >= 0 && t <= 1);
+
+    // fill style type
+    m_type = a.get_type();
+    assert(m_type == b.get_type());
+
+    // fill style color
+    m_color.set_lerp(a.get_color(), b.get_color(), t);
+
+    // fill style gradient matrix
+    //
+    // @@ TODO morphed gradients don't come out exactly
+    // right; they shift around some.  Not sure where the
+    // problem is.
+    m_gradient_matrix.set_lerp(a.m_gradient_matrix, b.m_gradient_matrix, t);
+
+    // fill style gradients
+    assert(m_gradients.size() == a.m_gradients.size());
+    assert(m_gradients.size() == b.m_gradients.size());
+    for (size_t j=0, nj=m_gradients.size(); j<nj; ++j)
+    {
+        m_gradients[j].m_ratio =
+            (uint8_t) frnd(
+                flerp(a.m_gradients[j].m_ratio, b.m_gradients[j].m_ratio, t)
+                );
+        m_gradients[j].m_color.set_lerp(a.m_gradients[j].m_color, 
b.m_gradients[j].m_color, t);
+    }
+    m_gradient_bitmap_info = NULL;
+
+    // fill style bitmap ID
+    m_bitmap_character = a.m_bitmap_character;
+    assert(m_bitmap_character == b.m_bitmap_character);
+
+    // fill style bitmap matrix
+    m_bitmap_matrix.set_lerp(a.m_bitmap_matrix, b.m_bitmap_matrix, t);
+}
+
+
+int 
+fill_style::get_color_stop_count() const 
+{
+  return m_gradients.size();
+}
+
+const gradient_record& 
+fill_style::get_color_stop(int index) const
+{
+  return m_gradients[index];
+}
+
+fill_style::fill_style(bitmap_character_def* bitmap)
+{
+       m_bitmap_character = bitmap;
+       m_type = SWF::FILL_CLIPPED_BITMAP;
+}
+
+
+// end of namespace
+}
+
+
+// Local Variables:
+// mode: C++
+// End:

Index: server/fill_style.h
===================================================================
RCS file: server/fill_style.h
diff -N server/fill_style.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/fill_style.h 13 Feb 2007 15:19:32 -0000      1.1
@@ -0,0 +1,146 @@
+// 
+//   Copyright (C) 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Based on work of Thatcher Ulrich <address@hidden> 2003
+
+/* $Id: fill_style.h,v 1.1 2007/02/13 15:19:32 strk Exp $ */
+
+#ifndef GNASH_FILL_STYLE_H
+#define GNASH_FILL_STYLE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+//#include "impl.h"
+#include "types.h"
+#include "matrix.h"
+#include "bitmap_character_def.h"
+
+namespace gnash {
+
+class stream;
+
+class gradient_record
+{
+public:
+       gradient_record();
+       void    read(stream* in, int tag_type);
+       
+       //data:
+       uint8_t m_ratio;
+       rgba    m_color;
+};
+
+
+/// For the interior of outline shapes.
+//
+class DSOEXPORT fill_style 
+{
+public:
+
+       fill_style();
+
+       /// Construct a clipped bitmap fill style, for
+       /// use by bitmap shape character.
+       ///
+       /// TODO: use a subclass for this
+       ///
+       fill_style(bitmap_character_def* bitmap);
+
+       virtual ~fill_style();
+       
+       /// Read the fill style from a stream
+       //
+       /// TODO: use a subclass for this (swf_fill_style?)
+       ///
+       void    read(stream* in, int tag_type, movie_definition* m);
+
+       /// \brief
+       /// Make a bitmap_info* corresponding to our gradient.
+       /// We can use this to set the gradient fill style.
+       gnash::bitmap_info*     create_gradient_bitmap() const;
+       
+       /// \brief
+       /// Makes sure that m_gradient_bitmap_info is not NULL. Calls 
+       /// create_gradient_bitmap() if necessary and returns 
m_gradient_bitmap_info.
+       gnash::bitmap_info* need_gradient_bitmap() const; 
+       
+       rgba    get_color() const { return m_color; }
+
+       void    set_color(rgba new_color) { m_color = new_color; }
+
+       int     get_type() const { return m_type; }
+       
+       /// Sets this style to a blend of a and b.  t = [0,1] (for shape 
morphing)
+       void    set_lerp(const fill_style& a, const fill_style& b, float t);
+       
+       /// Returns the bitmap info for all styles except solid fills
+       //
+       /// NOTE: calling this method against a solid fill style will
+       ///       result in a failed assertion.
+       /// 
+       /// NOTE2: this function can return NULL if the character_id
+       ///        specified for the style in the SWF does not resolve
+       ///        to a character defined in the characters dictionary.
+       ///        (it happens..)
+       ///
+       bitmap_info* get_bitmap_info() const;
+       
+       /// Returns the bitmap transformation matrix
+       matrix get_bitmap_matrix() const; 
+       
+       /// Returns the gradient transformation matrix
+       matrix get_gradient_matrix() const; 
+       
+       /// Returns the number of color stops in the gradient
+       int get_color_stop_count() const;
+       
+       /// Returns the color stop value at a specified index
+       const gradient_record& get_color_stop(int index) const;
+       
+private:
+
+       /// Return the color at the specified ratio into our gradient.
+       //
+       /// @param ratio
+       ///     Ratio is in the range [0, 255].
+       ///
+       rgba sample_gradient(uint8_t ratio) const;
+
+       friend class morph2_character_def;
+       friend class triangulating_render_handler;
+       
+       int     m_type;
+       rgba    m_color;
+       matrix  m_gradient_matrix;
+       std::vector<gradient_record>    m_gradients;
+       boost::intrusive_ptr<gnash::bitmap_info>        m_gradient_bitmap_info;
+       boost::intrusive_ptr<bitmap_character_def>      m_bitmap_character;
+       matrix  m_bitmap_matrix;
+};
+
+
+} // namespace gnash
+
+
+#endif // GNASH_FILL_STYLE_H
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:




reply via email to

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