2
0
Эх сурвалжийг харах

respect fgcolor and bgcolor for twirling icon

David Rose 14 жил өмнө
parent
commit
da3d88fefa

+ 3 - 1
direct/src/plugin/Sources.pp

@@ -33,6 +33,7 @@
     handleStream.cxx handleStream.h handleStream.I \
     handleStream.cxx handleStream.h handleStream.I \
     handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \
     handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \
     mkdir_complete.cxx mkdir_complete.h \
     mkdir_complete.cxx mkdir_complete.h \
+    parse_color.cxx parse_color.h \
     p3d_lock.h p3d_plugin.h \
     p3d_lock.h p3d_plugin.h \
     p3d_plugin_config.h \
     p3d_plugin_config.h \
     p3d_plugin_common.h \
     p3d_plugin_common.h \
@@ -182,7 +183,8 @@
     $[if $[IS_OSX],find_root_dir_assist.mm] \
     $[if $[IS_OSX],find_root_dir_assist.mm] \
     is_pathsep.h is_pathsep.I \
     is_pathsep.h is_pathsep.I \
     mkdir_complete.cxx mkdir_complete.h \
     mkdir_complete.cxx mkdir_complete.h \
-    get_twirl_data.cxx get_twirl_data.h
+    get_twirl_data.cxx get_twirl_data.h \
+    parse_color.cxx parse_color.h
 
 
 #begin static_lib_target
 #begin static_lib_target
 //
 //

+ 23 - 9
direct/src/plugin/get_twirl_data.cxx

