Tuesday, May 17, 2011

User.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;

public enum Roles : int
{
    Administrator = 1,
    Standard = 2
}

/// <summary>
/// Summary description for User
/// </summary>
public class User
{
    public Roles Role       { get; set; }
    public string Username  { get; set; }
    public string Password  { get; set; }
    public int UserId       { get; set; }

    public User()
    {
        //
        // TODO: Add constructor logic here
        //       
    }

    public void Save()
    {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["bluelobsterConnectionString"].ConnectionString);
        SqlCommand cmd = new SqlCommand("up_user_save",con);
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
       
        cmd.Parameters.Add("@password", System.Data.SqlDbType.VarChar).Value = Password;

        try
        {
            con.Open();

            cmd.ExecuteNonQuery();
        }
        catch(SqlException sqlEx)
        {

        }
        finally
        {
            con.Close();
        }
    }

    public void Retrieve()
    {
      
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["bluelobsterConnectionString"].ConnectionString);
        SqlCommand cmd = new SqlCommand("up_user_retrieve",con);
      
        SqlDataReader dr = null;
       
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
      
        cmd.Parameters.Add("@user_id", System.Data.SqlDbType.VarChar).Value = UserId;
        cmd.Parameters.Add("@username", System.Data.SqlDbType.VarChar).Value = Username;
        cmd.Parameters.Add("@password", System.Data.SqlDbType.VarChar).Value = Password;

        try
        {
            con.Open();

            dr = cmd.ExecuteReader();

            dr.Read();

            Password = dr["password"].ToString();
            Username = dr["username"].ToString();
            UserId = int.Parse(dr["user_id"].ToString());
            Role = (Roles)dr["role_id"];
        }
        catch (SqlException sqlEx)
        {

        }
        finally
        {
            con.Close();
        }
    }

}

MySession

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for MySession
/// </summary>

public class MySession
{
    // private constructor
    private MySession() { }

    // Gets the current session.
    public static MySession Current
    {
        get
        {
            MySession session =
                (MySession)HttpContext.Current.Session["__MySession__"];
            if (session == null)
            {
                session = new MySession();
                HttpContext.Current.Session["__MySession__"] = session;
            }
            return session;
        }
    }

    public static void Clear()
    {
        MySession session =
                (MySession)HttpContext.Current.Session["__MySession__"];
        if (session != null)
        {
            HttpContext.Current.Session.Remove("__MySession__");
        }
    }

    // **** add your session properties here, e.g like this:
      
    public User User { get; set; }

}

Saturday, December 11, 2010

Comicbook.js - Release 0.3

For my 0.3 release of comicbook.js I've attempted to optimize the combination of closepixelate.js and video by writing the image to a canvas in memory then copying the image over to the main canvas when the write was finished. View the demo here.

Using the function renderToCanvas() allows me to buffer the write and return the result

  renderToCanvas: function (self, renderOptions, width, height, renderFunction) {
    var buffer = document.createElement('canvas');
    buffer.width = width;
    buffer.height = height;
    renderFunction(buffer.getContext('2d'), renderOptions, self);
    return buffer;
  }

