CINXE.COM

Patch Review

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta property="og:type" content="website"> <meta property="og:title" content="Patch Review"> <meta property="og:url" content="https://bugzilla.mozilla.org/show_bug.cgi?id=505115"> <meta property="og:description" content="VERIFIED (matt.woodrow) in Core - CSS Parsing and Computation. Last updated 2015-11-12."> <meta name="twitter:label1" value="Type"> <meta name="twitter:data1" value="enhancement"> <meta name="twitter:label2" value="Priority"> <meta name="twitter:data2" value="--"> <meta name="viewport" content="width=1024"> <meta name="color-scheme" content="dark light"> <meta name="generator" content=" 20241126.1"> <meta name="bugzilla-global" content="dummy" id="bugzilla-global" data-bugzilla="{&quot;api_token&quot;:&quot;&quot;,&quot;config&quot;:{&quot;basepath&quot;:&quot;\/&quot;},&quot;constant&quot;:{&quot;COMMENT_COLS&quot;:80},&quot;param&quot;:{&quot;maxattachmentsize&quot;:&quot;10240&quot;,&quot;maxusermatches&quot;:&quot;50&quot;,&quot;splinter_base&quot;:&quot;\/page.cgi?id=splinter.html&amp;ignore=\/&quot;,&quot;use_markdown&quot;:&quot;1&quot;},&quot;string&quot;:{&quot;bug&quot;:&quot;&quot;,&quot;bug_type_required&quot;:&quot;You must select a Type for this &quot;,&quot;component_required&quot;:&quot;You must select a Component for this &quot;,&quot;description_required&quot;:&quot;You must enter a Description for this &quot;,&quot;short_desc_required&quot;:&quot;You must enter a Summary for this &quot;,&quot;version_required&quot;:&quot;You must select a Version for this &quot;},&quot;user&quot;:{&quot;is_new&quot;:true,&quot;login&quot;:&quot;&quot;}}"> <meta name="google-site-verification" content="JYXIuR9cAlV7fLmglSrc_4UaJS6Wzh5Mdxiorqu5AQc" /> <title>Patch Review</title> <link href="/static/v20241126.1/skins/standard/global.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/extensions/Splinter/web/splinter.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/js/jquery/ui/jquery-ui-min.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/js/jquery/ui/jquery-ui-structure-min.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/js/jquery/ui/jquery-ui-theme-min.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/skins/lib/prism.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/extensions/Review/web/styles/badge.css" rel="stylesheet" type="text/css"><link href="/static/v20241126.1/extensions/Review/web/styles/review.css" rel="stylesheet" type="text/css"> <script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/jquery/jquery-min.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/jquery/ui/jquery-ui-min.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/global.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/util.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/widgets.js"></script> <script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT">BUGZILLA.value_descs = JSON.parse('{\"bug_status\":{},\"resolution\":{\"\":\"---\"}}'); review_suggestions = { _mentors: [ ], 'CSS Parsing and Computation': [ ], _end: 1 }; static_component = 'CSS Parsing and Computation'; </script> <script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/extensions/Splinter/web/splinter.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/field.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/data-table.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/lib/prism.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/extensions/GoogleAnalytics/web/js/analytics.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/js/lib/md5.min.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/extensions/Review/web/js/badge.js"></script><script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT" src="/static/v20241126.1/extensions/Review/web/js/review.js"></script> <link href="/static/v20241126.1/skins/lib/fontawesome.min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/lib/fontawesome-brands.min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/lib/fontawesome-solid.min.css" rel="stylesheet" type="text/css"> <link rel="search" type="application/opensearchdescription+xml" title="Bugzilla@Mozilla" href="/search_plugin.cgi"><link rel="shortcut icon" href="/extensions/BMO/web/images/favicon.ico"> <link rel="canonical" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505115"> <link rel="shorturl" href="https://bugzilla.mozilla.org/505115"><meta name="google-analytics" content="UA-36116321-3" data-location="https://bugzilla.mozilla.org/pages/splinter" data-title="Patch Review"> <script async src="https://www.google-analytics.com/analytics.js"></script><meta name="robots" content="noarchive"> </head> <body class="bugzilla-mozilla-org skin-standard"> <div id="wrapper"> <header id="header" role="banner" aria-label="Global Header"> <div class="inner" role="none"> <button type="button" class="iconic ghost" id="open-menu-drawer" aria-label="Open Site Menu"> <span class="icon" aria-hidden="true" data-icon="menu"></span> </button><div id="header-external-links" class="dropdown" role="none"> <button type="button" id="header-external-menu-button" class="dropdown-button minor" aria-label="Show Mozilla Menu" aria-expanded="false" aria-haspopup="true" aria-controls="header-external-menu"> <img src="/static/v20241126.1/extensions/BMO/web/images/moz-fav-one-color-white-rgb.svg" width="32" height="32" alt=""> </button> <ul class="dropdown-content right" id="header-external-menu" role="menu" aria-label="Mozilla Menu" style="display:none;"> <li role="none"> <a href="https://www.mozilla.org/" role="menuitem"> <span class="label" role="none">Mozilla Home</span> </a> </li> <li role="separator"></li> <li role="none"> <a href="https://www.mozilla.org/privacy/websites/" role="menuitem"> <span class="label" role="none">Privacy</span> </a> </li> <li role="none"> <a href="https://www.mozilla.org/privacy/websites/#cookies" role="menuitem"> <span class="label" role="none">Cookies</span> </a> </li> <li role="none"> <a href="https://www.mozilla.org/about/legal/" role="menuitem"> <span class="label" role="none">Legal</span> </a> </li> </ul> </div> <h1 id="header-title" class="title" role="none"> <a class="header-button" href="https://bugzilla.mozilla.org/home" title="Go to home page"> <span aria-label="Go to Bugzilla Home Page">Bugzilla</span> </a> </h1> <form id="header-search" class="quicksearch" action="/buglist.cgi" data-no-csrf role="search" aria-label="Search Bugs"> <button type="button" class="iconic ghost" id="show-searchbox" aria-label="Search Bugs"> <span class="icon" aria-hidden="true" data-icon="search"></span> </button> <div class="searchbox-outer dropdown" role="combobox" aria-label="Quick Search" aria-haspopup="listbox" aria-owns="header-search-dropdown" aria-expanded="false"> <span class="icon" aria-hidden="true" data-icon="search"></span> <input id="quicksearch_top" class="dropdown-button" name="quicksearch" autocomplete="off" value="" accesskey="s" placeholder="Search Bugs" title="Enter a bug number or some search terms" role="searchbox" aria-controls="header-search-dropdown" aria-label="Search Terms"><div id="header-search-dropdown" class="dropdown-content dropdown-panel right" role="listbox" style="display: none;"> <div id="header-search-dropdown-wrapper" role="none"> <section id="header-search-dropdown-help" role="group" aria-label="Help"> <footer role="none"> <a href="/page.cgi?id=quicksearch.html">Quick Search Tips</a> <a href="/query.cgi?format=advanced">Advanced Search</a> </footer> </section> </div> </div> </div> </form> <nav id="header-nav" role="menubar" aria-label="Site Links"> <ul class="links" role="none"><li role="none"> <a class="header-button" href="/describecomponents.cgi" title="Browse bugs by component" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="category"></span> <span class="label" role="none">Browse</span> </a> </li> <li role="none"> <a class="header-button" href="/query.cgi?format=advanced" title="Search bugs using various criteria" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="pageview"></span> <span class="label" role="none">Advanced Search</span> </a> </li> <li role="none"> <a class="header-button" href="/enter_bug.cgi" title="File a new bug" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="add_box"></span> <span class="label" role="none">New Bug</span> </a> </li> </ul> <div class="dropdown" role="none"> <button type="button" id="header-tools-menu-button" class="header-button dropdown-button minor" title="More tools…" role="menuitem" aria-label="Show More Tools Menu" aria-expanded="false" aria-haspopup="true" aria-controls="header-tools-menu"> <span class="icon" aria-hidden="true" data-icon="more_horiz"></span> </button> <ul class="dropdown-content left" id="header-tools-menu" role="menu" aria-label="More Tools Menu" style="display:none;"><li role="none"> <a href="/report.cgi" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="analytics"></span> <span class="label" role="none">Reports</span> </a> </li> <li role="separator"></li> <li role="none"> <a href="https://bmo.readthedocs.io/en/latest/" target="_blank" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="help"></span> <span class="label" role="none">Documentation</span> </a> </li> </ul> </div> </nav> <ul id="header-login" class="links" role="none"><li id="mini_login_container_top" role="none"> <a id="login_link_top" href="/index.cgi?GoAheadAndLogIn=1" class='show_mini_login_form header-button' data-qs-suffix="_top" role="button"> <span class="icon" aria-hidden="true" data-icon="login"></span> <span class="label" role="none">Log In</span> </a> <div id="mini_login_top" class="mini-popup mini_login bz_default_hidden"> <form method="post" action="/github.cgi"> <input type="hidden" name="github_token" value="Y2PYRL5P9ZgTrBr4WFYbI1LfL4lR13qtrGWuGCH68llJZGFt8oQcJboBc6ZNMOPqZCyuMJPqZ2wbF8cemrRmxIhDl2M1A3iNOnYMhd3RcIXCa1AcOq3GBkiurSrejvo7NKkGlUdVFrI6qtw14ATmJVzA6fkAGgJoKa2yD4KW7Qy0bGn0CEcneIVJcCokRytA12hWXMGhCHD9Owaor0aippcuJ3k4IaqM3BVUqJHbYr1diO91us8JezNldpzFhHtz"> <input type="hidden" name="target_uri" value="https://bugzilla.mozilla.org/page.cgi"> <button type="submit"> <i class="fab fa-github"></i> Log In with GitHub </button> </form> <div class="method-separator">or</div> <form action="/page.cgi?id=splinter.html&amp;ignore=&amp;bug=505115&amp;attachment=525557" method="POST" data-qs-suffix="_top"> <input id="Bugzilla_login_top" class="bz_login" name="Bugzilla_login" title="Login" placeholder="Email" aria-label="Email" type="email" required > <input class="bz_password" id="Bugzilla_password_top" name="Bugzilla_password" type="password" title="Password" placeholder="Password" aria-label="Password" required > <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" id="Bugzilla_password_dummy_top" value="password" title="Password" > <span class="remember-outer"> <input type="checkbox" id="Bugzilla_remember_top" name="Bugzilla_remember" value="on" class="bz_remember" checked> <label for="Bugzilla_remember_top">Remember me</label> </span> <input type="hidden" name="Bugzilla_login_token" value="1732721905-9FM-cBGVUencreePxHCt9t1T59osgXP9ao8BXHcnRio"> <input type="submit" name="GoAheadAndLogIn" value="Log In" id="log_in_top" class="check_mini_login_fields" data-qs-suffix="_top"> <a href="#" id="hide_mini_login_top" aria-label="Close" class="close-button hide_mini_login_form" data-qs-suffix="_top"> <span class="icon" aria-hidden="true"></span> </a> </form> <div class="footer"> <a href="/createaccount.cgi">Create an Account</a> &middot; <a id="forgot_link_top" href="/index.cgi?GoAheadAndLogIn=1#forgot" class='show_forgot_form' data-qs-suffix="_top">Forgot Password</a> </div> </div> <div id="forgot_form_top" class="mini-popup mini_forgot bz_default_hidden"> <form action="/token.cgi" method="post"> <input type="email" name="loginname" size="20" placeholder="Email" aria-label="Email" required> <input id="forgot_button_top" value="Reset Password" type="submit"> <input type="hidden" name="a" value="reqpw"> <input type="hidden" id="token_top" name="token" value="1732721905-nD0INy0aFioBMEVaJGP3ErEA-S4DTRVB4h5WLRxg1TQ"> <a href="#" class="close-button hide_forgot_form" aria-label="Close" data-qs-suffix="_top"> <span class="icon" aria-hidden="true"></span> </a> </form> </div> </li> </ul> </div> <dialog id="menu-drawer" inert aria-label="Site Menu"> <div class="drawer-inner" role="none"> <div class="header" role="none"> <button type="button" class="iconic ghost" id="close-menu-drawer" aria-label="Close Site Menu"> <span class="icon" aria-hidden="true" data-icon="close"></span> </button> </div> <ul role="menu" aria-label="Site Links"><li role="none"> <a class="header-button" href="/describecomponents.cgi" title="Browse bugs by component" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="category"></span> <span class="label" role="none">Browse</span> </a> </li> <li role="none"> <a class="header-button" href="/query.cgi?format=advanced" title="Search bugs using various criteria" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="pageview"></span> <span class="label" role="none">Advanced Search</span> </a> </li> <li role="none"> <a class="header-button" href="/enter_bug.cgi" title="File a new bug" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="add_box"></span> <span class="label" role="none">New Bug</span> </a> </li><li role="none"> <a href="/report.cgi" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="analytics"></span> <span class="label" role="none">Reports</span> </a> </li> <li role="separator"></li> <li role="none"> <a href="https://bmo.readthedocs.io/en/latest/" target="_blank" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="help"></span> <span class="label" role="none">Documentation</span> </a> </li> </ul> </div> </dialog> </header> <main id="bugzilla-body" tabindex="-1"> <aside id="message-container" role="complementary"> <noscript> <div class="noscript"> <div class="inner"> <p>Please enable JavaScript in your browser to use all the features on this site.</p> </div> </div> </noscript> </aside> <div id="main-inner"> <script nonce="uL2uvJq7kY2Lz131PFkBxMO1eeTcas7vBgH9iI5tTnU0nyrT"> Splinter.configBase = 'https:\/\/bugzilla.mozilla.org\/page.cgi?id=splinter.html&ignore='; Splinter.configBugUrl = '\/'; Splinter.configHaveExtension = true; Splinter.configHelp = '\/page.cgi?id=splinter/help.html'; Splinter.configNote = ''; Splinter.readOnly = 0 == 0; Splinter.configAttachmentStatuses = [ ]; Splinter.bugId = Splinter.Utils.isDigits('505115') ? parseInt('505115') : NaN; Splinter.attachmentId = Splinter.Utils.isDigits('525557') ? parseInt('525557') : NaN; if (!isNaN(Splinter.bugId)) { var theBug = new Splinter.Bug.Bug(); theBug.id = parseInt('505115'); theBug.token = ''; theBug.shortDesc = Splinter.Utils.strip('CSS3 3D-Transforms'); theBug.creationDate = Splinter.Bug.parseDate('2009-07-19 09:22:56 -0700'); theBug.reporterEmail = Splinter.Utils.strip('jypenator\x40gmail.com'); theBug.reporterName = Splinter.Utils.strip('Jean-Yves Perrier [:teoli]'); Splinter.attachmentComment = 'Fixed bitrot.'; var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-02 18:40:50 -0700'); comment.text = 'Review of attachment 537016:\n-----------------------------------------------------------------'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-02 18:41:52 -0700'); comment.text = 'Review of attachment 537018:\n-----------------------------------------------------------------'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-02 18:43:17 -0700'); comment.text = 'Review of attachment 537019:\n-----------------------------------------------------------------\n\n::: gfx\/thebes\/gfx3DPoint.h\n\x40\x40 +101,5 \x40\x40\n\x3e + *this \/= Length();\n\x3e + }\n\x3e +};\n\x3e +\n\x3e +#endif \/* GFX_3DPOINT_H *\/ \n\\ No newline at end of file\n\nDoes it make sense to make a Base3DPoint class like BasePoint, and instantiate it here for gfx3DPoint? I think it probably does.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-13 15:55:18 -0700'); comment.text = 'Review of attachment 538995:\n-----------------------------------------------------------------\n\nLet\'s break this patch up into the 3DVector stuff, the matrix changes, and the layout changes.\n\nFor Base3DVector, \"3D\" should be last in the name for consistency with Azure and because we can\'t use 3DVector as a class name.\n\nAlso, per discussion on IRC this should be BasePoint3D. We\'ll have to review it carefully to keep the API as consistent with BasePoint as makes sense.\n\n::: gfx\/src\/Base3DVector.h\n\x40\x40 +124,5 \x40\x40\n\x3e + return sqrt(x*x + y*y + z*z);\n\x3e + }\n\x3e +\n\x3e + void Normalize() {\n\x3e + *this \/= Length();\n\nWhat if Length() is zero? At least document what the behavior is.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-13 16:18:28 -0700'); comment.text = 'Review of attachment 538998:\n-----------------------------------------------------------------\n\nr=me on everything outside of layout\/style, needs dbaron review for the style changes\n\n::: layout\/style\/nsCSSParser.cpp\n\x40\x40 +7524,5 \x40\x40\n\x3e + if (!ParseBoxPositionValues(position, PR_TRUE))\n\x3e + return PR_FALSE;\n\x3e +\n\x3e + PRBool allow3D =\n\x3e + mozilla::Preferences::GetBool(\"layout.3d-transforms.enabled\", PR_FALSE);\n\nI think we should cache this somewhere. Use Preferences::AddBoolVarCache.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-22 14:31:23 -0700'); comment.text = 'Review of attachment 540952:\n-----------------------------------------------------------------\n\n::: gfx\/src\/BasePoint3D.h\n\x40\x40 +62,5 \x40\x40\n\x3e + bool operator==(const Sub& aPoint) const {\n\x3e + return x == aPoint.x && y == aPoint.y && z == aPoint.z;\n\x3e + }\n\x3e + bool operator!=(const Sub& aPoint) const {\n\x3e + return x != aPoint.x || y != aPoint.y || z != aPoint.z;\n\nFor future reference, I usually find it easier and safer to write !(*this == aOther), but you needn\'t bother changing it.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-22 14:54:52 -0700'); comment.text = 'Review of attachment 540953:\n-----------------------------------------------------------------\n\n::: gfx\/thebes\/gfx3DMatrix.h\n\x40\x40 +117,5 \x40\x40\n\x3e + *\/\n\x3e + gfxPoint3D Transform3D(const gfxPoint3D& point) const;\n\x3e +\n\x3e + gfxPoint ProjectPoint(const gfxPoint& aPoint) const;\n\x3e + gfxRect ProjectRect(const gfxRect& aRect) const;\n\nCall this ProjectRectBounds since it takes the bounding rect.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-22 15:16:56 -0700'); comment.text = 'Review of attachment 540954:\n-----------------------------------------------------------------\n\n::: layout\/base\/nsLayoutUtils.h\n\x40\x40 +512,5 \x40\x40\n\x3e + \n\x3e +\n\x3e + static nsRect InvertRectToAncestor(nsIFrame* aFrame,\n\x3e + const nsRect& aRect,\n\x3e + nsIFrame* aStopAtAncestor);\n\nInvertRectToAncestorBounds? InvertRectBoundsToAncestor?\n\nWhy not just TransformRectToBoundsInAncestor?'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-22 15:38:35 -0700'); comment.text = 'Review of attachment 540959:\n-----------------------------------------------------------------\n\n::: layout\/base\/nsDisplayList.cpp\n\x40\x40 +2389,5 \x40\x40\n\x3e + }\n\x3e + \n\x3e + \/* Default position of perspective-origin is in the centre of the element *\/\n\x3e + result.x -= NSAppUnitsToFloatPixels(boundingRect.width, aFactor)\/2;\n\x3e + result.y -= NSAppUnitsToFloatPixels(boundingRect.height, aFactor)\/2;\n\nThis seems wrong. The initial value of the property is 50% 50%, and this should be what\'s in \"display\" by default, so why do we need to calculate it again?\n\n\x40\x40 +2394,5 \x40\x40\n\x3e +\n\x3e + result.x = -result.x;\n\x3e + result.y = -result.y;\n\x3e +\n\x3e + return result;\n\nreturn -result;'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-06-23 14:09:44 -0700'); comment.text = 'Review of attachment 540959:\n-----------------------------------------------------------------'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-07-31 17:25:32 -0700'); comment.text = 'Review of attachment 548080:\n-----------------------------------------------------------------\n\nInstead of exposing whether 3D transforms are enabled, how about just making the tests conditional on GPU acceleration enabled (for now)?\n\n::: layout\/reftests\/transform-3d\/reftest.list\n\x40\x40 +23,5 \x40\x40\n\x3e +== rotate3d-2a.html rotatey-1-ref.html\n\x3e +!= backface-visibility-1a.html about:blank\n\x3e +fails-if(!transforms3d) == backface-visibility-1b.html about:blank\n\x3e +fails-if(!transforms3d) != perspective-origin-1a.html rotatex-perspective-1a.html\n\x3e +== perspective-origin-1b.html perspective-origin-1a.html\n\nCan you put these in alphabetical order?'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-07-31 17:53:43 -0700'); comment.text = 'Review of attachment 548084:\n-----------------------------------------------------------------\n\n::: layout\/base\/nsDisplayList.cpp\n\x40\x40 +2441,4 \x40\x40\n\x3e {\n\x3e NS_PRECONDITION(aFrame, \"Cannot get transform matrix for a null frame!\");\n\x3e + \/\/NS_PRECONDITION(aFrame-\x3eGetStyleDisplay()-\x3eHasTransform(),\n\x3e + \/\/ \"Cannot get transform matrix if frame isn\'t transformed!\");\n\nJust remove this\n\n\x40\x40 +2446,5 \x40\x40\n\x3e + if (aOutAncestor) {\n\x3e + *aOutAncestor = aFrame-\x3eGetParent();\n\x3e + }\n\x3e +\n\x3e + if (!aFrame-\x3eGetStyleDisplay()-\x3eHasTransform()) {\n\nAdd comment that this is the preserve-3d case\n\n\x40\x40 +2476,5 \x40\x40\n\x3e + aFrame-\x3ePresContext(),\n\x3e + dummy, bounds, aFactor);\n\x3e + } else {\n\x3e + NS_ASSERTION(aFrame-\x3ePreserves3DChildren(), \n\x3e + \"If we don\'t have a transform, then we must be at least preserving transforms of our children\");\n\nShouldn\'t this be asserting aFrame-\x3ePreserves3D?\n\n\x40\x40 +2776,5 \x40\x40\n\x3e const nsRect* aBoundsOverride)\n\x3e {\n\x3e NS_PRECONDITION(aFrame, \"Can\'t take the transform based on a null frame!\");\n\x3e + \/\/NS_PRECONDITION(aFrame-\x3eGetStyleDisplay()-\x3eHasTransform(),\n\x3e + \/\/ \"Cannot transform a rectangle if there\'s no transformation!\");\n\nJust remove this, and the ones below\n\n::: layout\/generic\/nsFrame.cpp\n\x40\x40 +1431,5 \x40\x40\n\x3e + nsresult rv = NS_OK;\n\x3e + nsDisplayList newList;\n\x3e + while (nsDisplayItem *item = aList-\x3eRemoveBottom()) {\n\x3e + if (item-\x3eGetType() == nsDisplayItem::TYPE_TRANSFORM && item-\x3eGetUnderlyingFrame()-\x3eGetParent()-\x3ePreserves3DChildren()) {\n\x3e + NS_ASSERTION(item-\x3eGetUnderlyingFrame()-\x3ePreserves3D(), \"\");\n\nNeed a message!\n\nBut can\'t this assertion fire if you have a preserves-3D parent with a child that has a transform but also a clip?\n\n\x40\x40 +1481,5 \x40\x40\n\x3e *\/\n\x3e if ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&\n\x3e disp-\x3eHasTransform()) {\n\x3e \/* If we have a complex transform, just grab the entire overflow rect instead. *\/\n\x3e + if (Preserves3DChildren() || GetParent()-\x3ePreserves3DChildren() || !nsDisplayTransform::UntransformRect(dirtyRect, this, nsPoint(0, 0), &dirtyRect)) {\n\nJust call Preserves3D() here?\n\n\x40\x40 +1560,5 \x40\x40\n\x3e resultList.AppendToTop(set.BlockBorderBackgrounds());\n\x3e \/\/ 5: floats\n\x3e resultList.AppendToTop(set.Floats());\n\x3e \/\/ 7: general content\n\x3e + set.Content()-\x3eSortByZPosition(aBuilder, GetContent());\n\nHmm, this is a little bit scary. Maybe make this if (Preserves3DChildren())? And maybe instead of calling SortByZPosition and having SortByZPosition account for 3D, use a separate SortByZPosition3D path which you use here?\n\n\x40\x40 +4534,5 \x40\x40\n\x3e * See bug #452496 for more details.\n\x3e *\/\n\x3e +\n\x3e + \/\/ Check the transformed flags and remove it\n\x3e + PRBool isTransformed = (aFlags & INVALIDATE_ALREADY_TRANSFORMED);\n\n\"rectIsTransformed\" to be clearly different from IsTransformed()?\n\n\x40\x40 +4601,5 \x40\x40\n\x3e \n\x3e \/* If we\'re transformed, the matrix will be relative to our\n\x3e * cross-doc parent frame.\n\x3e *\/\n\x3e + \/\/*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(this);\n\nRemove\n\n\x40\x40 +6670,5 \x40\x40\n\x3e + }\n\x3e + } else {\n\x3e + \/\/ When we are preserving 3d we need to iterate over all children separately.\n\x3e + \/\/ If the child also preserves 3d then their overflow will already been in our\n\x3e + \/\/ coordinate space, otherwise we need to transform.\n\nMove this code to a helper function? FinishAndStoreOverflow is already a bit long :-)\n\n::: layout\/generic\/nsIFrame.h\n\x40\x40 +1192,5 \x40\x40\n\x3e \/**\n\x3e + * Returns whether this frame will attempt to preserve the 3d transforms of its\n\x3e + * children. This is a direct indicator of -moz-transform-style: preserve-3d.\n\x3e + *\/\n\x3e + virtual PRBool Preserves3DChildren() const;\n\nDoesn\'t need to be virtual?\n\n\x40\x40 +1195,5 \x40\x40\n\x3e + *\/\n\x3e + virtual PRBool Preserves3DChildren() const;\n\x3e +\n\x3e + \/**\n\x3e + * Returns whether this child frame will preserve 3d transforms.\n\nNeeds a better comment to distinguish it from the previous method.\n\n\x40\x40 +1197,5 \x40\x40\n\x3e +\n\x3e + \/**\n\x3e + * Returns whether this child frame will preserve 3d transforms.\n\x3e + *\/\n\x3e + virtual PRBool Preserves3D() const;\n\nDoesn\'t need to be virtual?'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Robert O\'Callahan (:roc) (email my personal email if necessary)'); comment.whoEmail = Splinter.Utils.strip('roc\x40ocallahan.org'); comment.date = Splinter.Bug.parseDate('2011-08-07 17:29:38 -0700'); comment.text = 'Review of attachment 551300:\n-----------------------------------------------------------------\n\nSomewhere you need a comment or two to explain the general setup: how preserve-3d transforms are applied to the display list (in BuildDisplayListForStackingContext, I guess), and how invalidation is handled (in Invalidate somewhere).\n\n::: layout\/base\/nsDisplayList.cpp\n\x40\x40 +772,5 \x40\x40\n\x3e + nsIFrame* ancestor;\n\x3e + gfx3DMatrix matrix1 = aItem1-\x3eGetUnderlyingFrame()-\x3eGetTransformMatrix(&ancestor);\n\x3e + gfx3DMatrix matrix2 = aItem2-\x3eGetUnderlyingFrame()-\x3eGetTransformMatrix(&ancestor);\n\x3e +\n\x3e + return matrix1._43 \x3c matrix2._43;\n\nIf these are equal, we should check IsContentLEQ, right?\n\n::: layout\/generic\/nsFrame.cpp\n\x40\x40 +1444,5 \x40\x40\n\x3e +{\n\x3e + nsresult rv = NS_OK;\n\x3e + nsDisplayList newList;\n\x3e + while (nsDisplayItem *item = aList-\x3eRemoveBottom()) {\n\x3e + if (item-\x3eGetType() == nsDisplayItem::TYPE_TRANSFORM && item-\x3eGetUnderlyingFrame()-\x3eGetParent()-\x3ePreserves3DChildren()) {\n\nHow about check item-\x3eGetUnderlyingFrame() not null, then check item-\x3eGetUnderlyingFrame()-\x3eGetParent()-\x3ePreserves3DChildren(), then switch on item-\x3eGetType()?\n\n\x40\x40 +1445,5 \x40\x40\n\x3e + nsresult rv = NS_OK;\n\x3e + nsDisplayList newList;\n\x3e + while (nsDisplayItem *item = aList-\x3eRemoveBottom()) {\n\x3e + if (item-\x3eGetType() == nsDisplayItem::TYPE_TRANSFORM && item-\x3eGetUnderlyingFrame()-\x3eGetParent()-\x3ePreserves3DChildren()) {\n\x3e + NS_ASSERTION(item-\x3eGetUnderlyingFrame()-\x3ePreserves3D(), \"\");\n\nNeed a message.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Timothy B. Terriberry (:derf)'); comment.whoEmail = Splinter.Utils.strip('tterribe\x40vt.edu'); comment.date = Splinter.Bug.parseDate('2011-08-10 19:16:55 -0700'); comment.text = 'Review of attachment 548634:\n-----------------------------------------------------------------\n\nSo, the operator[] issues, the order of translation in Inverse(), the left-over debugging code, and the MAX macro in a header must be fixed. The rest are suggestions you can take or leave as you like.\n\n::: gfx\/2d\/BasePoint3D.h\n\x40\x40 +68,5 \x40\x40\n\x3e + return y;\n\x3e + } else {\n\x3e + return z;\n\x3e + }\n\x3e + }\n\nThis function made me throw up in my mouth a little. Just saying.\n\n::: gfx\/2d\/BasePoint4D.h\n\x40\x40 +72,5 \x40\x40\n\x3e + Sub operator+(const Sub& aPoint) const {\n\x3e + return Sub(x + aPoint.x, y + aPoint.y, z + aPoint.z, w + aPoint.w);\n\x3e + }\n\x3e + Sub operator-(const Sub& aPoint) const {\n\x3e + return Sub(x - aPoint.x, y - aPoint.y, z - aPoint.z, w + aPoint.w);\n\nShould be w - aPoint.w, not +.\n\n::: gfx\/2d\/Makefile.in\n\x40\x40 +51,5 \x40\x40\n\x3e EXPORTS_mozilla\/gfx = \\\n\x3e 2D.h \\\n\x3e BasePoint.h \\\n\x3e BasePoint3D.h \\\n\x3e + BasePoint4D.h \\\n\nYou\'re using tabs here when the rest of the list (except the $(NULL) line) isn\'t.\n\n::: gfx\/thebes\/gfx3DMatrix.cpp\n\x40\x40 +114,5 \x40\x40\n\x3e return *this;\n\x3e }\n\x3e \n\x3e +gfxPointH3D&\n\x3e +gfx3DMatrix::operator[](const int aIndex)\n\nIs there any reason to declare aIndex const?\n\n\x40\x40 +118,5 \x40\x40\n\x3e +gfx3DMatrix::operator[](const int aIndex)\n\x3e +{\n\x3e + NS_ABORT_IF_FALSE(aIndex \x3e= 0 && aIndex \x3c= 3, \"Invalid matrix array index\");\n\x3e + if (aIndex == 0) {\n\x3e + return *reinterpret_cast\x3cgfxPointH3D*\x3e(&_11);\n\nSo, this kind of thing is technically invalid, though I don\'t know a compiler\/architecture combination where it will actually break.\n\nThe only way to guarantee, at a language level, that a series of memory cells are adjacent in memory, with no padding for alignment or whatever else between them, is to put them in an array.\n\nHowever, if you\'re going to rely on _11 through _14 being adjacent in memory, why not rely on _11 through _44 being adjacent? Then you can get rid of the if\/else chain and just use\n\n return *reinterpret_cast\x3cgfxPointH3D*\x3e((&_11)+4*aIndex);\n\ndirectly, and the whole thing can go in the header so it can be inlined, as it becomes basically one lea instruction on x86. A similar approach will eliminate the if\/else chain in BasePoint[34]D and even in TransposedVector()\/SetTransposedVector(). That at least has the advantage of generating reasonable code, while the current construction will create surprisingly slow code for some future caller that naively expects operator[] on a matrix class to be implemented efficiently.\n\nIn other words, if you\'re going to make the assumption these things are tightly packed, then you should actually use that assumption, rather than doing things halfway. Otherwise you\'re relying on loop unrolling to get reasonable code out of things like Normalize() and Transposed() below (looking at the asm, not only does gcc not unroll the loops, it doesn\'t inline the functions that are available to be inlined, either, likely because all the conditionals make them huge).\n\n\x40\x40 +129,5 \x40\x40\n\x3e + }\n\x3e +}\n\x3e +\n\x3e +const gfxPointH3D&\n\x3e +gfx3DMatrix::operator[](const int aIndex) const\n\nIs there any reason to declare aIndex const?\n\n\x40\x40 +249,5 \x40\x40\n\x3e +gfx3DMatrix\n\x3e +gfx3DMatrix::Inverse3x3() const\n\x3e +{\n\x3e + gfxFloat det = Determinant3x3();\n\x3e + if (det == 0.0) {\n\nSo, gfxMatrix::Invert uses cairo_matrix_invert(), which handles singular matrices slightly differently.\n\n1) It also fails if !ISFINITE(det).\n2) Because of the way it is called, the inverse of a singular matrix is (usually) the original singular matrix, rather than the identity. I say \"usually\" because in the simple scaling\/translation case, it inverts the X row before checking to see if the Y row is invertible, but I\'d call that behavior a bug in Cairo (the documentation only says the matrix is modified if the inversion process is successful, and in general it\'s bad form to partially modify things and then return an error). It also doesn\'t check ISFINITE in that case, which is probably another bug.\n\nI don\'t know how important preserving either of these semantics are. Given the aforementioned Cairo bugs, probably not very.\n\n\x40\x40 +264,5 \x40\x40\n\x3e + temp._23 = _13 * _21 - _11 * _23;\n\x3e + temp._31 = _21 * _32 - _22 * _31;\n\x3e + temp._32 = _31 * _12 - _11 * _32;\n\x3e + temp._33 = _11 * _22 - _12 * _21;\n\x3e + temp \/= det;\n\nI recommend temp *= (1\/det).\n\n\x40\x40 +293,5 \x40\x40\n\x3e + *\/\n\x3e + gfx3DMatrix translation;\n\x3e + translation[3] = gfxPointH3D(-_41, -_42, -_43, 1);\n\x3e +\n\x3e + matrix3 = Inverse3x3() * translation;\n\nIs this really correct? I get Inverse[{{a,b,c,0},{d,e,f,0},{g,e,h,0},{x,y,z,1}}] == {{1,0,0,0},{0,1,0,0},{0,0,1,0},{-x,-y,-z,1}}.Inverse[{{a,b,c,0},{d,e,f,0},{g,e,h,0},{0,0,0,1}}]. I.e.,\n\n matrix3 = translation * Inverse3x3();\n\nAlso, the vast majority of these multiplications are by 0 or 1, but because things get stored to memory and then read back, the optimizer is unlikely to eliminate them all. Perhaps it\'s worth expanding them out, e.g.:\n\n matrix3 = Inverse3x3();\n matrix3[3] = gfxPointH3D(-_41*matrix3._11 - _42*matrix3._22 - _43*matrix3._33,\n ...\n\nThat reduces the number of multiplications from 64 to 9. If you opt not to do that, you should still at least use the gfx3DMatrix::Translation() factory, rather than the translation[3] = ... construction you use above.\n\n\x40\x40 +294,5 \x40\x40\n\x3e + gfx3DMatrix translation;\n\x3e + translation[3] = gfxPointH3D(-_41, -_42, -_43, 1);\n\x3e +\n\x3e + matrix3 = Inverse3x3() * translation;\n\x3e + test = PR_TRUE;\n\nSo, this looks like left-over debugging code. In particular, you aren\'t actually returning the inverse you just computed, but are continuing on to compute the full 4x4 inverse.\n\n\x40\x40 +301,3 \x40\x40\n\x3e gfxFloat det = Determinant();\n\x3e if (det == 0.0) {\n\x3e + return gfx3DMatrix();\n\nAh, I see you\'re actually explicitly changing the behavior away from the Cairo behavior (i.e., returning the identity instead of the original, singular matrix). Is there a reason for this? Perhaps it should be documented?\n\n\x40\x40 +356,4 \x40\x40\n\x3e \n\x3e + temp \/= det;\n\x3e +\n\x3e + \/\/NS_ABORT_IF_FALSE(!test || matrix3 == temp, \"AAAAH\");\n\nEither #ifdef this to actually work in debug mode, or remove it entirely. Don\'t just leave it here commented out.\n\n\x40\x40 +407,5 \x40\x40\n\x3e +gfx3DMatrix::Normalize()\n\x3e +{\n\x3e + for (int i = 0; i \x3c 4; i++) {\n\x3e + for (int j = 0; j \x3c 4; j++) {\n\x3e + this-\x3eoperator [](i)[j] \/= this-\x3eoperator [](3)[3];\n\nPerhaps (*this)[i][j] would be cleaner?\n\n\x40\x40 +465,5 \x40\x40\n\x3e + return gfxPointH3D(x, y, z, w);\n\x3e +}\n\x3e +\n\x3e +gfxPointH3D\n\x3e +gfx3DMatrix::Transform4DLeft(const gfxPointH3D& aPoint) const\n\n\"Left\" messes with my head. It\'s correct for OpenGL, where points are column vectors multiplied on the right and the matrix is stored in column-major order, but it\'s backwards for D3D, where points are row vectors multiplied on the left to begin with (and in particular, this is how multiplication is documented to work for the 2D gfxMatrix class).\n\nPerhaps TransposeTransform4D?\n\n::: gfx\/thebes\/gfxQuaternion.h\n\x40\x40 +40,5 \x40\x40\n\x3e +\n\x3e +#include \"mozilla\/gfx\/BasePoint4D.h\"\n\x3e +#include \"gfx3DMatrix.h\"\n\x3e +\n\x3e +#define MAX(a,b) ((a)\x3e(b)?(a):(b))\n\nIt\'s probably not a great idea to put a macro named MAX in a header file like this. I also recommend documenting that it has to return b when a==b, and why. Otherwise someone is likely to replace it with some other MAX implementation and break things without realizing it.\n\n\x40\x40 +67,5 \x40\x40\n\x3e + gfxFloat dot = DotProduct(aOther);\n\x3e + if (dot == 1.0) {\n\x3e + return *this;\n\x3e + }\n\x3e + gfxFloat theta = acos(dot);\n\nRounding errors in the quaternion normalization or dot product could potentially give you a value slightly outside the range [-1,1], which will make acos() return NaN. I recommend clamping dot to that range.\n\n\x40\x40 +70,5 \x40\x40\n\x3e + }\n\x3e + gfxFloat theta = acos(dot);\n\x3e +\n\x3e + gfxQuaternion left = *this;\n\x3e + left *= sin((1 - aCoeff) * theta) \/ sin(theta);\n\nInstead of dividing by sin(theta), it may be better to use\n\n gfxFloat rsintheta = 1\/sqrt(1 - dot*dot);\n\nand then multiply by rsintheta. Square roots, and particularly reciprocal square roots, are much easier to compute.\n\n\x40\x40 +73,5 \x40\x40\n\x3e + gfxQuaternion left = *this;\n\x3e + left *= sin((1 - aCoeff) * theta) \/ sin(theta);\n\x3e +\n\x3e + gfxQuaternion right = aOther;\n\x3e + right *= sin(aCoeff * theta) \/ sin(theta);\n\nYou can also replace the remaining two calls to sin() with a call to sin() and cos() on the same angle (which is faster on many platforms). E.g., using the identity\n sin((1 - aCoeff) * theta)\/sin(theta)\n == sin(theta - aCoeff*theta)\/sin(theta)\n == (sin(theta)*cos(aCoeff*theta) - cos(theta)*sin(aCoeff*theta))\/sin(theta)\n == sin(theta)*cos(aCoeff*theta)\/sin(theta) - cos(theta)*sin(aCoeff*theta)\/sin(theta)\n == cos(aCoeff*theta) - dot*sin(aCoeff*theta)\/sin(theta)\n leads to the code:\n\ngfxFloat w = sin(aCoeff*theta)*rsintheta;\n\nleft *= cos(aCoeff*theta) - dot*w;\nright *= w;\n\n\x40\x40 +89,5 \x40\x40\n\x3e + temp[1][1] = 1 - (2 * x * x) - (2 * z * z);\n\x3e + temp[1][2] = (2 * y * z) + (2 * w * x);\n\x3e + temp[2][0] = (2 * x * z) + (2 * w * y);\n\x3e + temp[2][1] = (2 * y * z) - (2 * w * x);\n\x3e + temp[2][2] = 1 - (2 * x * x) - (2 * y * y);\n\nRecommend factoring out the 2\'s in each term, to save 9 multiplies, e.g.,\n\n temp[0][0] = 1 - 2*(y * y - z * z);\n\nThe compiler is generally conservative about doing such optimizations for you unless you compile with -ffast-math or an equivalent.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Timothy B. Terriberry (:derf)'); comment.whoEmail = Splinter.Utils.strip('tterribe\x40vt.edu'); comment.date = Splinter.Bug.parseDate('2011-08-10 19:20:15 -0700'); comment.text = 'Review of attachment 548635:\n-----------------------------------------------------------------\n\nr+ with some suggestions, but I did not review the style stuff carefully, as I\'m relying on the fact that dbaron knows that code much better than I do.\n\n::: gfx\/2d\/BasePoint4D.h\n\x40\x40 +72,5 \x40\x40\n\x3e Sub operator+(const Sub& aPoint) const {\n\x3e return Sub(x + aPoint.x, y + aPoint.y, z + aPoint.z, w + aPoint.w);\n\x3e }\n\x3e Sub operator-(const Sub& aPoint) const {\n\x3e + return Sub(x - aPoint.x, y - aPoint.y, z - aPoint.z, w - aPoint.w);\n\nYou should just fix this in Part 15, not here.\n\n::: layout\/style\/nsStyleAnimation.cpp\n\x40\x40 +1115,5 \x40\x40\n\x3e \n\x3e float scaleY = sqrt(C * C + D * D);\n\x3e C \/= scaleY;\n\x3e D \/= scaleY;\n\x3e +\n\nWhitespace-only change.\n\n\x40\x40 +1120,4 \x40\x40\n\x3e XYshear \/= scaleY;\n\x3e \n\x3e + \/\/ A*D - B*C should now be 1 or -1\n\x3e + NS_ASSERTION(0.99 \x3c PR_ABS(A*D - B*C) && PR_ABS(A*D - B*C) \x3c 1.01,\n\nWhy the change from NS_ABS to PR_ABS? There\'s plenty of other uses of NS_ABS that you didn\'t change.\n\n\x40\x40 +1147,5 \x40\x40\n\x3e +static PRBool\n\x3e +Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,\n\x3e + float aShear[3], gfx3DMatrix &aRotate,\n\x3e + gfxPoint3D &aTranslate, gfxPointH3D &aPerspective)\n\x3e +{\n\nThis is a pretty straightforward translation of the code from http:\/\/dev.w3.org\/csswg\/css3-2d-transforms\/#unmatrix to our C++ API, except you dropped all the comments from the original code. It would be nice if you could preserve those. Referencing that link would be a good idea, too.\n\n\x40\x40 +1194,5 \x40\x40\n\x3e + row[i].z = local[i].z;\n\x3e + }\n\x3e +\n\x3e + aScale.x = row[0].Length();\n\x3e + row[0].Normalize();\n\nYou just computed Length(), but Normalize() will compute it again internally. Recommend just dividing by the length you already computed. Ditto for the other two occurrences below.\n\n\x40\x40 +1197,5 \x40\x40\n\x3e + aScale.x = row[0].Length();\n\x3e + row[0].Normalize();\n\x3e + \n\x3e + aShear[XYSHEAR] = row[0].DotProduct(row[1]);\n\x3e + row[1] += row[0] * -aShear[XYSHEAR];\n\nrow[1] -= row[0] * aShear[XYSHEAR] perhaps? Ditto for the other two lines below.\n\n\x40\x40 +1224,5 \x40\x40\n\x3e +\n\x3e + for (int i =0; i \x3c 3; i++) {\n\x3e + aRotate[i] = gfxPointH3D(row[i].x, row[i].y, row[i].z, 0);\n\x3e + }\n\x3e + aRotate[3] = gfxPointH3D(0, 0, 0, 1);\n\nIs it really worth breaking out local into row[]? Operating on the rows of local directly would add 15 FMA\'s (assuming I can count), but the copies add 18 loads\/stores, not counting loop overhead, and a bunch of code.\n\n\x40\x40 +1310,4 \x40\x40\n\x3e \n\x3e + gfxPointH3D perspective = \n\x3e + InterpolateNumerically(perspective1, perspective2, aProgress);\n\x3e + if (perspective != gfxPointH3D(0, 0, 0, 1)) {\n\nWhat\'s the point of this check? Can\'t we just write perspective into result unconditionally? It would seem cheaper to always do that than to even do this test. I\'m dubious about the utility of some of the other checks below, as well.\n\n\x40\x40 +1317,5 \x40\x40\n\x3e + gfxPoint3D translate = \n\x3e + InterpolateNumerically(translate1, translate2, aProgress);\n\x3e + if (translate != gfxPoint3D(0, 0, 0)) {\n\x3e + gfx3DMatrix temp = gfx3DMatrix::Translation(translate);\n\x3e + result = temp * result;\n\nAs in the last patch, you can reduce this from 64 multiplies to 9. Perhaps you should just add a function for it to gfx3DMatrix?\n\n\x40\x40 +1322,5 \x40\x40\n\x3e + }\n\x3e +\n\x3e + gfxQuaternion q1(rotate1);\n\x3e + gfxQuaternion q2(rotate2);\n\x3e + gfxQuaternion q3 = q1.Slerp(q2, aProgress);\n\nPerhaps it would be better to have Decompose3DMatrix return a gfxQuaternion directly. Especially combined with the suggestion to just keep things in \"local\", it would avoid copying everything from local to aRotate at the end.\n\n\x40\x40 +1335,5 \x40\x40\n\x3e + InterpolateNumerically(shear1[YZSHEAR], shear2[YZSHEAR], aProgress);\n\x3e + if (yzshear != 0.0) {\n\x3e + gfx3DMatrix temp;\n\x3e + temp._32 = yzshear;\n\x3e + result = temp * result;\n\nThis can also be reduced to result[2] += yzshear*result[1], going from 64 multiplies to 4 and 3 lines of code to 1.\n\n\x40\x40 +1358,5 \x40\x40\n\x3e + gfxPoint3D scale = \n\x3e + InterpolateNumerically(scale1, scale2, aProgress);\n\x3e + if (scale != gfxPoint3D(1.0, 1.0, 1.0)) {\n\x3e + gfx3DMatrix temp = gfx3DMatrix::Scale(scale.x, scale.y, scale.z);\n\x3e + result = temp * result;\n\nThis can also be reduced from 64 multiplies to 12, though it requires 3 lines of code instead of 2.\n\n\x40\x40 +1576,4 \x40\x40\n\x3e \n\x3e \/\/ FIXME: If the matrix contains only numbers then we could decompose\n\x3e \/\/ here. We can\'t do this for matrix3d though, so it\'s probably\n\x3e \/\/ best to stay consistent.\n\nI\'m not sure that the second sentence here is true any longer. Certainly doing the decomposition once instead of for every step of the animation would save more computation than basically all of the other optimizations I pointed out combined.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Timothy B. Terriberry (:derf)'); comment.whoEmail = Splinter.Utils.strip('tterribe\x40vt.edu'); comment.date = Splinter.Bug.parseDate('2011-08-25 22:13:01 -0700'); comment.text = 'Review of attachment 553086:\n-----------------------------------------------------------------\n\nr+ from me, but you should probably address roc\'s comment 188.\n\n::: gfx\/2d\/BasePoint3D.h\n\x40\x40 +61,5 \x40\x40\n\x3e \/\/ compiler generated default assignment operator\n\x3e \n\x3e + T& operator[](int aIndex) {\n\x3e + NS_ABORT_IF_FALSE(aIndex \x3e= 0 && aIndex \x3c= 2, \"Invalid array index\");\n\x3e + return *reinterpret_cast\x3cT*\x3e((&x)+aIndex);\n\nIs the reinterpret_cast as written here necessary? &x should already be of type T*. One subtlety here is that automated tools like coverity may detect references past the end of the object x as being out-of-bounds. It might be possible that a reinterpret_cast to an array of size 3 instead would avoid triggering bogus reports in coverity, but I have no way to test this.\n\nThe same comment applies to all the other places you do this.\n\n::: gfx\/thebes\/gfx3DMatrix.cpp\n\x40\x40 +260,5 \x40\x40\n\x3e + }\n\x3e +\n\x3e + gfx3DMatrix temp;\n\x3e +\n\x3e + temp._11 = (_22 * _33 - _23 * _32) \/ det;\n\nMaking the \"\/ det\" local is good (the optimizer doesn\'t have to deal with things going out to memory and back and trying to figure out if intermediate things have side-effects). But my suggestion was to compute the reciprocal \"1 \/ det\" and then multiply by that.\n\nIt\'s just a suggestion, and if you want to ignore me, feel free. It can be a ULP or two less accurate than doing all the divisions, but it should be significantly faster. Not only do divisions take many cycles, but on x86 they are also not pipelined, so all your other floating-point operations will stall, waiting for them.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Timothy B. Terriberry (:derf)'); comment.whoEmail = Splinter.Utils.strip('tterribe\x40vt.edu'); comment.date = Splinter.Bug.parseDate('2011-08-25 22:18:26 -0700'); comment.text = 'Review of attachment 555944:\n-----------------------------------------------------------------\n\nI know I already r+\'d this, but I had a few more quick comments anyway.\n\n::: layout\/style\/nsStyleAnimation.cpp\n\x40\x40 +1163,5 \x40\x40\n\x3e + \/* Normalize the matrix *\/\n\x3e + local.Normalize();\n\x3e +\n\x3e + \/** \n\x3e + * perspective is used to solve for perspective, but it also provides\n\nThis sounds pretty funny. Perhaps \"This\" in place of the first \"perspective\".\n\n\x40\x40 +1205,5 \x40\x40\n\x3e + \/* Compute X scale factor and normalize first row. *\/\n\x3e + aScale.x = local[0].Length();\n\x3e + local[0] \/= aScale.x;\n\x3e + \n\x3e + \/* Compute XY shear factor and make 2nd local orthogonal to 1st. *\/\n\nThis looks like an erroneous search and replace? I think \"2nd row\" still makes more sense here than \"2nd local\" (there\'s only one variable named \"local\"). Same for all the places below.\n\n\x40\x40 +1228,5 \x40\x40\n\x3e + aShear[XZSHEAR] \/= aScale.z;\n\x3e + aShear[YZSHEAR] \/= aScale.z;\n\x3e +\n\x3e + \/**\n\x3e + * At this point, the matrix (in locals) is orthonormal.\n\nUnless you actually want to rename the variable to \"locals\"... but I think that\'s pretty silly.'; theBug.comments.push(comment); var comment = new Splinter.Bug.Comment(); comment.whoName = Splinter.Utils.strip('Timothy B. Terriberry (:derf)'); comment.whoEmail = Splinter.Utils.strip('tterribe\x40vt.edu'); comment.date = Splinter.Bug.parseDate('2011-08-31 21:50:06 -0700'); comment.text = 'Review of attachment 557395:\n-----------------------------------------------------------------\n\nr+ with changes.\n\n::: gfx\/thebes\/gfx3DMatrix.cpp\n\x40\x40 +349,5 \x40\x40\n\x3e + _24 = -sinTheta * temp + cosTheta * _24;\n\x3e +}\n\x3e +\n\x3e +void \n\x3e +gfx3DMatrix::Multiply(const gfx3DMatrix& aOther)\n\nThis should be called something like PreMultiply (like in gfxMatrix) to distinguish it from the normal operator*=(). It would also be a lot simpler to implement it the same way:\n *this = aOther * (*this);\n\n\x40\x40 +374,5 \x40\x40\n\x3e + *this = temp;\n\x3e +}\n\x3e +\n\x3e +void\n\x3e +gfx3DMatrix::Multiply(const gfxMatrix& aOther)\n\nSame comment here with respect to the name.\n\n::: layout\/style\/nsStyleTransformMatrix.cpp\n\x40\x40 +118,5 \x40\x40\n\x3e NSAppUnitsToFloatPixels(offset, aAppUnitsPerMatrixUnit);\n\x3e }\n\x3e \n\x3e +static void\n\x3e +ProcessTranslatePart(double& aResult,\n\nCan\'t you just make the ProcessTranslatePart() function above return a float instead of taking an aResult outparam? Then you wouldn\'t need this extra version.\n\n\x40\x40 +258,5 \x40\x40\n\x3e * | dx 0 0 1 |\n\x3e * So E = value\n\x3e * \n\x3e * Otherwise, we might have a percentage, so we want to set the dX component\n\x3e * to the percent.\n\nWe\'re no longer constructing a matrix here, so this comment should be updated. A similar comment showing the equivalent matrix at the declaration of gfx3DMatrix::Translate() (and its friends) might be useful, however. Same for all the other, similar comments below.\n\n\x40\x40 +603,5 \x40\x40\n\x3e float depth;\n\x3e ProcessTranslatePart(depth, aData-\x3eItem(1), aContext,\n\x3e aPresContext, aCanStoreInRuleTree,\n\x3e 0, aAppUnitsPerMatrixUnit);\n\x3e NS_ASSERTION(depth \x3e 0.0, \"Perspective must be positive!\");\n\nYou\'ve got this same assertion in gfx3DMatrix::Perspective(). You probably only need it in one place, and I think there is better.\n\n::: layout\/style\/nsStyleTransformMatrix.h\n\x40\x40 +79,5 \x40\x40\n\x3e \/**\n\x3e * Given an nsCSSValue::Array* containing a -moz-transform function,\n\x3e * returns a matrix containing the value of that function.\n\x3e *\n\x3e * \x40param aData The nsCSSValue::Array* containing the transform function.\n\nThe documentation here needs to be updated to include the aMatrix parameter. You may also want to put the full documentation on the public ReadTransforms() instead of this private method.\n\n\x40\x40 +102,2 \x40\x40\n\x3e \n\x3e + static void ProcessMatrix(gfx3DMatrix& aMatrix, const nsCSSValue::Array *aData,\n\nAll of these functions look like they are only ever used as implementation details of the public nsStyleTransformMatrix functions, and are never referenced from anywhere else. That class has no data members and only static methods (its entire existence looks like an odd stand-in for a namespace). I realize it\'s good C++ form to expose lots of unnecessary details of your private implementation in the public headers, to spread the joy of recompiling when things change and to tempt people to expose things they can see right there, just under that pesky \"private\" keyword, but perhaps you should just make these into non-member, static (in the original C sense of the keyword) functions (so they only appear in the .cpp file).'; theBug.comments.push(comment); var attachid = parseInt('459283'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 1: Fix OpenGL container layer to support transforming children'); attachment.filename = Splinter.Utils.strip('opengl-transforms'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-07-21 20:06:49 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('459284'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 2: Make nsDisplayTransform create a Container layer'); attachment.filename = Splinter.Utils.strip('layerify-displaytransform'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-07-21 20:09:17 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('459742'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 2 v2: Layerify nsDisplayTransform'); attachment.filename = Splinter.Utils.strip('layerify-displaytransform'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-07-23 01:41:46 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('461956'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 2 v3: Layerify nsDisplayTransform'); attachment.filename = Splinter.Utils.strip('layerify-displaytransform'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-08-01 16:42:44 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('461957'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-08-01 16:43:47 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('461958'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 4: Upgrade gfx3DMatrix'); attachment.filename = Splinter.Utils.strip('gfx3DMatrix-upgrade'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-08-01 16:44:26 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('461959'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 5: Use gfx3DMatrix in layout'); attachment.filename = Splinter.Utils.strip('use-3d-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2010-08-01 16:45:40 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('525557'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.data = 'diff --git a\/layout\/style\/nsStyleTransformMatrix.cpp b\/layout\/style\/nsStyleTransformMatrix.cpp\n--- a\/layout\/style\/nsStyleTransformMatrix.cpp\n+++ b\/layout\/style\/nsStyleTransformMatrix.cpp\n\x40\x40 -14,16 +14,17 \x40\x40\n *\n * The Original Code is mozilla.org code.\n *\n * The Initial Developer of the Original Code is\n * Mozilla Corporation\n *\n * Contributor(s):\n * Keith Schwarz \x3ckschwarz\x40mozilla.com\x3e (original author)\n+ * Matt Woodrow \x3cmwoodrow\x40mozilla.com\x3e\n *\n * Alternatively, the contents of this file may be used under the terms of\n * either of the GNU General Public License Version 2 or later (the \"GPL\"),\n * or the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n * in which case the provisions of the GPL or the LGPL are applicable instead\n * of those above. If you wish to allow use of your version of this file only\n * under the terms of either the GPL or the LGPL, and not to allow others to\n * use your version of this file under the terms of the MPL, indicate your\n\x40\x40 -95,112 +96,155 \x40\x40 static double SafeTangent(double aTheta)\n nsStyleTransformMatrix::nsStyleTransformMatrix()\n {\n SetToIdentity();\n }\n \n \/* SetToIdentity just fills in the appropriate values. *\/\n void nsStyleTransformMatrix::SetToIdentity()\n {\n- \/* Set the main matrix to the identity. *\/\n- mMain[0] = 1.0f;\n- mMain[1] = 0.0f;\n- mMain[2] = 0.0f;\n- mMain[3] = 1.0f;\n- mDelta[0] = 0;\n- mDelta[1] = 0;\n+ \/* Set the main matrix to the identity. *\/\n+ _11 = 1.0f, _12 = 0.0f, _13 = 0.0f, _14 = 0.0f;\n+ _21 = 0.0f, _22 = 1.0f, _23 = 0.0f, _24 = 0.0f;\n+ _31 = 0.0f, _32 = 0.0f, _33 = 1.0f, _34 = 0.0f;\n+ _41 = 0, _42 = 0, _43 = 0, _44 = 1.0f;\n \n \/* Both translation matrices are zero. *\/\n mX[0] = 0.0f;\n mX[1] = 0.0f;\n mY[0] = 0.0f;\n mY[1] = 0.0f;\n }\n \n \/* Adds the constant translation to the scale factor translation components. *\/\n nscoord nsStyleTransformMatrix::GetXTranslation(const nsRect& aBounds) const\n {\n return NSToCoordRound(aBounds.width * mX[0] + aBounds.height * mY[0]) +\n- mDelta[0];\n+ _41;\n }\n nscoord nsStyleTransformMatrix::GetYTranslation(const nsRect& aBounds) const\n {\n return NSToCoordRound(aBounds.width * mX[1] + aBounds.height * mY[1]) +\n- mDelta[1];\n+ _42;\n }\n \n \/* GetThebesMatrix converts the stored matrix in a few steps. *\/\n gfxMatrix nsStyleTransformMatrix::GetThebesMatrix(const nsRect& aBounds,\n float aScale) const\n {\n \/* Compute the graphics matrix. We take the stored main elements, along with\n * the delta, and add in the matrices:\n *\n- * | 0 0 dx1|\n- * | 0 0 dx2| * width\n- * | 0 0 0|\n+ * | 0 0 0 0 |\n+ * | 0 0 0 0 | * width\n+ * | 0 0 0 0 |\n+ * | dx1 dx2 0 0 |\n *\n- * | 0 0 dy1|\n- * | 0 0 dy2| * height\n- * | 0 0 0|\n+ * | 0 0 0 0 |\n+ * | 0 0 0 0 | * height\n+ * | 0 0 0 0 |\n+ * | dy1 dy2 0 0 |\n *\/\n- return gfxMatrix(mMain[0], mMain[1], mMain[2], mMain[3],\n- NSAppUnitsToFloatPixels(GetXTranslation(aBounds), aScale),\n- NSAppUnitsToFloatPixels(GetYTranslation(aBounds), aScale));\n+ gfx3DMatrix matrix;\n+\n+ matrix._11 = _11;\n+ matrix._12 = _12;\n+ matrix._13 = _13;\n+ matrix._14 = _14;\n+ matrix._21 = _21;\n+ matrix._22 = _22;\n+ matrix._23 = _23;\n+ matrix._24 = _24;\n+ matrix._31 = _31;\n+ matrix._32 = _32;\n+ matrix._33 = _33;\n+ matrix._34 = _34;\n+ matrix._41 = NSAppUnitsToFloatPixels(GetXTranslation(aBounds), aScale);\n+ matrix._42 = NSAppUnitsToFloatPixels(GetYTranslation(aBounds), aScale);\n+ matrix._43 = _43;\n+ matrix._44 = _44;\n+\n+ gfxMatrix matrix2d;\n+\n+ if (!matrix.Is2D(&matrix2d)) {\n+ NS_ERROR(\"Only 2D transforms are supported!\");\n+ }\n+ return matrix2d;\n }\n \n+\n \/* Performs the matrix multiplication necessary to multiply the two matrices,\n * then hands back a reference to ourself.\n *\/\n nsStyleTransformMatrix&\n nsStyleTransformMatrix::operator *= (const nsStyleTransformMatrix &aOther)\n {\n \/* We\'ll buffer all of our results into a temporary storage location\n * during this operation since we don\'t want to overwrite the values of\n * the old matrix with the values of the new.\n *\/\n- float newMatrix[4];\n- nscoord newDelta[2];\n+ float new11, new12, new13, new14;\n+ float new21, new22, new23, new24;\n+ float new31, new32, new33, new34;\n+ nscoord new41, new42;\n+ float new43, new44;\n float newX[2];\n float newY[2];\n- \n- \/* [this] [aOther]\n- * |a1 c1 e1| |a0 c0 e0| |a0a1 + b0c1 c0a1 + d0c1 e0a1 + f0c1 + e1|\n- * |b1 d1 f1|x|b0 d0 f0| = |a0b1 + b0d1 c0b1 + d0d1 e0b1 + f0d1 + f1|\n- * |0 0 1 | | 0 0 1| | 0 0 1|\n- *\/\n- newMatrix[0] = aOther.mMain[0] * mMain[0] + aOther.mMain[1] * mMain[2];\n- newMatrix[1] = aOther.mMain[0] * mMain[1] + aOther.mMain[1] * mMain[3];\n- newMatrix[2] = aOther.mMain[2] * mMain[0] + aOther.mMain[3] * mMain[2];\n- newMatrix[3] = aOther.mMain[2] * mMain[1] + aOther.mMain[3] * mMain[3];\n- newDelta[0] = NSToCoordRound(aOther.mDelta[0] * mMain[0] +\n- aOther.mDelta[1] * mMain[2]) + mDelta[0];\n- newDelta[1] = NSToCoordRound(aOther.mDelta[0] * mMain[1] +\n- aOther.mDelta[1] * mMain[3]) + mDelta[1];\n+ \n+ new11 = aOther._11 * _11 + aOther._12 * _21 + aOther._13 * _31 + aOther._14 * _41;\n+ new21 = aOther._21 * _11 + aOther._22 * _21 + aOther._23 * _31 + aOther._24 * _41;\n+ new31 = aOther._31 * _11 + aOther._32 * _21 + aOther._33 * _31 + aOther._34 * _41;\n+ new41 = NSToCoordRound(aOther._41 * _11 + aOther._42 * _21 + aOther._43 * _31 + aOther._44 * _41);\n+ new12 = aOther._11 * _12 + aOther._12 * _22 + aOther._13 * _32 + aOther._14 * _42;\n+ new22 = aOther._21 * _12 + aOther._22 * _22 + aOther._23 * _32 + aOther._24 * _42;\n+ new32 = aOther._31 * _12 + aOther._32 * _22 + aOther._33 * _32 + aOther._34 * _42;\n+ new42 = NSToCoordRound(aOther._41 * _12 + aOther._42 * _22 + aOther._43 * _32 + aOther._44 * _42);\n+ new13 = aOther._11 * _13 + aOther._12 * _23 + aOther._13 * _33 + aOther._14 * _43;\n+ new23 = aOther._21 * _13 + aOther._22 * _23 + aOther._23 * _33 + aOther._24 * _43;\n+ new33 = aOther._31 * _13 + aOther._32 * _23 + aOther._33 * _33 + aOther._34 * _43;\n+ new43 = aOther._41 * _13 + aOther._42 * _23 + aOther._43 * _33 + aOther._44 * _43;\n+ new14 = aOther._11 * _14 + aOther._12 * _24 + aOther._13 * _34 + aOther._14 * _44;\n+ new24 = aOther._21 * _14 + aOther._22 * _24 + aOther._23 * _34 + aOther._24 * _44;\n+ new34 = aOther._31 * _14 + aOther._32 * _24 + aOther._33 * _34 + aOther._34 * _44;\n+ new44 = aOther._41 * _14 + aOther._42 * _24 + aOther._43 * _34 + aOther._44 * _44;\n+\n \n \/* For consistent terminology, let u0, u1, v0, and v1 be the four transform\n * coordinates from our matrix, and let x0, x1, y0, and y1 be the four\n * transform coordinates from the other matrix. Then the new transform\n * coordinates are:\n *\n * u0\' = a1u0 + c1u1 + x0\n * u1\' = b1u0 + d1u1 + x1\n * v0\' = a1v0 + c1v1 + y0\n * v1\' = b1v0 + d1v1 + y1\n *\/\n- newX[0] = mMain[0] * aOther.mX[0] + mMain[2] * aOther.mX[1] + mX[0];\n- newX[1] = mMain[1] * aOther.mX[0] + mMain[3] * aOther.mX[1] + mX[1];\n- newY[0] = mMain[0] * aOther.mY[0] + mMain[2] * aOther.mY[1] + mY[0];\n- newY[1] = mMain[1] * aOther.mY[0] + mMain[3] * aOther.mY[1] + mY[1];\n+ newX[0] = _11 * aOther.mX[0] + _21 * aOther.mX[1] + mX[0];\n+ newX[1] = _12 * aOther.mX[0] + _22 * aOther.mX[1] + mX[1];\n+ newY[0] = _11 * aOther.mY[0] + _21 * aOther.mY[1] + mY[0];\n+ newY[1] = _12 * aOther.mY[0] + _22 * aOther.mY[1] + mY[1];\n \n \/* Now, write everything back in. *\/\n- for (PRInt32 index = 0; index \x3c 4; ++index)\n- mMain[index] = newMatrix[index];\n+ _11 = new11;\n+ _12 = new12;\n+ _13 = new13;\n+ _14 = new14;\n+ _21 = new21;\n+ _22 = new22;\n+ _23 = new23;\n+ _24 = new24;\n+ _31 = new31;\n+ _32 = new32;\n+ _33 = new33;\n+ _34 = new34;\n+ _41 = new41;\n+ _42 = new42;\n+ _43 = new43;\n+ _44 = new44;\n for (PRInt32 index = 0; index \x3c 2; ++index) {\n- mDelta[index] = newDelta[index];\n mX[index] = newX[index];\n mY[index] = newY[index];\n }\n \n \/* As promised, return a reference to ourselves. *\/\n return *this;\n }\n \n\x40\x40 -320,218 +364,222 \x40\x40 static void ProcessTranslatePart(nscoord\n aOffset = result.mLength;\n } else {\n aOffset = CalcLength(aValue, aContext, aPresContext,\n aCanStoreInRuleTree);\n }\n }\n \n \/* Helper function to process a matrix entry. *\/\n-static void ProcessMatrix(float aMain[4], nscoord aDelta[2],\n- float aX[2], float aY[2],\n- const nsCSSValue::Array* aData,\n- nsStyleContext* aContext,\n- nsPresContext* aPresContext,\n- PRBool& aCanStoreInRuleTree)\n+void nsStyleTransformMatrix::ProcessMatrix(const nsCSSValue::Array* aData,\n+ nsStyleContext* aContext,\n+ nsPresContext* aPresContext,\n+ PRBool& aCanStoreInRuleTree)\n {\n NS_PRECONDITION(aData-\x3eCount() == 7, \"Invalid array!\");\n \n \/* Take the first four elements out of the array as floats and store\n- * them in aMain.\n+ * them.\n *\/\n- for (PRUint16 index = 1; index \x3c= 4; ++index)\n- aMain[index - 1] = aData-\x3eItem(index).GetFloatValue();\n+ _11 = aData-\x3eItem(1).GetFloatValue();\n+ _12 = aData-\x3eItem(2).GetFloatValue();\n+ _21 = aData-\x3eItem(3).GetFloatValue();\n+ _22 = aData-\x3eItem(4).GetFloatValue();\n \n \/* The last two elements have their length parts stored in aDelta\n * and their percent parts stored in aX[0] and aY[1].\n *\/\n- ProcessTranslatePart(aDelta[0], aX[0], aData-\x3eItem(5),\n+ ProcessTranslatePart(_41, mX[0], aData-\x3eItem(5),\n aContext, aPresContext, aCanStoreInRuleTree);\n- ProcessTranslatePart(aDelta[1], aY[1], aData-\x3eItem(6),\n+ ProcessTranslatePart(_42, mY[0], aData-\x3eItem(6),\n aContext, aPresContext, aCanStoreInRuleTree);\n }\n \n \/* Helper function to process a translatex function. *\/\n-static void ProcessTranslateX(nscoord aDelta[2], float aX[2],\n- const nsCSSValue::Array* aData,\n- nsStyleContext* aContext,\n- nsPresContext* aPresContext,\n- PRBool& aCanStoreInRuleTree)\n+void nsStyleTransformMatrix::ProcessTranslateX(const nsCSSValue::Array* aData,\n+ nsStyleContext* aContext,\n+ nsPresContext* aPresContext,\n+ PRBool& aCanStoreInRuleTree)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2, \"Invalid array!\");\n \n \/* There are two cases. If we have a number, we want our matrix to look\n * like this:\n *\n- * | 1 0 dx|\n- * | 0 1 0|\n- * | 0 0 1|\n+ * | 1 0 0 0 |\n+ * | 0 1 0 0 |\n+ * | 0 0 1 0 |\n+ * | dx 0 0 1 |\n * So E = value\n * \n * Otherwise, we might have a percentage, so we want to set the dX component\n * to the percent.\n *\/\n- ProcessTranslatePart(aDelta[0], aX[0], aData-\x3eItem(1),\n+ ProcessTranslatePart(_41, mX[0], aData-\x3eItem(1),\n aContext, aPresContext, aCanStoreInRuleTree);\n }\n \n \/* Helper function to process a translatey function. *\/\n-static void ProcessTranslateY(nscoord aDelta[2], float aY[2],\n- const nsCSSValue::Array* aData,\n- nsStyleContext* aContext,\n- nsPresContext* aPresContext,\n- PRBool& aCanStoreInRuleTree)\n+void nsStyleTransformMatrix::ProcessTranslateY(const nsCSSValue::Array* aData,\n+ nsStyleContext* aContext,\n+ nsPresContext* aPresContext,\n+ PRBool& aCanStoreInRuleTree)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2, \"Invalid array!\");\n \n \/* There are two cases. If we have a number, we want our matrix to look\n * like this:\n *\n- * | 1 0 0|\n- * | 0 1 dy|\n- * | 0 0 1|\n+ * | 1 0 0 0 |\n+ * | 0 1 0 0 |\n+ * | 0 0 1 0 |\n+ * | 0 dy 0 1 |\n * So E = value\n * \n * Otherwise, we might have a percentage, so we want to set the dY component\n * to the percent.\n *\/\n- ProcessTranslatePart(aDelta[1], aY[1], aData-\x3eItem(1),\n+ ProcessTranslatePart(_42, mY[1], aData-\x3eItem(1),\n aContext, aPresContext, aCanStoreInRuleTree);\n }\n \n \/* Helper function to process a translate function. *\/\n-static void ProcessTranslate(nscoord aDelta[2], float aX[2], float aY[2],\n- const nsCSSValue::Array* aData,\n- nsStyleContext* aContext,\n- nsPresContext* aPresContext,\n- PRBool& aCanStoreInRuleTree)\n+void nsStyleTransformMatrix::ProcessTranslate(const nsCSSValue::Array* aData,\n+ nsStyleContext* aContext,\n+ nsPresContext* aPresContext,\n+ PRBool& aCanStoreInRuleTree)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2 || aData-\x3eCount() == 3, \"Invalid array!\");\n \n \/* There are several cases to consider.\n * First, we might have one value, or we might have two. If we have\n * two, we need to consider both dX and dY components.\n * Next, the values might be lengths, or they might be percents. If they\'re\n * percents, store them in the dX and dY components. Otherwise, store them in\n * the main matrix.\n *\/\n \n- ProcessTranslatePart(aDelta[0], aX[0], aData-\x3eItem(1),\n+ ProcessTranslatePart(_41, mX[0], aData-\x3eItem(1),\n aContext, aPresContext, aCanStoreInRuleTree);\n \n \/* If we read in a Y component, set it appropriately *\/\n if (aData-\x3eCount() == 3) {\n- ProcessTranslatePart(aDelta[1], aY[1], aData-\x3eItem(2),\n+ ProcessTranslatePart(_42, mY[1], aData-\x3eItem(2),\n aContext, aPresContext, aCanStoreInRuleTree);\n }\n }\n \n \/* Helper function to set up a scale matrix. *\/\n-static void ProcessScaleHelper(float aXScale, float aYScale, float aMain[4])\n+void nsStyleTransformMatrix::ProcessScaleHelper(float aXScale, float aYScale, float aZScale)\n {\n \/* We want our matrix to look like this:\n- * | dx 0 0|\n- * | 0 dy 0|\n- * | 0 0 1|\n+ * | dx 0 0 0 |\n+ * | 0 dy 0 0 |\n+ * | 0 0 dz 0 |\n+ * | 0 0 0 1 |\n * So A = value\n *\/\n- aMain[0] = aXScale;\n- aMain[3] = aYScale;\n+ _11 = aXScale;\n+ _22 = aYScale;\n+ _33 = aZScale;\n }\n \n \/* Process a scalex function. *\/\n-static void ProcessScaleX(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessScaleX(const nsCSSValue::Array* aData)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2, \"Bad array!\");\n- ProcessScaleHelper(aData-\x3eItem(1).GetFloatValue(), 1.0f, aMain);\n+ ProcessScaleHelper(aData-\x3eItem(1).GetFloatValue(), 1.0f, 1.0f);\n }\n \n \/* Process a scaley function. *\/\n-static void ProcessScaleY(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessScaleY(const nsCSSValue::Array* aData)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2, \"Bad array!\");\n- ProcessScaleHelper(1.0f, aData-\x3eItem(1).GetFloatValue(), aMain);\n+ ProcessScaleHelper(1.0f, aData-\x3eItem(1).GetFloatValue(), 1.0f);\n }\n \n \/* Process a scale function. *\/\n-static void ProcessScale(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessScale(const nsCSSValue::Array* aData)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2 || aData-\x3eCount() == 3, \"Bad array!\");\n \/* We either have one element or two. If we have one, it\'s for both X and Y.\n * Otherwise it\'s one for each.\n *\/\n const nsCSSValue& scaleX = aData-\x3eItem(1);\n const nsCSSValue& scaleY = (aData-\x3eCount() == 2 ? scaleX :\n aData-\x3eItem(2));\n \n ProcessScaleHelper(scaleX.GetFloatValue(),\n- scaleY.GetFloatValue(), aMain);\n+ scaleY.GetFloatValue(),\n+ 1.0f);\n }\n \n \/* Helper function that, given a set of angles, constructs the appropriate\n * skew matrix.\n *\/\n-static void ProcessSkewHelper(double aXAngle, double aYAngle, float aMain[4])\n+void nsStyleTransformMatrix::ProcessSkewHelper(double aXAngle, double aYAngle)\n {\n \/* We want our matrix to look like this:\n- * | 1 tan(ThetaX) 0|\n- * | tan(ThetaY) 1 0|\n- * | 0 0 1|\n+ * | 1 tan(ThetaY) 0 0 |\n+ * | tan(ThetaX) 1 0 0 |\n+ * | 0 0 1 0 |\n+ * | 0 0 0 1 |\n * However, to avoid infinite values, we\'ll use the SafeTangent function\n * instead of the C standard tan function.\n *\/\n- aMain[2] = SafeTangent(aXAngle);\n- aMain[1] = SafeTangent(aYAngle);\n+ _12 = SafeTangent(aYAngle);\n+ _21 = SafeTangent(aXAngle);\n }\n \n \/* Function that converts a skewx transform into a matrix. *\/\n-static void ProcessSkewX(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessSkewX(const nsCSSValue::Array* aData)\n {\n NS_ASSERTION(aData-\x3eCount() == 2, \"Bad array!\");\n- ProcessSkewHelper(aData-\x3eItem(1).GetAngleValueInRadians(), 0.0, aMain);\n+ ProcessSkewHelper(aData-\x3eItem(1).GetAngleValueInRadians(), 0.0);\n }\n \n \/* Function that converts a skewy transform into a matrix. *\/\n-static void ProcessSkewY(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessSkewY(const nsCSSValue::Array* aData)\n {\n NS_ASSERTION(aData-\x3eCount() == 2, \"Bad array!\");\n- ProcessSkewHelper(0.0, aData-\x3eItem(1).GetAngleValueInRadians(), aMain);\n+ ProcessSkewHelper(0.0, aData-\x3eItem(1).GetAngleValueInRadians());\n }\n \n \/* Function that converts a skew transform into a matrix. *\/\n-static void ProcessSkew(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessSkew(const nsCSSValue::Array* aData)\n {\n NS_ASSERTION(aData-\x3eCount() == 2 || aData-\x3eCount() == 3, \"Bad array!\");\n \n double xSkew = aData-\x3eItem(1).GetAngleValueInRadians();\n double ySkew = (aData-\x3eCount() == 2\n ? 0.0 : aData-\x3eItem(2).GetAngleValueInRadians());\n \n- ProcessSkewHelper(xSkew, ySkew, aMain);\n+ ProcessSkewHelper(xSkew, ySkew);;\n }\n \n \/* Function that converts a rotate transform into a matrix. *\/\n-static void ProcessRotate(float aMain[4], const nsCSSValue::Array* aData)\n+void nsStyleTransformMatrix::ProcessRotateZ(const nsCSSValue::Array* aData)\n {\n NS_PRECONDITION(aData-\x3eCount() == 2, \"Invalid array!\");\n \n \/* We want our matrix to look like this:\n- * | cos(theta) -sin(theta) 0|\n- * | sin(theta) cos(theta) 0|\n- * | 0 0 1|\n+ * | cos(theta) sin(theta) 0 0 |\n+ * | -sin(theta) cos(theta) 0 0 |\n+ * | 0 0 1 0 |\n+ * | 0 0 0 1 |\n * (see http:\/\/www.w3.org\/TR\/SVG\/coords.html#RotationDefined)\n *\/\n double theta = aData-\x3eItem(1).GetAngleValueInRadians();\n float cosTheta = FlushToZero(cos(theta));\n float sinTheta = FlushToZero(sin(theta));\n \n- aMain[0] = cosTheta;\n- aMain[1] = sinTheta;\n- aMain[2] = -sinTheta;\n- aMain[3] = cosTheta;\n+ _11 = cosTheta;\n+ _12 = sinTheta;\n+ _21 = -sinTheta;\n+ _22 = cosTheta;\n }\n \n \/**\n * Return the transform function, as an nsCSSKeyword, for the given\n * nsCSSValue::Array from a transform list.\n *\/\n \/* static *\/ nsCSSKeyword\n nsStyleTransformMatrix::TransformFunctionOf(const nsCSSValue::Array* aData)\n\x40\x40 -559,50 +607,50 \x40\x40 nsStyleTransformMatrix::SetToTransformFu\n \/* Reset the matrix to the identity so that each subfunction can just\n * worry about its own components.\n *\/\n SetToIdentity();\n \n \/* Get the keyword for the transform. *\/\n switch (TransformFunctionOf(aData)) {\n case eCSSKeyword_translatex:\n- ProcessTranslateX(mDelta, mX, aData, aContext, aPresContext,\n+ ProcessTranslateX(aData, aContext, aPresContext,\n aCanStoreInRuleTree);\n break;\n case eCSSKeyword_translatey:\n- ProcessTranslateY(mDelta, mY, aData, aContext, aPresContext,\n+ ProcessTranslateY(aData, aContext, aPresContext,\n aCanStoreInRuleTree);\n break;\n case eCSSKeyword_translate:\n- ProcessTranslate(mDelta, mX, mY, aData, aContext, aPresContext,\n+ ProcessTranslate(aData, aContext, aPresContext,\n aCanStoreInRuleTree);\n break;\n case eCSSKeyword_scalex:\n- ProcessScaleX(mMain, aData);\n+ ProcessScaleX(aData);\n break;\n case eCSSKeyword_scaley:\n- ProcessScaleY(mMain, aData);\n+ ProcessScaleY(aData);\n break;\n case eCSSKeyword_scale:\n- ProcessScale(mMain, aData);\n+ ProcessScale(aData);\n break;\n case eCSSKeyword_skewx:\n- ProcessSkewX(mMain, aData);\n+ ProcessSkewX(aData);\n break;\n case eCSSKeyword_skewy:\n- ProcessSkewY(mMain, aData);\n+ ProcessSkewY(aData);\n break;\n case eCSSKeyword_skew:\n- ProcessSkew(mMain, aData);\n+ ProcessSkew(aData);\n break;\n case eCSSKeyword_rotate:\n- ProcessRotate(mMain, aData);\n+ ProcessRotateZ(aData);\n break;\n case eCSSKeyword_matrix:\n- ProcessMatrix(mMain, mDelta, mX, mY, aData, aContext, aPresContext,\n+ ProcessMatrix(aData, aContext, aPresContext,\n aCanStoreInRuleTree);\n break;\n default:\n NS_NOTREACHED(\"Unknown transform function!\");\n }\n }\n \n \/* Given a -moz-transform token stream, accumulates them into an\n\x40\x40 -639,20 +687,19 \x40\x40 nsStyleTransformMatrix::ReadTransforms(c\n }\n \n \/* Does an element-by-element comparison and returns whether or not the\n * matrices are equal.\n *\/\n PRBool\n nsStyleTransformMatrix::operator ==(const nsStyleTransformMatrix &aOther) const\n {\n- for (PRInt32 index = 0; index \x3c 4; ++index)\n- if (mMain[index] != aOther.mMain[index])\n- return PR_FALSE;\n+ if (!(_11 == aOther._11 && _12 == aOther._12 && _13 == aOther._13 && _14 == aOther._14 &&\n+ _21 == aOther._21 && _22 == aOther._22 && _23 == aOther._23 && _24 == aOther._24 &&\n+ _31 == aOther._31 && _32 == aOther._32 && _33 == aOther._33 && _34 == aOther._34 &&\n+ _41 == aOther._41 && _42 == aOther._42 && _43 == aOther._43 && _44 == aOther._44))\n+ return PR_FALSE;\n \n- for (PRInt32 index = 0; index \x3c 2; ++index)\n- if (mDelta[index] != aOther.mDelta[index] ||\n- mX[index] != aOther.mX[index] ||\n- mY[index] != aOther.mY[index])\n- return PR_FALSE;\n-\n+ if (!(mX[0] == aOther.mX[0] && mX[1] == aOther.mX[1] &&\n+ mY[0] == aOther.mY[0] && mY[1] == aOther.mY[1]))\n+ return PR_FALSE;\n return PR_TRUE;\n }\ndiff --git a\/layout\/style\/nsStyleTransformMatrix.h b\/layout\/style\/nsStyleTransformMatrix.h\n--- a\/layout\/style\/nsStyleTransformMatrix.h\n+++ b\/layout\/style\/nsStyleTransformMatrix.h\n\x40\x40 -14,16 +14,17 \x40\x40\n *\n * The Original Code is mozilla.org code.\n *\n * The Initial Developer of the Original Code is\n * Mozilla Corporation\n *\n * Contributor(s):\n * Keith Schwarz \x3ckschwarz\x40mozilla.com\x3e (original author)\n+ * Matt Woodrow \x3cmwoodrow\x40mozilla.com\x3e\n *\n * Alternatively, the contents of this file may be used under the terms of\n * either of the GNU General Public License Version 2 or later (the \"GPL\"),\n * or the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n * in which case the provisions of the GPL or the LGPL are applicable instead\n * of those above. If you wish to allow use of your version of this file only\n * under the terms of either the GPL or the LGPL, and not to allow others to\n * use your version of this file under the terms of the MPL, indicate your\n\x40\x40 -38,34 +39,33 \x40\x40\n * A class representing three matrices that can be used for style transforms.\n *\/\n \n #ifndef nsStyleTransformMatrix_h_\n #define nsStyleTransformMatrix_h_\n \n #include \"nsCSSValue.h\"\n #include \"gfxMatrix.h\"\n+#include \"gfx3DMatrix.h\"\n #include \"nsRect.h\"\n \n struct nsCSSValueList;\n \n \/**\n * A class representing a style transformation matrix. The class actually\n * wraps three different matrices, a constant matrix and two matrices\n * whose values are scaled by the width and the height of the bounding\n * rectangle for the object to transform. Thus, given a frame rectangle\n- * of dimensions (width, height) and a point (x, y) to transform, the matrix\n+ * of dimensions (width, height) and a point (x, y, z) to transform, the matrix\n * corresponds to the transform operation\n *\n- * | a c e | |0 0 dX1| |0 0 dY1| | x |\n- *(| b d f | + |0 0 dX2| (width) + |0 0 dY2| (height)) | y |\n- * | 0 0 1 | |0 0 0| |0 0 0| | 1 |\n- *\n- * Note that unlike the Thebes gfxMatrix, vectors are column vectors and\n- * consequently the multiplication of a matrix A and a vector x is Ax, not xA.\n+ * | _11 _12 _13 _14 | | 0 0 0 0 | | 0 0 0 0 |\n+ *(| _21 _22 _23 _24 | + | 0 0 0 0 | (width) + | 0 0 0 0 | (height))\n+ * | _31 _32 _33 _34 | | 0 0 0 0 | | 0 0 0 0 | \n+ * | _41 _42 _43 _44 | |dX1 dX2 0 0 | |dY1 dY2 0 0 |\n *\/\n class nsStyleContext;\n class nsPresContext;\n class nsStyleTransformMatrix\n {\n public:\n \/**\n * Constructor sets the matrix to the identity.\n\x40\x40 -144,43 +144,54 \x40\x40 class nsStyleTransformMatrix\n * Sets this matrix to be the identity matrix.\n *\/\n void SetToIdentity();\n \n \/**\n * Returns the value of the entry at the 2x2 submatrix of the\n * transform matrix that defines the non-affine linear transform.\n * The order is given as\n- * |elem[0] elem[2]|\n- * |elem[1] elem[3]|\n+ * |elem[0] elem[1] 0 0|\n+ * |elem[2] elem[3] 0 0|\n+ * | 0 0 0 0|\n+ * | 0 0 0 0|\n *\n * \x40param aIndex The element index.\n * \x40return The value of the element at that index.\n *\/\n float GetMainMatrixEntry(PRInt32 aIndex) const\n {\n NS_PRECONDITION(aIndex \x3e= 0 && aIndex \x3c 4, \"Index out of bounds!\");\n- return mMain[aIndex];\n+ if (aIndex == 0) {\n+ return _11;\n+ } else if (aIndex == 1) {\n+ return _12;\n+ } else if (aIndex == 2) {\n+ return _21;\n+ } else {\n+ return _22;\n+ }\n }\n \n+\n \/**\n * Returns the value of the X or Y translation component of the matrix,\n * given the specified bounds.\n *\n * \x40param aBounds The bounds of the element.\n * \x40return The value of the X or Ytranslation component.\n *\/\n nscoord GetXTranslation(const nsRect& aBounds) const;\n nscoord GetYTranslation(const nsRect& aBounds) const;\n \n \/**\n * Get the raw components used for GetXTranslation and GetYTranslation.\n *\/\n- nscoord GetCoordXTranslation() const { return mDelta[0]; }\n- nscoord GetCoordYTranslation() const { return mDelta[1]; }\n+ nscoord GetCoordXTranslation() const { return _41; }\n+ nscoord GetCoordYTranslation() const { return _42; }\n float GetWidthRelativeXTranslation() const { return mX[0]; }\n float GetWidthRelativeYTranslation() const { return mX[1]; }\n float GetHeightRelativeXTranslation() const { return mY[0]; }\n float GetHeightRelativeYTranslation() const { return mY[1]; }\n \n \/**\n * Returns whether the two matrices are equal or not.\n *\n\x40\x40 -189,28 +200,63 \x40\x40 class nsStyleTransformMatrix\n *\/\n PRBool operator== (const nsStyleTransformMatrix& aOther) const;\n PRBool operator!= (const nsStyleTransformMatrix& aOther) const\n {\n return !(*this == aOther);\n }\n \n private:\n+ void ProcessMatrix(const nsCSSValue::Array *aData,\n+ nsStyleContext *aContext,\n+ nsPresContext *aPresContext,\n+ PRBool &aCanStoreInRuleTree);\n+ void ProcessTranslateX(const nsCSSValue::Array *aData,\n+ nsStyleContext *aContext,\n+ nsPresContext *aPresContext,\n+ PRBool &aCanStoreInRuleTree);\n+ void ProcessTranslateY(const nsCSSValue::Array *aData,\n+ nsStyleContext *aContext,\n+ nsPresContext *aPresContext,\n+ PRBool &aCanStoreInRuleTree);\n+ void ProcessTranslate(const nsCSSValue::Array *aData,\n+ nsStyleContext *aContext,\n+ nsPresContext *aPresContext,\n+ PRBool &aCanStoreInRuleTree);\n+ void ProcessScaleHelper(float aXScale, float aYScale, float aZScale);\n+ void ProcessScaleX(const nsCSSValue::Array *aData);\n+ void ProcessScaleY(const nsCSSValue::Array *aData);\n+ void ProcessScale(const nsCSSValue::Array *aData);\n+ void ProcessSkewHelper(double aXAngle, double aYAngle);\n+ void ProcessSkewX(const nsCSSValue::Array *aData);\n+ void ProcessSkewY(const nsCSSValue::Array *aData);\n+ void ProcessSkew(const nsCSSValue::Array *aData);\n+ void ProcessRotateZ(const nsCSSValue::Array *aData);\n+ void ProcessRotateX(const nsCSSValue::Array *aData); \n+\n+\n \/* The three matrices look like this:\n- * |mMain[0] mMain[2] mDelta[0]|\n- * |mMain[1] mMain[3] mDelta[1]| \x3c-- Constant matrix\n- * | 0 0 1|\n+ * | _11 _12 _13 _14 |\n+ * | _21 _22 _23 _24 | \x3c-- Constant matrix\n+ * | _31 _32 _33 _34 |\n+ * | _41 _42 _43 _44 |\n *\n- * | 0 0 mX[0]|\n- * | 0 0 mX[1]| \x3c-- Scaled by width of element\n- * | 0 0 0|\n+ * | 0 0 0 0 |\n+ * | 0 0 0 0 | \x3c-- Scaled by width of element\n+ * | 0 0 0 0 |\n+ * | mX[0] mX[1] 0 0 |\n *\n- * | 0 0 mY[0]|\n- * | 0 0 mY[1]| \x3c-- Scaled by height of element\n- * | 0 0 0|\n+ * | 0 0 0 0 |\n+ * | 0 0 0 0 | \x3c-- Scaled by height of element\n+ * | 0 0 0 0 |\n+ * | mY[0] mY[1] 0 0 |\n *\/\n- float mMain[4];\n- nscoord mDelta[2];\n float mX[2];\n float mY[2];\n+\n+ float _11, _12, _13, _14;\n+ float _21, _22, _23, _24;\n+ float _31, _32, _33, _34;\n+ nscoord _41, _42;\n+ float _43, _44;\n };\n \n #endif\n'; attachment.token = '1732721905-vv2OwH9SV9FgygIiTsMw3BgJSotU3s2ZvD2f2gzQTeY'; attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix v2'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-04-12 16:56:55 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('525558'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 4: Upgrade gfx3DMatrix v2'); attachment.filename = Splinter.Utils.strip('gfx3DMatrix-upgrade'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-04-12 16:58:01 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('525561'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 5: Use gfx3DMatrix in layout v2'); attachment.filename = Splinter.Utils.strip('use-3d-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-04-12 17:05:47 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('530273'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix v3'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-05-05 04:42:24 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('530964'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix v4'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-05-08 16:39:48 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537013'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix v5'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:10:54 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537014'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 4: Upgrade gfx3DMatrix v3'); attachment.filename = Splinter.Utils.strip('gfx3DMatrix-upgrade'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:11:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537016'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 5: Use gfx3DMatrix in layout v3'); attachment.filename = Splinter.Utils.strip('use-3d-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:13:26 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537017'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 6: Implement the 3d -moz-transform functions'); attachment.filename = Splinter.Utils.strip('3d-transform-functions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:14:57 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537018'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 7: Layers support for 3d transforms'); attachment.filename = Splinter.Utils.strip('fixy-fix-fix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:16:24 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('537019'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 8: Add ray tracing to untransform 2d points on a 3d plane'); attachment.filename = Splinter.Utils.strip('untransform-3d'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-02 16:19:36 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('538995'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 8: Add ray tracing to untransform 2d points on a 3d plane v2'); attachment.filename = Splinter.Utils.strip('untransform-3d'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-13 13:44:31 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('538996'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 9 - Implement the perspective() transform function and style property.'); attachment.filename = Splinter.Utils.strip('3d-perspective'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-13 13:45:42 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('538997'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 10 - Implement -moz-backface-visible'); attachment.filename = Splinter.Utils.strip('backface-visible'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-13 13:46:39 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('538998'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 11 - Make -moz-transform-origin also support a z component.'); attachment.filename = Splinter.Utils.strip('transform-origin-z'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-13 13:47:49 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('538999'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 12 - Implement -moz-perspective-origin.'); attachment.filename = Splinter.Utils.strip('perspective-origin'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-13 13:49:26 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540952'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 8a: Add BasePoint3D and gfxPoint3D'); attachment.filename = Splinter.Utils.strip('untransform-points'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:09:18 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540953'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 8b: Add 3D Point support, and ray tracing to gfx3DMatrix'); attachment.filename = Splinter.Utils.strip('untransform-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:10:10 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540954'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 8c: Use ray tracing to untransform 2d points on a 3d plane.'); attachment.filename = Splinter.Utils.strip('untransform-3d'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:10:58 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540955'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 10 - Implement -moz-backface-visible'); attachment.filename = Splinter.Utils.strip('backface-visible'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:11:55 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540956'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 11a: Add nsCSSValueTriplet and optionally read a z component to -moz-transform-origin'); attachment.filename = Splinter.Utils.strip('transform-origin-z'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:12:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540957'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 11b: Layout changes to use a z component for -moz-transform-origin'); attachment.filename = Splinter.Utils.strip('transform-origin-z-layout'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:13:43 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540958'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 12a: Implement -moz-perspective-origin style property.'); attachment.filename = Splinter.Utils.strip('perspective-origin'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:14:36 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('540959'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 12b: Layout changes to use -moz-perspective-origin'); attachment.filename = Splinter.Utils.strip('perspective-origin-layout'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-06-21 19:15:36 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('547812'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 3: Convert nsStyleTransformMatrix to be backed by a 4x4 matrix v6'); attachment.filename = Splinter.Utils.strip('3d-style-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-22 14:53:24 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('547813'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 5: Use gfx3DMatrix in layout v4'); attachment.filename = Splinter.Utils.strip('use-3d-matrix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-22 14:54:53 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548074'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 6: Implement the 3d -moz-transform functions v2'); attachment.filename = Splinter.Utils.strip('3d-transform-functions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:46:31 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548075'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 7: Layers support for 3d transforms v2'); attachment.filename = Splinter.Utils.strip('fixy-fix-fix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:48:35 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548076'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 9 - Implement the perspective() transform function and style property. v2'); attachment.filename = Splinter.Utils.strip('3d-perspective'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:50:15 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548077'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 10 - Implement -moz-backface-visible v2'); attachment.filename = Splinter.Utils.strip('backface-visible'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:52:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548078'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 11a: Add nsCSSValueTriplet and optionally read a z component to -moz-transform-origin v2'); attachment.filename = Splinter.Utils.strip('transform-origin-z'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:55:40 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548079'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 12a: Implement -moz-perspective-origin style property. v2'); attachment.filename = Splinter.Utils.strip('perspective-origin'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 18:56:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548080'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 13: Add basic reftests for 3d transforms and expose 3d transform status in GfxInfo'); attachment.filename = Splinter.Utils.strip('actually-reftest'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 19:00:00 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548083'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 14a: Add -moz-transform-style CSS property'); attachment.filename = Splinter.Utils.strip('preserve-3d'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 19:05:49 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548084'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 14b: Layout changes for preserve-3d'); attachment.filename = Splinter.Utils.strip('preserve-3d-for-realz'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 19:57:35 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548086'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 15 - Add 4D Vectors, Quaternions and gfx3DMatrix functions'); attachment.filename = Splinter.Utils.strip('quaternions-and-friends'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-24 20:40:35 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548634'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 15 - Add 4D Vectors, Quaternions and gfx3DMatrix functions v2'); attachment.filename = Splinter.Utils.strip('quaternions-and-friends'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-26 16:56:10 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548635'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 16 - Implement transitions\/animations for 3d transforms.'); attachment.filename = Splinter.Utils.strip('transitions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-26 16:57:14 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('548636'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 17 - Add style tests for the new transform functions, and transitions'); attachment.filename = Splinter.Utils.strip('style-tests'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-26 16:58:36 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('549620'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 9 - Implement the perspective() transform function and style property. v3'); attachment.filename = Splinter.Utils.strip('3d-perspective'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-30 21:18:49 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('549699'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 9 - Implement the perspective() transform function and style property. v4'); attachment.filename = Splinter.Utils.strip('3d-perspective'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-07-31 16:55:30 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('551300'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 14b: Layout changes for preserve-3d v2'); attachment.filename = Splinter.Utils.strip('preserve-3d-for-realz'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-06 20:16:37 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('552267'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 14b: Layout changes for preserve-3d v3'); attachment.filename = Splinter.Utils.strip('preserve-3d-for-realz'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-10 17:04:35 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('553086'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 15 - Add 4D Vectors, Quaternions and gfx3DMatrix functions v3'); attachment.filename = Splinter.Utils.strip('quaternions-and-friends'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-14 19:35:31 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('553087'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 16 - Implement transitions\/animations for 3d transforms. v2'); attachment.filename = Splinter.Utils.strip('transitions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-14 19:37:02 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('555944'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 16 - Implement transitions\/animations for 3d transforms. v3'); attachment.filename = Splinter.Utils.strip('transitions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-25 20:27:29 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('555946'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 17 - Add style tests for the new transform functions, and transitions v2'); attachment.filename = Splinter.Utils.strip('style-tests'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-25 20:28:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('555950'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 17 - Add style tests for the new transform functions, and transitions v3'); attachment.filename = Splinter.Utils.strip('style-tests'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-25 21:25:51 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('555951'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 18 - Make the perspective() transform function actually fail on numbers \x3c= 0'); attachment.filename = Splinter.Utils.strip('negative-length-fix'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-25 21:26:46 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556169'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 15 - Add 4D Vectors, Quaternions and gfx3DMatrix functions v4'); attachment.filename = Splinter.Utils.strip('quaternions-and-friends'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-26 16:15:44 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556450'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 16 - Implement transitions\/animations for 3d transforms. v4'); attachment.filename = Splinter.Utils.strip('transitions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-28 19:15:30 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556451'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 17 - Add style tests for the new transform functions, and transitions v4'); attachment.filename = Splinter.Utils.strip('style-tests'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-28 19:16:51 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556452'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 19: Make all translate functions handle lengths and percents'); attachment.filename = Splinter.Utils.strip('length-percent-handling'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-28 19:17:58 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556453'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 13: Add basic reftests for 3d transforms v3'); attachment.filename = Splinter.Utils.strip('actually-reftest'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-28 19:22:59 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('556463'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 13: Add basic reftests for 3d transforms v4'); attachment.filename = Splinter.Utils.strip('actually-reftest'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-28 20:25:51 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('557395'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 20 - Add more gfx3DMatrix transformation function and use these in nsStyleTransformMatrix'); attachment.filename = Splinter.Utils.strip('style-transform-matrix-opt'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-08-31 19:30:43 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 1; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('558196'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 20 - Add more gfx3DMatrix transformation function and use these in nsStyleTransformMatrix v2'); attachment.filename = Splinter.Utils.strip('style-transform-matrix-opt'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-09-04 15:22:02 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('561953'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 16 - Implement transitions\/animations for 3d transforms. v5'); attachment.filename = Splinter.Utils.strip('transitions'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-09-22 19:13:19 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('561961'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 18 - Make the perspective() transform function actually fail on numbers \x3c= 0 v2'); attachment.filename = Splinter.Utils.strip('length-percent-handling'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-09-22 20:56:31 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('561962'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 19: Make matrix* functions handle lengths and percents'); attachment.filename = Splinter.Utils.strip('length-percent-handling'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-09-22 20:58:14 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); var attachid = parseInt('562585'); var attachment = new Splinter.Bug.Attachment('', attachid); attachment.description = Splinter.Utils.strip('Part 21: Enable 3D transforms!'); attachment.filename = Splinter.Utils.strip('enable'); attachment.contenttypeentry = Splinter.Utils.strip(''); attachment.date = Splinter.Bug.parseDate('2011-09-26 16:45:33 -0700'); attachment.whoName = Splinter.Utils.strip('Matt Woodrow (:mattwoodrow)'); attachment.whoEmail = Splinter.Utils.strip('matt.woodrow\x40gmail.com'); attachment.isPatch = 1; attachment.isObsolete = 0; attachment.isPrivate = 0; attachment.isCRLF = 0; theBug.attachments.push(attachment); Splinter.theBug = theBug; } </script> <!--[if lt IE 7]> <p style="border: 1px solid #880000; padding: 1em; background: #ffee88; font-size: 120%;"> Splinter Patch Review requires a modern browser, such as <a href="https://www.mozilla.org/firefox/">Firefox</a>, for correct operation. </p> <![endif]--> <div id="helpful-links"> <a id='helpLink' target='splinterHelp' href="/page.cgi?id=splinter/help.html"> [help]</a> </div> <div id="bugInfo" style="display: none;"> <b>Bug <a id="bugLink"><span id="bugId"></span></a>:</b> <span id="bugShortDesc"></span> - <span id="bugReporter"></span> - <span id="bugCreationDate"></span> </div> <div id="attachInfo" style="display:none;"> <span id="attachWarning"></span> <b>Attachment <a id="attachLink"><span id="attachId"></span></a>:</b> <span id="attachDesc"></span> - <span id="attachCreator"></span> - <span id="attachDate"></span> <a href="/attachment.cgi?id=525557&amp;action=diff" target="_blank">[diff]</a> <a href="/attachment.cgi?id=525557&amp;action=edit" target="_blank">[details]</a> <p> <b>Comment:</b><br> <span id="attachComment"></span> </p> </div> <div id="error" style="display: none;"> </div> <div id="enterBug" style="display: none;">Bug to review: <input id="enterBugInput"> <input id="enterBugGo" type="button" value="Go"> <div id="chooseReview" style="display: none;"> Drafts and published reviews: <div id="chooseReviewTable"></div> </div> </div> <div id="chooseAttachment" style="display: none;"> <div id="chooseAttachmentTable"></div> </div> <div id="quickHelpShow" style="display:none;"> <p> <a href="javascript:Splinter.quickHelpToggle();" title="Show the quick help section" id="quickHelpToggle"> Show Quick Help</a> </p> </div> <div id="quickHelpContent" style="display:none;"> <p> <a href="javascript:Splinter.quickHelpToggle();" title="Hide the quick help section" id="quickHelpToggle">Close Quick Help</a> </p> <ul id="quickHelpList"> <li>From the Overview page, you can add a more generic overview comment that will appear at the beginning of your review.</li> <li>To comment on a specific lines in the patch, first select the filename from the file navigation links.</li> <li>Then double click the line you want to review and a comment box will appear below the line.</li> <li>When the review is complete and you publish it, the overview comment and all line specific comments with their context, will be combined together into a single review comment on the bug report.</li> <li>For more detailed instructions, read the Splinter <a id='helpLink' target='splinterHelp' href="/page.cgi?id=splinter/help.html">help page</a>. </li> </ul> </div> <div id="navigationContainer" style="display: none;"> <b>Navigation:</b> <span id="navigation"></span> </div> <div id="overview" style="display: none;"> <div id="patchIntro"></div> <div> <span id="restored" style="display: none;"> (Restored from draft; last edited <span id="restoredLastModified"></span>) </span> </div> <div> You must be logged in to review patches. </div> <div id="oldReviews" style="display: none;"> <div class="review-title"> Previous Reviews </div> </div> </div> <div id="splinter-files" style="display: none;"> <div id="file-collapse-all" style="display:none;"> <a href="javascript:void(0);" onclick="Splinter.toggleCollapsed('', 'none')">Collapse All</a> | <a href="javascript:void(0);" onclick="Splinter.toggleCollapsed('', 'block')">Expand All</a> </div> </div> <div id="credits"> Powered by <a href="http://fishsoup.net/software/splinter">Splinter</a> </div> <div id="saveDraftNotice" style="display: none;"></div> </div> </main> </div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10