@@ -689,19 +689,25 @@ static const unsigned char * const twirl_data[3] = {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: get_twirl_data
 //     Function: get_twirl_data
 //  Description: Fills the indicated data array with a string of
 //  Description: Fills the indicated data array with a string of
-//               twirl_width * twirl_height bytes, representing the
-//               grayscale pixel values of the twirl_width x
+//               twirl_width * twirl_height * 3 bytes, representing
+//               the RGB pixel values of the twirl_width x
 //               twirl_height image at frame number step of
 //               twirl_height image at frame number step of
-//               twirl_num_steps frames.  Returns true on success,
-//               false on failure.
+//               twirl_num_steps frames.  The specified fg and bg
+//               colors are applied to the array appropriately.
+//
+//               Returns true on success, false on failure.  On false,
+//               the array is initialized with zero.
 //
 //
 //               You must pass data_length = twirl_width *
 //               You must pass data_length = twirl_width *
-//               twirl_height; this value is passed as a sanity check
-//               on array size.  You should pass step so that 0 <=
-//               step < twirl_num_steps.
+//               twirl_height * 3; this value is passed as a sanity
+//               check on array size.  You should pass step so that 0
+//               <= step < twirl_num_steps.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool
 bool
-get_twirl_data(unsigned char data[], size_t data_length, int step) {
+get_twirl_data(unsigned char data[], size_t data_length, int step,
+               int fg_r, int fg_g, int fg_b,
+               int bg_r, int bg_g, int bg_b) {
+
   if (step < 0 || step >= twirl_num_steps) {
   if (step < 0 || step >= twirl_num_steps) {
     memset(data, 0, data_length);
     memset(data, 0, data_length);
     return false;
     return false;
@@ -715,6 +721,7 @@ get_twirl_data(unsigned char data[], size_t data_length, int step) {
   const unsigned char *in_data = twirl_data[flip._index];
   const unsigned char *in_data = twirl_data[flip._index];
 
 
   for (int yi = 0; yi < twirl_height; ++yi) {
   for (int yi = 0; yi < twirl_height; ++yi) {
+    const unsigned char *sp = &in_data[yi * twirl_width];
     for (int xi = 0; xi < twirl_width; ++xi) {
     for (int xi = 0; xi < twirl_width; ++xi) {
       int xo = xi;
       int xo = xi;
       int yo = yi;
       int yo = yi;
@@ -729,8 +736,15 @@ get_twirl_data(unsigned char data[], size_t data_length, int step) {
         xo = yo;
         xo = yo;
         yo = t;
         yo = t;
       }
       }
+      unsigned char *dp = &data[yo * twirl_width * 3];
+      dp += 3 * xo;
+
+      double t = (double)(*sp) / 255.0;
+      ++sp;
 
 
-      data[yo * twirl_width + xo] = in_data[yi * twirl_width + xi];
+      dp[0] = (unsigned char)(fg_r + t * (bg_r - fg_r));
+      dp[1] = (unsigned char)(fg_g + t * (bg_g - fg_g));
+      dp[2] = (unsigned char)(fg_b + t * (bg_b - fg_b));
     }
     }
   }
   }
 
 

+ 4 - 2
direct/src/plugin/get_twirl_data.h

@@ -15,13 +15,15 @@
 #ifndef GET_TWIRL_DATA_H
 #ifndef GET_TWIRL_DATA_H
 #define GET_TWIRL_DATA_H
 #define GET_TWIRL_DATA_H
 
 
-#include "stddef.h"
+#include <stddef.h>
 
 
 static const int twirl_width = 48;
 static const int twirl_width = 48;
 static const int twirl_height = 48;
 static const int twirl_height = 48;
 static const int twirl_num_steps = 12;
 static const int twirl_num_steps = 12;
 
 
-bool get_twirl_data(unsigned char data[], size_t data_length, int step);
+bool get_twirl_data(unsigned char data[], size_t data_length, int step,
+                    int fg_r, int fg_g, int fg_b,
+                    int bg_r, int bg_g, int bg_b);
 
 
 #endif
 #endif
 
 

+ 1 - 62
direct/src/plugin/p3dInstance.cxx

@@ -26,6 +26,7 @@
 #include "p3dUndefinedObject.h"
 #include "p3dUndefinedObject.h"
 #include "p3dMultifileReader.h"
 #include "p3dMultifileReader.h"
 #include "p3dTemporaryFile.h"
 #include "p3dTemporaryFile.h"
+#include "parse_color.h"
 
 
 #include <sstream>
 #include <sstream>
 #include <algorithm>
 #include <algorithm>
@@ -3872,68 +3873,6 @@ send_notify(const string &message) {
   add_baked_request(request);
   add_baked_request(request);
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: P3DInstance::parse_color
-//       Access: Private, Static
-//  Description: Parses a HTML color spec of the form #rgb or #rrggbb.
-//               Returns true on success, false on failure.  On
-//               success, fills r, g, b with the color values in the
-//               range 0..255.  On failure, r, g, b are undefined.
-////////////////////////////////////////////////////////////////////
-bool P3DInstance::
-parse_color(int &r, int &g, int &b, const string &color) {
-  if (color.empty() || color[0] != '#') {
-    return false;
-  }
-  if (color.length() == 4) {
-    if (!parse_hexdigit(r, color[1]) || 
-        !parse_hexdigit(g, color[2]) || 
-        !parse_hexdigit(b, color[3])) {
-      return false;
-    }
-    r *= 0x11;
-    g *= 0x11;
-    b *= 0x11;
-    return true;
-  }
-  if (color.length() == 7) {
-    int rh, rl, gh, gl, bh, bl;
-    if (!parse_hexdigit(rh, color[1]) ||
-        !parse_hexdigit(rl, color[2]) ||
-        !parse_hexdigit(gh, color[3]) ||
-        !parse_hexdigit(gl, color[4]) ||
-        !parse_hexdigit(bh, color[5]) ||
-        !parse_hexdigit(bl, color[6])) {
-      return false;
-    }
-    r = (rh << 4) | rl;
-    g = (gh << 4) | gl;
-    b = (bh << 4) | bl;
-    return true;
-  }
-
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: P3DInstance::parse_hexdigit
-//       Access: Private, Static
-//  Description: Parses a single hex digit.  Returns true on success,
-//               false on failure.  On success, fills result with the
-//               parsed value, an integer in the range 0..15.
-////////////////////////////////////////////////////////////////////
-bool P3DInstance::
-parse_hexdigit(int &result, char digit) {
-  if (isdigit(digit)) {
-    result = digit - '0';
-    return true;
-  } else if (isxdigit(digit)) {
-    result = tolower(digit) - 'a' + 10;
-    return true;
-  }
-  return false;
-}
-
 #ifdef __APPLE__
 #ifdef __APPLE__
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::alloc_swbuffer
 //     Function: P3DInstance::alloc_swbuffer

+ 0 - 3
direct/src/plugin/p3dInstance.h

@@ -220,9 +220,6 @@ private:
 
 
   void send_notify(const string &message);
   void send_notify(const string &message);
 
 
-  static bool parse_color(int &r, int &g, int &b, const string &color);
-  static bool parse_hexdigit(int &result, char digit);
-
 #ifdef __APPLE__
 #ifdef __APPLE__
   void alloc_swbuffer();
   void alloc_swbuffer();
   void free_swbuffer();
   void free_swbuffer();

+ 78 - 0
direct/src/plugin/parse_color.cxx

@@ -0,0 +1,78 @@
+// Filename: parse_color.cxx
+// Created by:  drose (25Aug11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "parse_color.h"
+#include <ctype.h>
+
+static bool parse_hexdigit(int &result, char digit);
+
+////////////////////////////////////////////////////////////////////
+//     Function: parse_color
+//  Description: Parses a HTML color spec of the form #rgb or #rrggbb.
+//               Returns true on success, false on failure.  On
+//               success, fills r, g, b with the color values in the
+//               range 0..255.  On failure, r, g, b are undefined.
+////////////////////////////////////////////////////////////////////
+bool
+parse_color(int &r, int &g, int &b, const string &color) {
+  if (color.empty() || color[0] != '#') {
+    return false;
+  }
+  if (color.length() == 4) {
+    if (!parse_hexdigit(r, color[1]) || 
+        !parse_hexdigit(g, color[2]) || 
+        !parse_hexdigit(b, color[3])) {
+      return false;
+    }
+    r *= 0x11;
+    g *= 0x11;
+    b *= 0x11;
+    return true;
+  }
+  if (color.length() == 7) {
+    int rh, rl, gh, gl, bh, bl;
+    if (!parse_hexdigit(rh, color[1]) ||
+        !parse_hexdigit(rl, color[2]) ||
+        !parse_hexdigit(gh, color[3]) ||
+        !parse_hexdigit(gl, color[4]) ||
+        !parse_hexdigit(bh, color[5]) ||
+        !parse_hexdigit(bl, color[6])) {
+      return false;
+    }
+    r = (rh << 4) | rl;
+    g = (gh << 4) | gl;
+    b = (bh << 4) | bl;
+    return true;
+  }
+
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: parse_hexdigit
+//  Description: Parses a single hex digit.  Returns true on success,
+//               false on failure.  On success, fills result with the
+//               parsed value, an integer in the range 0..15.
+////////////////////////////////////////////////////////////////////
+bool
+parse_hexdigit(int &result, char digit) {
+  if (isdigit(digit)) {
+    result = digit - '0';
+    return true;
+  } else if (isxdigit(digit)) {
+    result = tolower(digit) - 'a' + 10;
+    return true;
+  }
+  return false;
+}

+ 24 - 0
direct/src/plugin/parse_color.h

@@ -0,0 +1,24 @@
+// Filename: parse_color.h
+// Created by:  drose (25Aug11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PARSE_COLOR_H
+#define PARSE_COLOR_H
+
+#include <string>
+using namespace std;
+
+bool parse_color(int &r, int &g, int &b, const string &color);
+
+#endif
+

+ 71 - 17
direct/src/plugin_npapi/ppInstance.cxx

@@ -20,6 +20,7 @@
 #include "p3d_plugin_config.h"
 #include "p3d_plugin_config.h"
 #include "find_root_dir.h"
 #include "find_root_dir.h"
 #include "mkdir_complete.h"
 #include "mkdir_complete.h"
+#include "parse_color.h"
 #include "nppanda3d_common.h"
 #include "nppanda3d_common.h"
 
 
 // We can include this header file to get the DTOOL_PLATFORM
 // We can include this header file to get the DTOOL_PLATFORM
@@ -96,6 +97,36 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
   _p3d_temp_file_total_size = 0;
   _p3d_temp_file_total_size = 0;
   _p3d_instance_id = 0;
   _p3d_instance_id = 0;
 
 
+  // fgcolor and bgcolor are useful to know here (in case we have to
+  // draw a twirling icon).
+
+  // The default fgcolor is white.
+  _bgcolor_r = _bgcolor_g = _bgcolor_b = 0xff;
+  if (has_token("bgcolor")) {
+    int r, g, b;
+    if (parse_color(r, g, b, lookup_token("bgcolor"))) {
+      _bgcolor_r = r;
+      _bgcolor_g = g;
+      _bgcolor_b = b;
+    }
+  }
+
+  // The default fgcolor is either black or white, according to the
+  // brightness of the bgcolor.
+  if (_bgcolor_r + _bgcolor_g + _bgcolor_b > 0x80 + 0x80 + 0x80) {
+    _fgcolor_r = _fgcolor_g = _fgcolor_b = 0x00;
+  } else {
+    _fgcolor_r = _fgcolor_g = _fgcolor_b = 0xff;
+  }
+  if (has_token("fgcolor")) {
+    int r, g, b;
+    if (parse_color(r, g, b, lookup_token("fgcolor"))) {
+      _fgcolor_r = r;
+      _fgcolor_g = g;
+      _fgcolor_b = b;
+    }
+  }
+
   _got_window = false;
   _got_window = false;
   _python_window_open = false;
   _python_window_open = false;
 #ifdef _WIN32
 #ifdef _WIN32
@@ -1927,6 +1958,25 @@ lookup_token(const string &keyword) const {
   return string();
   return string();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::has_token
+//       Access: Public
+//  Description: Returns true if the named token appears in the list,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool PPInstance::
+has_token(const string &keyword) const {
+  Tokens::const_iterator ti;
+  for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) {
+    if ((*ti)._keyword == keyword) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PPInstance::compare_seq
 //     Function: PPInstance::compare_seq
 //       Access: Private, Static
 //       Access: Private, Static
@@ -2203,22 +2253,24 @@ win_get_twirl_bitmaps() {
   HDC dc = GetDC(_hwnd);
   HDC dc = GetDC(_hwnd);
 
 
   static const size_t twirl_size = twirl_width * twirl_height;
   static const size_t twirl_size = twirl_width * twirl_height;
-  unsigned char twirl_data[twirl_size];
+  unsigned char twirl_data[twirl_size * 3];
   unsigned char new_data[twirl_size * 4];
   unsigned char new_data[twirl_size * 4];
 
 
   for (int step = 0; step < twirl_num_steps; ++step) {
   for (int step = 0; step < twirl_num_steps; ++step) {
-    get_twirl_data(twirl_data, twirl_size, step);
+    get_twirl_data(twirl_data, twirl_size, step,
+                   _fgcolor_r, _fgcolor_g, _fgcolor_b, 
+                   _bgcolor_r, _bgcolor_g, _bgcolor_b);
 
 
-    // Replicate out the grayscale channels into RGBA.
+    // Expand out the RGB channels into RGBA.
     for (int yi = 0; yi < twirl_height; ++yi) {
     for (int yi = 0; yi < twirl_height; ++yi) {
-      const unsigned char *sp = twirl_data + yi * twirl_width;
+      const unsigned char *sp = twirl_data + yi * twirl_width * 3;
       unsigned char *dp = new_data + yi * twirl_width * 4;
       unsigned char *dp = new_data + yi * twirl_width * 4;
       for (int xi = 0; xi < twirl_width; ++xi) {
       for (int xi = 0; xi < twirl_width; ++xi) {
         dp[0] = sp[0];
         dp[0] = sp[0];
-        dp[1] = sp[0];
-        dp[2] = sp[0];
+        dp[1] = sp[1];
+        dp[2] = sp[2];
         dp[3] = (unsigned char)0xff;
         dp[3] = (unsigned char)0xff;
-        sp += 1;
+        sp += 3;
         dp += 4;
         dp += 4;
       }
       }
     }
     }
@@ -2457,24 +2509,26 @@ osx_get_twirl_images() {
   _got_twirl_images = true;
   _got_twirl_images = true;
 
 
   static const size_t twirl_size = twirl_width * twirl_height;
   static const size_t twirl_size = twirl_width * twirl_height;
-  unsigned char twirl_data[twirl_size];
+  unsigned char twirl_data[twirl_size * 3];
 
 
   for (int step = 0; step < twirl_num_steps; ++step) {
   for (int step = 0; step < twirl_num_steps; ++step) {
-    get_twirl_data(twirl_data, twirl_size, step);
+    get_twirl_data(twirl_data, twirl_size, step,
+                   _fgcolor_r, _fgcolor_g, _fgcolor_b, 
+                   _bgcolor_r, _bgcolor_g, _bgcolor_b);
 
 
     unsigned char *new_data = new unsigned char[twirl_size * 4];
     unsigned char *new_data = new unsigned char[twirl_size * 4];
 
 
-    // Replicate out the grayscale channels into RGBA.  Flip
-    // upside-down too.
+    // Expand the RGB channels into RGBA.  Flip upside-down too.
     for (int yi = 0; yi < twirl_height; ++yi) {
     for (int yi = 0; yi < twirl_height; ++yi) {
-      const unsigned char *sp = twirl_data + (twirl_height - 1 - yi) * twirl_width;
+      const unsigned char *sp = twirl_data + (twirl_height - 1 - yi) * twirl_width * 3;
       unsigned char *dp = new_data + yi * twirl_width * 4;
       unsigned char *dp = new_data + yi * twirl_width * 4;
       for (int xi = 0; xi < twirl_width; ++xi) {
       for (int xi = 0; xi < twirl_width; ++xi) {
-        dp[0] = sp[0];
-        dp[1] = sp[0];
+        // RGB <= BGR.
+        dp[0] = sp[2];
+        dp[1] = sp[1];
         dp[2] = sp[0];
         dp[2] = sp[0];
         dp[3] = (unsigned char)0xff;
         dp[3] = (unsigned char)0xff;
-        sp += 1;
+        sp += 3;
         dp += 4;
         dp += 4;
       }
       }
     }
     }
@@ -2547,8 +2601,8 @@ osx_release_twirl_images() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void PPInstance::
 void PPInstance::
 paint_twirl_osx_cgcontext(CGContextRef context) {
 paint_twirl_osx_cgcontext(CGContextRef context) {
-  // Clear the whole region to white before beginning.
-  CGFloat bg_components[] = { 1, 1, 1, 1 };
+  // Clear the whole region to the bgcolor before beginning.
+  CGFloat bg_components[] = { _bgcolor_r / 255.0f, _bgcolor_g / 255.0f, _bgcolor_b / 255.0f, 1 };
   CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
   CGColorSpaceRef rgb_space = CGColorSpaceCreateDeviceRGB();
   CGColorRef bg = CGColorCreate(rgb_space, bg_components);
   CGColorRef bg = CGColorCreate(rgb_space, bg_components);
 
 

+ 5 - 0
direct/src/plugin_npapi/ppInstance.h

@@ -96,6 +96,7 @@ private:
   bool copy_file(const string &from_filename, const string &to_filename);
   bool copy_file(const string &from_filename, const string &to_filename);
 
 
   string lookup_token(const string &keyword) const;
   string lookup_token(const string &keyword) const;
+  bool has_token(const string &keyword) const;
   static int compare_seq(const string &seq_a, const string &seq_b);
   static int compare_seq(const string &seq_a, const string &seq_b);
   static int compare_seq_int(const char *&num_a, const char *&num_b);
   static int compare_seq_int(const char *&num_a, const char *&num_b);
 
 
@@ -145,6 +146,10 @@ private:
   typedef vector<P3D_token> Tokens;
   typedef vector<P3D_token> Tokens;
   Tokens _tokens;
   Tokens _tokens;
 
 
+  // Set from fgcolor & bgcolor.
+  int _fgcolor_r, _fgcolor_b, _fgcolor_g;
+  int _bgcolor_r, _bgcolor_b, _bgcolor_g;
+  
   string _root_dir;
   string _root_dir;
   string _standard_url_prefix;
   string _standard_url_prefix;
   string _download_url_prefix;
   string _download_url_prefix;