var cached = this.renderToCanvas(
                self,
                renderOptions,
                this.c1.width,
                this.c1.height,
                function (ctx, renderOptions, self) {               
                    var imgData = self.ctx1.getImageData(0, 0, self.c1.width, self.c1.height);//.data;
                    self.ctx1.clearRect( 0, 0, self.c1.width, self.c1.height);
                    for (var i=0, len = renderOptions.length; i < len; i++) {
                     var opts = renderOptions[i],
                          res = opts.resolution,
                          // option defaults
                          size = opts.size || res,
                          alpha = opts.alpha || 1,
                          offset = opts.offset || 0,
                          offsetX = 0,
                          offsetY = 0,
                          cols = self.c1.width / res + 1,
                          rows = self.c1.height / res + 1,
                          halfSize = size / 2,
                          diamondSize = size / Math.SQRT2,
                          halfDiamondSize = diamondSize / 2;

                    offsetX = offsetY = offset;
                   
                     for ( var row = 0; row < rows; row++ ) {
                        var y = ( row - 0.5 ) * res + offsetY,
                          // normalize y so shapes around edges get color
                          pixelY = Math.max( Math.min( y, self.c1.height-1), 0);

                        for ( var col = 0; col < cols; col++ ) { 
                          var x = ( col - 0.5 ) * res + offsetX,
                                // normalize y so shapes around edges get color
                                pixelX = Math.max( Math.min( x, self.c1.width-1), 0),
                                pixelIndex = ( pixelX + pixelY * self.c1.width ) * 4,
                                red = imgData.data[ pixelIndex + 0 ],
                                green = imgData.data[ pixelIndex + 1 ],
                                blue = imgData.data[ pixelIndex + 2 ],
                                pixelAlpha = alpha * (imgData.data[ pixelIndex + 3 ] / 255);

                            ctx.fillStyle = 'rgba(' + red +','+ green +','+ blue +','+ pixelAlpha + ')';

                          switch ( opts.shape ) {
                             case 'circle' :
                                ctx.beginPath();
                                  ctx.arc ( x, y, halfSize, 0, self.PI2, true );
                                  ctx.fill();
                                ctx.closePath();
                                break;
                             case 'diamond' :
                                ctx.save();
                                  ctx.translate( x, y );
                                  ctx.rotate( self.PI1_4 );
                                  ctx.fillRect( -halfDiamondSize, -halfDiamondSize, diamondSize, diamondSize );
                                ctx.restore();
                                break;
                             default : // square           
                                ctx.fillRect( x - halfSize, y - halfSize, size, size );
                          } // switch       
                        } // col
                     } // row   
                  } // options
                }

this.ctx1.drawImage(cached, 0, 0);

This technique has definitely helped the performance. Another method of optimization that is probably more efficient is to eliminate the canvas draw functions altogether and create custom functions which modify the image data array directly.

I'm still stumped as to how to actually create the Halftone/Duotone effect which is pretty disappointing. Though the course is now over I'll continue working on this project on my own time.

Wednesday, December 8, 2010

Testing Firefox changes

The next step after customizing Firefox to open new tabs adjacent to the current tab, was to create an automated test to validate that everything works in all situations.

The first step is to (re)build with the enable-tests option  by placing "ac_add_options --enable-tests" in .mozconfig

Now we'll need to write our test() function using assertions; ok(), is(), isnot()

ok(val, "val exists!");                        // Tests existence
is(val1, val2, "val1 equals val2");            // Tests equality
isnot(val1, val2, "val1 does not equal val2"); // Tests if not equal

My test script looks like this:

function test() {
 var firstTab = gBrowser.addTab();

 var tabs = gBrowser.tabs;

 is(tabs.length, 2, "2 tabs are open");
 is(gBrowser.selectedTab._tPos, 0, "First tab is selected");

 var newTab = gBrowser.addTab();

 is(gBrowser.selectedTab._tPos, 0, "first tab selected");
 is(tabs[2]._tPos, newTab._tPos, "Was inserted at #3");

 gBrowser.moveTabTo(newTab,0);
 is(newTab._tPos,0, "moved new tab to first position");
 var tempLen = tabs.length;
 gBrowser.removeTab(newTab);
 is(tabs.length, tempLen-1 ,"deleted newTab");

 while (tabs.length > 1)
  gBrowser.removeCurrentTab();
}

So where do we put this file?
src\obj-i686-pc-mingw32\_tests\testing\mochitest\browser\browser\base\content\test\browser_tab_test.js

To run the test script run navigate to the src directory and run:

 TEST_PATH=browser/base/content/test/YOUR_TEST_SCRIPT.js make -C $(OBJDIR) mochitest-browser-chrome

When the test finishes you should see the results as either TEST-PASS or TEST-UNEXPECTED-FAIL.

Sunday, December 5, 2010

Customizing Firefox

Continuing with Firefox our next assignment was to modify the browser slightly by making new tabs appear right after the current tab. Since we already know how to get the source code and build it it's just a matter of finding the code we need to modify.

One way of searching through the code is to use http://mxr.mozilla.org.

We eventually found our way to this snippet of code: http://mxr.mozilla.org/mozilla-central/source/browser/base/content/tabbrowser.xml#1326

1321             // Check if we're opening a tab related to the current tab and
1322             // move it to after the current tab.
1323             // aReferrerURI is null or undefined if the tab is opened from
1324             // an external application or bookmark, i.e. somewhere other
1325             // than the current tab.
1326             if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
1327                 Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
1328               let newTabPos = (this._lastRelatedTab ||
1329                                this.selectedTab)._tPos + 1;
1330               if (this._lastRelatedTab)
1331                 this._lastRelatedTab.owner = null;
1332               else
1333                 t.owner = this.selectedTab;
1334               this.moveTabTo(t, newTabPos);
1335               this._lastRelatedTab = t;
1336             }

Just by reading the commented code you'll see that this is exactly what we're looking for. It checks to see if the current tab is related to the new tab and will open it next to the current if true. So by commenting out the first "if" statement we will essentially make all new tabs open next to the current. Our new changes will look like this:

-            if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
-                Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
+            //if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
+            //    Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
               let newTabPos = (this._lastRelatedTab ||
                                this.selectedTab)._tPos + 1;
               if (this._lastRelatedTab)
                 this._lastRelatedTab.owner = null;
               else
                 t.owner = this.selectedTab;
               this.moveTabTo(t, newTabPos);
               this._lastRelatedTab = t;
-            }
+            //}

Thats it, we didn't even have to write any new code, simply commenting out several lines did what we were looking for. Finally build the source code again.

Building Firefox from source

Building Firefox was a lot easier than I thought it would be. When we were initially given the assignment I felt pretty lost because I had no idea what building the code would entail. After doing the research I found that the steps involved are actually quite simple:

Step 1 - Installing Mercurial:

Download Mercurial here and run the setup. The installation will create c:\mozilla-build by default. When the installation is done navigate to the mozilla-build folder and depending what version of visual studio you have you'll run one of:

  • start-msvc8.bat  (VS 2005)
  • start-msvc9.bat  (VS 2008)
  • start-msvc10.bat (VS 2010) 
Step 2 - Downloading the source code:

Run these commands to download the source code and move to the folder:

hg clone http://hg.mozilla.org/mozilla-central/ src

cd src

Step 3 - Building:

Create the config file and build the code by running these commands:

echo '. $topsrcdir/browser/config/mozconfig' > .mozconfig
echo 'mk_add_options AUTOCONF=autoconf2.13' >> .mozconfig
make -f client.mk build

Step 4 - Running you build

Navigate to ~/src/obj/dist/bin/firefox.exe to run your new build

Comicbook.js - Release 0.2

My initial plans after 0.1 of completing the halftone/duotone effect hasn't gone the way I had hoped. Trying to create it on my own has been extremely difficult, so I went to Dave Humphrey for some advice. He introduced me to the Close Pixelate library which creates various pixelation effects on still images:



These effects are partially what I was trying to accomplish. As a result my 0.2 goal became combining close-pixelate.js with video/canvas. You can view my demo here.

There are a few problems that need to be solved for my next release. First is optimizing the code, when a couple or more effects are used it creates a lot of lag due to several nested for loops doing a huge number of canvas drawing. Second is working on the halftone/duotone effect.

I'll also be working with Kenneth Pangilinan on including these effects in Candy.js.