[Top][All Lists]
[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:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/Makefile.am server/style...,
Sandro Santilli <=