merge fx-team to m-c

This commit is contained in:
Mihai Sucan 2012-05-31 21:46:33 +03:00
commit dfa577d0f7
599 changed files with 5376 additions and 10691 deletions

View File

@ -19,7 +19,7 @@ interface nsIAccessiblePivotObserver;
* provides traversal methods to move the pivot to next/prev state that complies
* to a given rule.
*/
[scriptable, uuid(689058ae-e301-444f-acb0-b5c2b189f350)]
[scriptable, uuid(15ff23de-879e-47ea-b536-6532466108c5)]
interface nsIAccessiblePivot : nsISupports
{
const TextBoundaryType CHAR_BOUNDARY = 0;
@ -61,20 +61,32 @@ interface nsIAccessiblePivot : nsISupports
in long aStartOffset, in long aEndOffset);
/**
* Move pivot to next object complying to given traversal rule.
* Move pivot to next object, from current position or given anchor,
* complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @param aRule [in] traversal rule to use.
* @param aAnchor [in] accessible to start search from, if not provided,
* current position will be used.
* @param aIncludeStart [in] include anchor accessible in search.
* @return true on success, false if there are no new nodes to traverse to.
*/
boolean moveNext(in nsIAccessibleTraversalRule aRule);
[optional_argc] boolean moveNext(in nsIAccessibleTraversalRule aRule,
[optional] in nsIAccessible aAnchor,
[optional] in boolean aIncludeStart);
/**
* Move pivot to previous object complying to given traversal rule.
* Move pivot to previous object, from current position or given anchor,
* complying to given traversal rule.
*
* @param aRule [in] traversal rule to use.
* @param aRule [in] traversal rule to use.
* @param aAnchor [in] accessible to start search from, if not provided,
* current position will be used.
* @param aIncludeStart [in] include anchor accessible in search.
* @return true on success, false if there are no new nodes to traverse to.
*/
boolean movePrevious(in nsIAccessibleTraversalRule aRule);
[optional_argc] boolean movePrevious(in nsIAccessibleTraversalRule aRule,
[optional] in nsIAccessible aAnchor,
[optional] in boolean aIncludeStart);
/**
* Move pivot to first object in subtree complying to given traversal rule.

View File

@ -180,17 +180,23 @@ nsAccessiblePivot::SetTextRange(nsIAccessibleText* aTextAccessible,
// Traversal functions
NS_IMETHODIMP
nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule, bool* aResult)
nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule,
nsIAccessible* aAnchor, bool aIncludeStart,
PRUint8 aArgc, bool* aResult)
{
NS_ENSURE_ARG(aResult);
NS_ENSURE_ARG(aRule);
if (mPosition && (mPosition->IsDefunct() ||
!mPosition->Document()->IsInDocument(mPosition)))
*aResult = false;
nsRefPtr<Accessible> anchor =
(aArgc > 0) ? do_QueryObject(aAnchor) : mPosition;
if (anchor && (anchor->IsDefunct() || !IsRootDescendant(anchor)))
return NS_ERROR_NOT_IN_TREE;
nsresult rv = NS_OK;
Accessible* accessible = SearchForward(mPosition, aRule, false, &rv);
Accessible* accessible =
SearchForward(anchor, aRule, (aArgc > 1) ? aIncludeStart : false, &rv);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = accessible;
@ -201,17 +207,24 @@ nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule, bool* aResult)
}
NS_IMETHODIMP
nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule, bool* aResult)
nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule,
nsIAccessible* aAnchor,
bool aIncludeStart,
PRUint8 aArgc, bool* aResult)
{
NS_ENSURE_ARG(aResult);
NS_ENSURE_ARG(aRule);
if (mPosition && (mPosition->IsDefunct() ||
!mPosition->Document()->IsInDocument(mPosition)))
*aResult = false;
nsRefPtr<Accessible> anchor =
(aArgc > 0) ? do_QueryObject(aAnchor) : mPosition;
if (anchor && (anchor->IsDefunct() || !IsRootDescendant(anchor)))
return NS_ERROR_NOT_IN_TREE;
nsresult rv = NS_OK;
Accessible* accessible = SearchBackward(mPosition, aRule, false, &rv);
Accessible* accessible =
SearchBackward(anchor, aRule, (aArgc > 1) ? aIncludeStart : false, &rv);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = accessible;
@ -320,6 +333,7 @@ nsAccessiblePivot::IsRootDescendant(Accessible* aAccessible)
if (!mRoot || mRoot->IsDefunct())
return false;
// XXX Optimize with IsInDocument() when appropriate. Blocked by bug 759875.
Accessible* accessible = aAccessible;
do {
if (accessible == mRoot)

View File

@ -13,6 +13,7 @@
#include "Role.h"
#include "States.h"
#include "nsContentList.h"
#include "nsIAccessibleRelation.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLInputElement.h"
@ -22,6 +23,7 @@
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMNodeList.h"
#include "nsIEditor.h"
#include "nsIFormControl.h"
#include "nsIFrame.h"
#include "nsINameSpaceManager.h"
#include "nsISelectionController.h"
@ -138,9 +140,8 @@ HTMLRadioButtonAccessible::NativeState()
PRUint64 state = AccessibleWrap::NativeState();
state |= states::CHECKABLE;
bool checked = false; // Radio buttons and check boxes can be checked
bool checked = false; // Radio buttons and check boxes can be checked
nsCOMPtr<nsIDOMHTMLInputElement> htmlRadioElement =
do_QueryInterface(mContent);
if (htmlRadioElement)
@ -156,8 +157,7 @@ void
HTMLRadioButtonAccessible::GetPositionAndSizeInternal(PRInt32* aPosInSet,
PRInt32* aSetSize)
{
nsAutoString nsURI;
mContent->NodeInfo()->GetNamespaceURI(nsURI);
PRInt32 namespaceId = mContent->NodeInfo()->NamespaceID();
nsAutoString tagName;
mContent->NodeInfo()->GetName(tagName);
@ -166,43 +166,30 @@ HTMLRadioButtonAccessible::GetPositionAndSizeInternal(PRInt32* aPosInSet,
nsAutoString name;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMNodeList> inputs;
nsRefPtr<nsContentList> inputElms;
nsCOMPtr<nsIDOMHTMLInputElement> radio(do_QueryInterface(mContent));
nsCOMPtr<nsIDOMHTMLFormElement> form;
radio->GetForm(getter_AddRefs(form));
if (form) {
form->GetElementsByTagNameNS(nsURI, tagName, getter_AddRefs(inputs));
} else {
nsIDocument* doc = mContent->OwnerDoc();
nsCOMPtr<nsIDOMDocument> document(do_QueryInterface(doc));
if (document)
document->GetElementsByTagNameNS(nsURI, tagName, getter_AddRefs(inputs));
}
nsCOMPtr<nsIFormControl> formControlNode(do_QueryInterface(mContent));
dom::Element* formElm = formControlNode->GetFormElement();
if (formElm)
inputElms = NS_GetContentList(formElm, namespaceId, tagName);
else
inputElms = NS_GetContentList(mContent->OwnerDoc(), namespaceId, tagName);
NS_ENSURE_TRUE(inputElms, );
NS_ENSURE_TRUE(inputs, );
PRUint32 inputsCount = 0;
inputs->GetLength(&inputsCount);
PRUint32 inputCount = inputElms->Length(false);
// Compute posinset and setsize.
PRInt32 indexOf = 0;
PRInt32 count = 0;
for (PRUint32 index = 0; index < inputsCount; index++) {
nsCOMPtr<nsIDOMNode> itemNode;
inputs->Item(index, getter_AddRefs(itemNode));
nsCOMPtr<nsIContent> item(do_QueryInterface(itemNode));
if (item &&
item->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
type, eCaseMatters) &&
item->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
name, eCaseMatters)) {
for (PRUint32 index = 0; index < inputCount; index++) {
nsIContent* inputElm = inputElms->Item(index, false);
if (inputElm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
type, eCaseMatters) &&
inputElm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
name, eCaseMatters)) {
count++;
if (item == mContent)
if (inputElm == mContent)
indexOf = count;
}
}

View File

@ -217,6 +217,11 @@ var AccessFu = {
let position = pivot.position;
let doc = aEvent.DOMNode;
let presenterContext =
new PresenterContext(position, event.oldAccessible);
this.presenters.forEach(
function(p) { p.pivotChanged(presenterContext); });
if (position && position.DOMNode &&
doc instanceof Ci.nsIDOMDocument) {
// Set the caret to the start of the pivot position, and move
@ -230,11 +235,6 @@ var AccessFu = {
.getService(Ci.nsIFocusManager).moveFocus(
doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
}
let presenterContext = new PresenterContext(pivot.position,
event.oldAccessible);
this.presenters.forEach(
function(p) { p.pivotChanged(presenterContext); });
break;
}
case Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE:

View File

@ -0,0 +1,192 @@
// screen.js:
// Set the screen size, pixel density and scaling of the b2g client screen
// based on the --screen command-line option, if there is one.
//
// TODO: support multiple device pixels per CSS pixel
//
// We do this on ContentStart because querying the displayDPI fails otherwise.
window.addEventListener('ContentStart', function() {
// This is the toplevel <window> element
let shell = document.getElementById('shell');
// The <browser> element inside it
let browser = document.getElementById('homescreen');
// Figure out the native resolution of the screen
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
let hostDPI = windowUtils.displayDPI;
// This is a somewhat random selection of named screens.
// Add more to this list when we support more hardware.
// Data from: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
let screens = {
iphone: {
name: 'Apple iPhone', width:320, height:480, dpi:163
},
ipad: {
name: 'Apple iPad', width:1024, height:768, dpi:132
},
nexus_s: {
name: 'Samsung Nexus S', width:480, height:800, dpi:235
},
galaxy_s2: {
name: 'Samsung Galaxy SII (I9100)', width:480, height:800, dpi:219
},
galaxy_nexus: {
name: 'Samsung Galaxy Nexus', width:720, height:1280, dpi:316
},
galaxy_tab: {
name: 'Samsung Galaxy Tab 10.1', width:800, height:1280, dpi:149
},
wildfire: {
name: 'HTC Wildfire', width:240, height:320, dpi:125
},
tattoo: {
name: 'HTC Tattoo', width:240, height:320, dpi:143
},
salsa: {
name: 'HTC Salsa', width:320, height:480, dpi:170
},
chacha: {
name: 'HTC ChaCha', width:320, height:480, dpi:222
},
};
// Get the command line arguments that were passed to the b2g client
let args = window.arguments[0].QueryInterface(Ci.nsICommandLine);
let screenarg;
// Get the --screen argument from the command line
try {
screenarg = args.handleFlagWithParam('screen', false);
// If there isn't one, we don't need to do anything
if (screenarg === null)
return;
// With no value, tell the user how to use it
if (screenarg == '')
usage();
}
catch(e) {
// If getting the argument value fails, its an error
usage();
}
// Special case --screen=full goes into fullscreen mode
if (screenarg === 'full') {
shell.setAttribute('sizemode', 'fullscreen');
return;
}
let rescale = false;
// If the value of --screen ends with !, we'll be scaling the output
if (screenarg[screenarg.length - 1] === '!') {
rescale = true;
screenarg = screenarg.substring(0, screenarg.length-1);
}
let width, height, dpi;
if (screenarg in screens) {
// If this is a named screen, get its data
let screen = screens[screenarg];
width = screen.width;
height = screen.height;
dpi = screen.dpi;
} else {
// Otherwise, parse the resolution and density from the --screen value.
// The supported syntax is WIDTHxHEIGHT[@DPI]
let match = screenarg.match(/^(\d+)x(\d+)(@(\d+))?$/);
// Display usage information on syntax errors
if (match == null)
usage();
// Convert strings to integers
width = parseInt(match[1], 10);
height = parseInt(match[2], 10);
if (match[4])
dpi = parseInt(match[4], 10);
else // If no DPI, use the actual dpi of the host screen
dpi = hostDPI;
// If any of the values came out 0 or NaN or undefined, display usage
if (!width || !height || !dpi)
usage();
}
// In order to do rescaling, we set the <browser> tag to the specified
// width and height, and then use a CSS transform to scale it so that
// it appears at the correct size on the host display. We also set
// the size of the <window> element to that scaled target size.
let scale = rescale ? hostDPI / dpi : 1;
// Set the window width and height to desired size plus chrome
let chromewidth = window.outerWidth - window.innerWidth;
let chromeheight = window.outerHeight - window.innerHeight;
window.resizeTo(Math.round(width * scale) + chromewidth,
Math.round(height * scale) + chromeheight);
// Set the browser element to the full unscaled size of the screen
browser.style.width = browser.style.minWidth = browser.style.maxWidth =
width + 'px';
browser.style.height = browser.style.minHeight = browser.style.maxHeight =
height + 'px';
browser.setAttribute('flex', '0'); // Don't let it stretch
// Now scale the browser element as needed
if (scale !== 1) {
browser.style.MozTransformOrigin = 'top left';
browser.style.MozTransform = 'scale(' + scale + ',' + scale + ')';
}
// Set the pixel density that we want to simulate.
// This doesn't change the on-screen size, but makes
// CSS media queries and mozmm units work right.
Services.prefs.setIntPref('layout.css.dpi', dpi);
// A utility function like console.log() for printing to the terminal window
// Uses dump(), but enables it first, if necessary
function print() {
let dump_enabled =
Services.prefs.getBoolPref('browser.dom.window.dump.enabled');
if (!dump_enabled)
Services.prefs.setBoolPref('browser.dom.window.dump.enabled', true);
dump(Array.prototype.join.call(arguments, ' ') + '\n');
if (!dump_enabled)
Services.prefs.setBoolPref('browser.dom.window.dump.enabled', false);
}
// Print usage info for --screen and exit
function usage() {
// Documentation for the --screen argument
let msg =
'The --screen argument specifies the desired resolution and\n' +
'pixel density of the simulated device screen. Use it like this:\n' +
'\t--screen=WIDTHxHEIGHT\t\t\t// E.g.: --screen=320x480\n' +
'\t--screen=WIDTHxHEIGHT@DOTS_PER_INCH\t// E.g.: --screen=480x800@250\n' +
'\t--screen=full\t\t\t\t// run in fullscreen mode\n' +
'\nYou can also specify certain device names:\n';
for(let p in screens)
msg += '\t--screen=' + p + '\t// ' + screens[p].name + '\n';
msg +=
'\nAdd a ! to the end of a screen specification to rescale the\n' +
'screen so that it is shown at actual size on your monitor:\n' +
'\t--screen=nexus_s!\n' +
'\t--screen=320x480@200!\n'
;
// Display the usage message
print(msg);
// Exit the b2g client
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
}
});

View File

@ -6,17 +6,19 @@
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="shell"
width="480" height="800"
windowtype="navigator:browser"
#ifdef ANDROID
sizemode="fullscreen"
#endif
style="background: black; overflow: hidden;"
style="background: black; overflow: hidden; width:480px; height:800px"
onload="shell.start();"
onunload="shell.stop();">
<script type="application/javascript" src="chrome://browser/content/shell.js"/>
#ifndef ANDROID
<!-- this script handles the screen argument for desktop builds -->
<script type="application/javascript" src="chrome://browser/content/screen.js"/>
#endif
<browser id="homescreen"
type="content-primary"
flex="1"

View File

@ -11,6 +11,9 @@ chrome.jar:
content/dbg-browser-actors.js (content/dbg-browser-actors.js)
* content/shell.xul (content/shell.xul)
* content/shell.js (content/shell.js)
#ifndef ANDROID
content/screen.js (content/screen.js)
#endif
content/webapi.js (content/webapi.js)
content/content.css (content/content.css)
content/touchcontrols.css (content/touchcontrols.css)

View File

@ -13,7 +13,6 @@ DIRS = profile/extensions
dist_dest = $(DIST)/$(MOZ_MACBUNDLE_NAME)
PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
$(srcdir)/profile/channel-prefs.js \
$(NULL)
@ -138,6 +137,11 @@ endif
libs:: $(srcdir)/profile/prefs.js
$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile
# channel-prefs.js is handled separate from other prefs due to bug 756325
libs:: $(srcdir)/profile/channel-prefs.js
$(NSINSTALL) -D $(DIST)/bin/defaults/pref
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(ACDEFINES) $^ > $(DIST)/bin/defaults/pref/channel-prefs.js
libs:: $(srcdir)/blocklist.xml
$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin

View File

@ -491,10 +491,19 @@ pref("browser.gesture.pinch.threshold", 150);
pref("browser.gesture.pinch.latched", false);
pref("browser.gesture.pinch.threshold", 25);
#endif
#ifdef XP_WIN
// Enabled for touch input display zoom.
pref("browser.gesture.pinch.out", "cmd_fullZoomEnlarge");
pref("browser.gesture.pinch.in", "cmd_fullZoomReduce");
pref("browser.gesture.pinch.out.shift", "cmd_fullZoomReset");
pref("browser.gesture.pinch.in.shift", "cmd_fullZoomReset");
#else
// Disabled by default due to issues with track pad input.
pref("browser.gesture.pinch.out", "");
pref("browser.gesture.pinch.in", "");
pref("browser.gesture.pinch.out.shift", "");
pref("browser.gesture.pinch.in.shift", "");
#endif
pref("browser.gesture.twist.latched", false);
pref("browser.gesture.twist.threshold", 25);
pref("browser.gesture.twist.right", "");

View File

@ -1109,10 +1109,13 @@ let PlacesToolbarHelper = {
return;
// If the bookmarks toolbar item is hidden because the parent toolbar is
// collapsed or hidden (i.e. in a popup), spare the initialization.
// collapsed or hidden (i.e. in a popup), spare the initialization. Also,
// there is no need to initialize the toolbar if customizing because
// init() will be called when the customization is done.
let toolbar = viewElt.parentNode.parentNode;
if (toolbar.collapsed ||
getComputedStyle(toolbar, "").display == "none")
getComputedStyle(toolbar, "").display == "none" ||
this._isCustomizing)
return;
new PlacesToolbar(this._place);
@ -1122,9 +1125,12 @@ let PlacesToolbarHelper = {
let viewElt = this._viewElt;
if (viewElt && viewElt._placesView)
viewElt._placesView.uninit();
this._isCustomizing = true;
},
customizeDone: function PTH_customizeDone() {
this._isCustomizing = false;
this.init();
}
};

View File

@ -653,8 +653,7 @@ function grabAll(elem)
};
addImgFunc(gStrings.mediaBGImg, computedStyle.getPropertyCSSValue("background-image"));
addImgFunc(gStrings.mediaBorderImg, computedStyle.getPropertyCSSValue("-moz-border-image-source"));
// TODO: support unprefixed "border-image" once bug 713643 is fixed.
addImgFunc(gStrings.mediaBorderImg, computedStyle.getPropertyCSSValue("border-image-source"));
addImgFunc(gStrings.mediaListImg, computedStyle.getPropertyCSSValue("list-style-image"));
addImgFunc(gStrings.mediaCursor, computedStyle.getPropertyCSSValue("cursor"));
}

View File

@ -1,7 +1,5 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
// test the main (normal) browser window
testCustomize(window, testChromeless);
}

View File

@ -1,7 +1,5 @@
function test() {
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
testCustomize(window, finish);
}

View File

@ -1,7 +1,6 @@
function test()
{
waitForExplicitFinish();
ignoreAllUncaughtExceptions();
var frame = document.getElementById("customizeToolbarSheetIFrame");
frame.addEventListener("load", testCustomizeFrameLoadedPre, true);

View File

@ -30,7 +30,7 @@ private:
nsRefPtr<IUrlHistoryStg2> mIEHistory;
nsRefPtr<IEnumSTATURL> mURLEnumerator;
nsRefPtr<nsIWritablePropertyBag2> mCachedNextEntry;
nsCOMPtr<nsIWritablePropertyBag2> mCachedNextEntry;
};
#endif

View File

@ -1241,14 +1241,13 @@ PlacesToolbar.prototype = {
this._removeChild(elt);
this._rootElt.insertBefore(elt, this._rootElt.childNodes[aNewIndex]);
// If the chevron popup is open, keep it in sync.
if (this._chevron.open) {
let chevronPopup = this._chevronPopup;
let menuitem = chevronPopup.childNodes[aOldIndex];
chevronPopup.removeChild(menuitem);
chevronPopup.insertBefore(menuitem,
chevronPopup.childNodes[aNewIndex]);
}
// The chevron view may get nodeMoved after the toolbar. In such a case,
// we should ensure (by manually swapping menuitems) that the actual nodes
// are in the final position before updateChevron tries to updates their
// visibility, or the chevron may go out of sync.
// Luckily updateChevron runs on a timer, so, by the time it updates
// nodes, the menu has already handled the notification.
this.updateChevron();
return;
}

View File

@ -92,9 +92,10 @@
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.removeObserver(this, "browser-search-engine-modified");
this._addedObserver = false;
}
// Make sure to break the cycle from _texbox to us. Otherwise we leak
// Make sure to break the cycle from _textbox to us. Otherwise we leak
// the world. But make sure it's actually pointing to us.
if (this._textbox.mController.input == this)
this._textbox.mController.input = null;

View File

@ -509,13 +509,14 @@
; All the pref files must be part of base to prevent migration bugs
@BINPATH@/@PREF_DIR@/firefox.js
@BINPATH@/@PREF_DIR@/firefox-branding.js
@BINPATH@/@PREF_DIR@/channel-prefs.js
#ifdef MOZ_SERVICES_SYNC
@BINPATH@/@PREF_DIR@/services-sync.js
#endif
@BINPATH@/greprefs.js
@BINPATH@/defaults/autoconfig/platform.js
@BINPATH@/defaults/autoconfig/prefcalls.js
; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325)
@BINPATH@/defaults/pref/channel-prefs.js
@BINPATH@/defaults/profile/prefs.js
; [Layout Engine Resources]

View File

@ -1,7 +1,3 @@
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
; IMPORTANT: This file should always start with a newline in case a locale
; provided updater.ini does not end with a newline.

View File

@ -1425,11 +1425,18 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
#page-proxy-favicon {
width: 16px;
height: 16px;
margin: 1px 3px;
margin-top: 1px;
margin-bottom: 1px;
-moz-margin-start: 3px;
-moz-margin-end: 2px;
list-style-image: url(chrome://browser/skin/identity-icons-generic.png);
-moz-image-region: rect(0, 16px, 16px, 0);
}
@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar > #identity-box > #identity-box-inner > #page-proxy-stack > #page-proxy-favicon {
-moz-margin-end: 1px;
}
.verifiedDomain > #identity-box-inner > #page-proxy-stack > #page-proxy-favicon[pageproxystate="valid"] {
list-style-image: url(chrome://browser/skin/identity-icons-https.png);
}

View File

@ -831,7 +831,9 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
JS_SetOptions(cx, JS_GetOptions(cx) |
JSOPTION_PRIVATE_IS_NSISUPPORTS |
JSOPTION_ALLOW_XML);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, ContentScriptErrorReporter);

View File

@ -2187,6 +2187,7 @@ nsObjectLoadingContent::DoStopPlugin(nsPluginInstanceOwner* aInstanceOwner,
}
mIsStopping = true;
nsRefPtr<nsPluginInstanceOwner> kungFuDeathGrip(aInstanceOwner);
nsRefPtr<nsNPAPIPluginInstance> inst;
aInstanceOwner->GetInstance(getter_AddRefs(inst));
if (inst) {

View File

@ -468,11 +468,11 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
return false;
} else {
if (value.Length() == 1 && value[0] == '1')
// This means that we need to set JSOPTION_XML in the JS options.
// We re-use our knowledge of the implementation to reuse
// JSVERSION_HAS_XML as a safe version flag.
// If version has JSVERSION_UNKNOWN (-1), then this is still OK.
version = js::VersionSetXML(JSVersion(version), true);
// This happens in about 2 web pages. Enable E4X no matter what JS
// version number was selected. We do this by turning on the "moar
// XML" version bit. This is OK even if version has
// JSVERSION_UNKNOWN (-1).
version = js::VersionSetMoarXML(JSVersion(version), true);
}
}
} else {

View File

@ -153,7 +153,7 @@ WebGLContext::WebGLContext()
mContextStatus = ContextStable;
mContextLostErrorSet = false;
mAlreadyReportedMessages = 0;
mAlreadyGeneratedWarnings = 0;
}
WebGLContext::~WebGLContext()
@ -911,25 +911,27 @@ WebGLContext::GetExtension(const nsAString& aName)
return nsnull;
}
// handle simple extensions that don't need custom objects first
nsString lowerCaseName(aName);
ToLowerCase(lowerCaseName);
WebGLExtensionID ei = WebGLExtensionID_Max;
if (aName.EqualsLiteral("OES_texture_float")) {
if (lowerCaseName.EqualsLiteral("oes_texture_float")) {
if (IsExtensionSupported(WebGL_OES_texture_float))
ei = WebGL_OES_texture_float;
}
else if (aName.EqualsLiteral("OES_standard_derivatives")) {
else if (lowerCaseName.EqualsLiteral("oes_standard_derivatives")) {
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives;
}
else if (aName.EqualsLiteral("MOZ_EXT_texture_filter_anisotropic")) {
else if (lowerCaseName.EqualsLiteral("moz_ext_texture_filter_anisotropic")) {
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
ei = WebGL_EXT_texture_filter_anisotropic;
}
else if (aName.EqualsLiteral("MOZ_WEBGL_lose_context")) {
else if (lowerCaseName.EqualsLiteral("moz_webgl_lose_context")) {
if (IsExtensionSupported(WebGL_WEBGL_lose_context))
ei = WebGL_WEBGL_lose_context;
}
else if (aName.EqualsLiteral("MOZ_WEBGL_compressed_texture_s3tc")) {
else if (lowerCaseName.EqualsLiteral("moz_webgl_compressed_texture_s3tc")) {
if (IsExtensionSupported(WebGL_WEBGL_compressed_texture_s3tc))
ei = WebGL_WEBGL_compressed_texture_s3tc;
}

View File

@ -740,11 +740,13 @@ public:
WebGLenum pname,
ErrorResult& rv);
JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname);
void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval, ErrorResult& rv);
void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval, ErrorResult& rv);
JS::Value GetRenderbufferParameter(WebGLenum target, WebGLenum pname);
JS::Value GetShaderParameter(WebGLShader *shader, WebGLenum pname);
already_AddRefed<WebGLShaderPrecisionFormat>
GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype);
void GetShaderInfoLog(WebGLShader *shader, nsACString& retval, ErrorResult& rv);
void GetShaderInfoLog(WebGLShader *shader, nsAString& retval, ErrorResult& rv);
void GetShaderSource(WebGLShader *shader, nsAString& retval);
JS::Value GetTexParameter(WebGLenum target, WebGLenum pname);
@ -1293,7 +1295,11 @@ protected:
ContextStatus mContextStatus;
bool mContextLostErrorSet;
int mAlreadyReportedMessages;
int mAlreadyGeneratedWarnings;
bool ShouldGenerateWarnings() const {
return mAlreadyGeneratedWarnings < 32;
}
#ifdef XP_MACOSX
// see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime

View File

@ -2993,6 +2993,18 @@ WebGLContext::GetProgramInfoLog(nsIWebGLProgram *pobj, nsAString& retval)
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval,
ErrorResult& rv)
{
nsCAutoString s;
GetProgramInfoLog(prog, s, rv);
if (s.IsVoid())
retval.SetIsVoid(true);
else
CopyASCIItoUTF16(s, retval);
}
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval,
ErrorResult& rv)
{
if (!IsContextStable())
{
@ -3012,8 +3024,10 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval,
GLint k = -1;
gl->fGetProgramiv(progname, LOCAL_GL_INFO_LOG_LENGTH, &k);
if (k == -1) {
// XXX GL error? shouldn't happen!
rv = NS_ERROR_FAILURE;
// If GetProgramiv doesn't modify |k|,
// it's because there was a GL error.
// GetProgramInfoLog should return null on error. (Bug 746740)
retval.SetIsVoid(true);
return;
}
@ -3022,14 +3036,9 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval,
return;
}
nsCAutoString log;
log.SetCapacity(k);
gl->fGetProgramInfoLog(progname, k, &k, (char*) log.BeginWriting());
log.SetLength(k);
CopyASCIItoUTF16(log, retval);
retval.SetCapacity(k);
gl->fGetProgramInfoLog(progname, k, &k, (char*) retval.BeginWriting());
retval.SetLength(k);
}
// here we have to support all pnames with both int and float params.
@ -3685,6 +3694,8 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
}
if (!program->HasBothShaderTypesAttached()) {
GenerateWarning("linkProgram: this program doesn't have both a vertex shader"
" and a fragment shader");
program->SetLinkStatus(false);
return;
}
@ -3697,8 +3708,64 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
if (ok) {
bool updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
// Bug 750527
if (gl->WorkAroundDriverBugs() &&
updateInfoSucceeded &&
gl->Vendor() == gl::GLContext::VendorNVIDIA)
{
if (program == mCurrentProgram)
gl->fUseProgram(progname);
}
} else {
program->SetLinkStatus(false);
if (ShouldGenerateWarnings()) {
// report shader/program infoLogs as warnings.
// note that shader compilation errors can be deferred to linkProgram,
// which is why we can't do anything in compileShader. In practice we could
// report in compileShader the translation errors generated by ANGLE,
// but it seems saner to keep a single way of obtaining shader infologs.
ErrorResult rv;
nsCAutoString log;
bool alreadyReportedShaderInfoLog = false;
for (size_t i = 0; i < program->AttachedShaders().Length(); i++) {
WebGLShader* shader = program->AttachedShaders()[i];
GetShaderInfoLog(shader, log, rv);
if (rv.Failed() || log.IsEmpty())
continue;
const char *shaderTypeName = nsnull;
if (shader->ShaderType() == LOCAL_GL_VERTEX_SHADER) {
shaderTypeName = "vertex";
} else if (shader->ShaderType() == LOCAL_GL_FRAGMENT_SHADER) {
shaderTypeName = "fragment";
} else {
// should have been validated earlier
NS_ABORT();
shaderTypeName = "<unknown>";
}
GenerateWarning("linkProgram: a %s shader used in this program failed to "
"compile, with this log:\n%s\n",
shaderTypeName,
log.get());
alreadyReportedShaderInfoLog = true;
}
if (!alreadyReportedShaderInfoLog) {
GetProgramInfoLog(program, log, rv);
if (!(rv.Failed() || log.IsEmpty())) {
GenerateWarning("linkProgram failed, with this log:\n%s\n",
log.get());
}
}
}
}
}
@ -5232,6 +5299,18 @@ WebGLContext::GetShaderInfoLog(nsIWebGLShader *sobj, nsAString& retval)
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
ErrorResult& rv)
{
nsCAutoString s;
GetShaderInfoLog(shader, s, rv);
if (s.IsVoid())
retval.SetIsVoid(true);
else
CopyASCIItoUTF16(s, retval);
}
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval,
ErrorResult& rv)
{
if (!IsContextStable())
{
@ -5242,9 +5321,8 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
if (!ValidateObject("getShaderInfoLog: shader", shader))
return;
const nsCString& tlog = shader->TranslationLog();
if (!tlog.IsVoid()) {
CopyASCIItoUTF16(tlog, retval);
retval = shader->TranslationLog();
if (!retval.IsVoid()) {
return;
}
@ -5262,14 +5340,9 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
return;
}
nsCAutoString log;
log.SetCapacity(k);
gl->fGetShaderInfoLog(shadername, k, &k, (char*) log.BeginWriting());
log.SetLength(k);
CopyASCIItoUTF16(log, retval);
retval.SetCapacity(k);
gl->fGetShaderInfoLog(shadername, k, &k, (char*) retval.BeginWriting());
retval.SetLength(k);
}
NS_IMETHODIMP

View File

@ -45,12 +45,10 @@ WebGLContext::GenerateWarning(const char *fmt, ...)
void
WebGLContext::GenerateWarning(const char *fmt, va_list ap)
{
const int MaxReportedMessages = 32;
if (mAlreadyReportedMessages >= MaxReportedMessages)
if (!ShouldGenerateWarnings())
return;
mAlreadyReportedMessages++;
mAlreadyGeneratedWarnings++;
char buf[1024];
PR_vsnprintf(buf, 1024, fmt, ap);
@ -61,10 +59,10 @@ WebGLContext::GenerateWarning(const char *fmt, va_list ap)
JSContext* ccx = nsnull;
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
JS_ReportWarning(ccx, "WebGL: %s", buf);
if (mAlreadyReportedMessages == MaxReportedMessages) {
if (!ShouldGenerateWarnings()) {
JS_ReportWarning(ccx,
"WebGL: no further warnings will be reported for this WebGL context "
"(already reported %d warnings)", mAlreadyReportedMessages);
"WebGL: No further warnings will be reported for this WebGL context "
"(already reported %d warnings)", mAlreadyGeneratedWarnings);
}
}
}

View File

@ -54,7 +54,7 @@ WebGLProgram::UpdateInfo()
if (loc < mContext->mGLMaxVertexAttribs) {
mAttribsInUse[loc] = true;
} else {
mContext->ErrorInvalidOperation("program exceeds MAX_VERTEX_ATTRIBS");
mContext->GenerateWarning("program exceeds MAX_VERTEX_ATTRIBS");
return false;
}
}

View File

@ -153,7 +153,11 @@ public:
// Called by the media stream, on the main thread, when the download
// has been resumed by the cache or because the element itself
// asked the decoder to resumed the download.
void DownloadResumed();
// If aForceNetworkLoading is True, ignore the fact that the download has
// previously finished. We are downloading the middle of the media after
// having downloaded the end, we need to notify the element a download in
// ongoing.
void DownloadResumed(bool aForceNetworkLoading = false);
// Called by the media decoder to indicate that the download has stalled
// (no data has arrived for a while).

View File

@ -549,8 +549,8 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
if (parent &&
parent->GetStylePosition()->mBoxSizing != NS_STYLE_BOX_SIZING_BORDER) {
const nsStyleBorder* border = parent->GetStyleBorder();
origin.x -= border->GetActualBorderWidth(NS_SIDE_LEFT);
origin.y -= border->GetActualBorderWidth(NS_SIDE_TOP);
origin.x -= border->GetComputedBorderWidth(NS_SIDE_LEFT);
origin.y -= border->GetComputedBorderWidth(NS_SIDE_TOP);
}
// XXX We should really consider subtracting out padding for

View File

@ -2779,9 +2779,9 @@ void nsHTMLMediaElement::DownloadSuspended()
}
}
void nsHTMLMediaElement::DownloadResumed()
void nsHTMLMediaElement::DownloadResumed(bool aForceNetworkLoading)
{
if (mBegun) {
if (mBegun || aForceNetworkLoading) {
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
AddRemoveSelfReference();
}

View File

@ -214,8 +214,19 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
// We weren't seeking and got a valid response status,
// set the length of the content.
PRInt32 cl = -1;
hc->GetContentLength(&cl);
PRInt64 cl = -1;
nsCOMPtr<nsIPropertyBag2> bag = do_QueryInterface(hc);
if (bag) {
bag->GetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, &cl);
}
if (cl < 0) {
PRInt32 cl32;
hc->GetContentLength(&cl32);
cl = cl32;
}
if (cl >= 0) {
mCacheStream.NotifyDataLength(cl);
}
@ -451,6 +462,8 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
nsresult rv = mChannel->AsyncOpen(listener, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
// Tell the media element that we are fetching data from a channel.
element->DownloadResumed(true);
}
return NS_OK;

View File

@ -758,7 +758,8 @@ nsOpusState::nsOpusState(ogg_page* aBosPage) :
mGain(0.0),
mChannelMapping(0),
mStreams(0),
mDecoder(NULL)
mDecoder(NULL),
mSkip(0)
{
MOZ_COUNT_CTOR(nsOpusState);
}
@ -780,6 +781,7 @@ nsresult nsOpusState::Reset()
if (mActive && mDecoder) {
// Reset the decoder.
opus_decoder_ctl(mDecoder, OPUS_RESET_STATE);
mSkip = 0; // Let the seek logic handle this.
}
// Clear queued data.
@ -787,6 +789,8 @@ nsresult nsOpusState::Reset()
return NS_ERROR_FAILURE;
}
LOG(PR_LOG_DEBUG, ("Opus decoder reset, to skip %d", mSkip));
return res;
}
@ -797,6 +801,9 @@ bool nsOpusState::Init(void)
NS_ASSERTION(mDecoder == NULL, "leaking OpusDecoder");
mDecoder = opus_decoder_create(mRate, mChannels, &error);
mSkip = mPreSkip;
LOG(PR_LOG_DEBUG, ("Opus decoder init, to skip %d", mSkip));
return error == OPUS_OK;
}
@ -851,6 +858,17 @@ bool nsOpusState::DecodeHeader(ogg_packet* aPacket)
return true;
}
#ifdef DEBUG
LOG(PR_LOG_DEBUG, ("Opus stream header:"));
LOG(PR_LOG_DEBUG, (" channels: %d", mChannels));
LOG(PR_LOG_DEBUG, (" preskip: %d", mPreSkip));
LOG(PR_LOG_DEBUG, (" original: %d Hz", mNominalRate));
LOG(PR_LOG_DEBUG, (" gain: %.2f dB", mGain));
LOG(PR_LOG_DEBUG, ("Channel Mapping:"));
LOG(PR_LOG_DEBUG, (" family: %d", mChannelMapping));
LOG(PR_LOG_DEBUG, (" streams: %d", mStreams));
#endif
return true;
}

View File

@ -314,6 +314,7 @@ public:
int mStreams; // Number of packed streams in each packet.
OpusDecoder *mDecoder;
int mSkip; // Number of samples left to trim before playback.
private:

View File

@ -100,6 +100,11 @@ nsresult nsOggReader::Init(nsBuiltinDecoderReader* aCloneDonor) {
}
nsresult nsOggReader::ResetDecode()
{
return ResetDecode(false);
}
nsresult nsOggReader::ResetDecode(bool start)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
nsresult res = NS_OK;
@ -113,8 +118,17 @@ nsresult nsOggReader::ResetDecode()
if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
res = NS_ERROR_FAILURE;
}
if (mOpusState && NS_FAILED(mOpusState->Reset())) {
res = NS_ERROR_FAILURE;
if (mOpusState) {
if (NS_FAILED(mOpusState->Reset())) {
res = NS_ERROR_FAILURE;
}
else if (start) {
// Reset the skip frame counter as if
// we're starting playback fresh.
mOpusState->mSkip = mOpusState->mPreSkip;
LOG(PR_LOG_DEBUG, ("Seek to start: asking opus decoder to skip %d",
mOpusState->mSkip));
}
}
if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
res = NS_ERROR_FAILURE;
@ -378,6 +392,7 @@ nsresult nsOggReader::DecodeVorbis(ogg_packet* aPacket) {
nsresult nsOggReader::DecodeOpus(ogg_packet* aPacket) {
NS_ASSERTION(aPacket->granulepos != -1, "Must know opus granulepos!");
// Maximum value is 63*2880.
PRInt32 frames = opus_decoder_get_nb_samples(mOpusState->mDecoder,
aPacket->packet,
aPacket->bytes);
@ -405,23 +420,32 @@ nsresult nsOggReader::DecodeOpus(ogg_packet* aPacket) {
PRInt64 startTime = mOpusState->Time(endFrame - frames);
PRInt64 duration = endTime - startTime;
// Trim the initial samples.
if (endTime < 0)
return NS_OK;
if (startTime < 0) {
PRInt32 skip = mOpusState->mPreSkip;
PRInt32 goodFrames = frames - skip;
NS_ASSERTION(goodFrames > 0, "endTime calculation was wrong");
nsAutoArrayPtr<AudioDataValue> goodBuffer(new AudioDataValue[goodFrames * channels]);
for (PRInt32 i = 0; i < goodFrames * PRInt32(channels); i++)
goodBuffer[i] = buffer[skip*channels + i];
// Trim the initial frames while the decoder is settling.
if (mOpusState->mSkip > 0) {
PRInt32 skipFrames = NS_MIN(mOpusState->mSkip, frames);
if (skipFrames == frames) {
// discard the whole packet
mOpusState->mSkip -= frames;
LOG(PR_LOG_DEBUG, ("Opus decoder skipping %d frames"
" (whole packet)", frames));
return NS_OK;
}
PRInt32 keepFrames = frames - skipFrames;
int samples = keepFrames * channels;
nsAutoArrayPtr<AudioDataValue> trimBuffer(new AudioDataValue[samples]);
for (int i = 0; i < samples; i++)
trimBuffer[i] = buffer[skipFrames*channels + i];
startTime = mOpusState->Time(endFrame - goodFrames);
startTime = mOpusState->Time(endFrame - keepFrames);
duration = endTime - startTime;
frames = goodFrames;
buffer = goodBuffer;
frames = keepFrames;
buffer = trimBuffer;
mOpusState->mSkip -= skipFrames;
LOG(PR_LOG_DEBUG, ("Opus decoder skipping %d frames", skipFrames));
}
LOG(PR_LOG_DEBUG, ("Opus decoder pushing %d frames", frames));
mAudioQueue.Push(new AudioData(mPageOffset,
startTime,
duration,
@ -1086,7 +1110,7 @@ nsresult nsOggReader::Seek(PRInt64 aTarget,
NS_ENSURE_SUCCESS(res,res);
mPageOffset = 0;
res = ResetDecode();
res = ResetDecode(true);
NS_ENSURE_SUCCESS(res,res);
NS_ASSERTION(aStartTime != -1, "mStartTime should be known");

View File

@ -58,6 +58,10 @@ public:
private:
// Specialized Reset() method to signal if the seek is
// to the start of the stream.
nsresult ResetDecode(bool start);
bool HasSkeleton() {
return mSkeletonState != 0 && mSkeletonState->mActive;
}

View File

@ -1428,7 +1428,7 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
false);
NS_ENSURE_SUCCESS(rv, rv);
rv = HandleCharacterData(aErrorText, nsCRT::strlen(aErrorText), false);
rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText), false);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString sourcetext(errorNs);
@ -1439,7 +1439,7 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
false);
NS_ENSURE_SUCCESS(rv, rv);
rv = HandleCharacterData(aSourceText, nsCRT::strlen(aSourceText), false);
rv = HandleCharacterData(aSourceText, NS_strlen(aSourceText), false);
NS_ENSURE_SUCCESS(rv, rv);
rv = HandleEndElement(sourcetext.get(), false);

View File

@ -695,7 +695,7 @@ XULContentSinkImpl::ReportError(const PRUnichar* aErrorText,
rv = HandleStartElement(parsererror.get(), noAtts, 0, -1, 0);
NS_ENSURE_SUCCESS(rv,rv);
rv = HandleCharacterData(aErrorText, nsCRT::strlen(aErrorText));
rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText));
NS_ENSURE_SUCCESS(rv,rv);
nsAutoString sourcetext(errorNs);
@ -705,7 +705,7 @@ XULContentSinkImpl::ReportError(const PRUnichar* aErrorText,
rv = HandleStartElement(sourcetext.get(), noAtts, 0, -1, 0);
NS_ENSURE_SUCCESS(rv,rv);
rv = HandleCharacterData(aSourceText, nsCRT::strlen(aSourceText));
rv = HandleCharacterData(aSourceText, NS_strlen(aSourceText));
NS_ENSURE_SUCCESS(rv,rv);
rv = HandleEndElement(sourcetext.get());
@ -917,11 +917,9 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
}
// Some js specifics yet to be abstracted.
if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
// By default scripts in XUL documents have E4X turned on. We use
// our implementation knowledge to reuse JSVERSION_HAS_XML as a
// safe version flag. This is still OK if version is
// JSVERSION_UNKNOWN (-1),
version = js::VersionSetXML(JSVersion(version), true);
// By default scripts in XUL documents have E4X turned on. This
// is still OK if version is JSVERSION_UNKNOWN (-1),
version = js::VersionSetMoarXML(JSVersion(version), true);
nsAutoString value;
rv = parser.GetParameter("e4x", value);
@ -930,7 +928,7 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
return rv;
} else {
if (value.Length() == 1 && value[0] == '0')
version = js::VersionSetXML(JSVersion(version), false);
version = js::VersionSetMoarXML(JSVersion(version), false);
}
}
}
@ -944,7 +942,7 @@ XULContentSinkImpl::OpenScript(const PRUnichar** aAttributes,
// Even when JS version < 1.6 is specified, E4X is
// turned on in XUL.
version = js::VersionSetXML(JSVersion(version), true);
version = js::VersionSetMoarXML(JSVersion(version), true);
}
}
aAttributes += 2;

View File

@ -1531,7 +1531,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionLoseContext, WebGLExtensionSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_ADDPROPERTY)
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionCompressedTextureS3TC, nsDOMGenericSH,
NS_DEFINE_CLASSINFO_DATA(WebGLExtensionCompressedTextureS3TC, WebGLExtensionSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS |
nsIXPCScriptable::WANT_ADDPROPERTY)
@ -5054,7 +5054,7 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto)
// Don't overwrite a property set by content.
JSBool found;
if (!::JS_AlreadyHasOwnUCProperty(cx, global, reinterpret_cast<const jschar*>(mData->mNameUTF16),
nsCRT::strlen(mData->mNameUTF16), &found)) {
NS_strlen(mData->mNameUTF16), &found)) {
return NS_ERROR_FAILURE;
}
@ -5930,7 +5930,7 @@ public:
JSBool ok = JS_WrapValue(cx, &thisAsVal) &&
::JS_DefineUCProperty(cx, target,
reinterpret_cast<const jschar *>(mClassName),
nsCRT::strlen(mClassName), thisAsVal, nsnull,
NS_strlen(mClassName), thisAsVal, nsnull,
nsnull, 0);
return ok ? NS_OK : NS_ERROR_UNEXPECTED;

View File

@ -1616,7 +1616,7 @@ nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
// need to preserve the <!-- script hiding hack from JS-in-HTML daze
// (introduced in 1995 for graceful script degradation in Netscape 1,
// Mosaic, and other pre-JS browsers).
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_XML);
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_MOAR_XML);
}
JSObject* outer = NewOuterWindowProxy(cx, aNewInner->FastGetGlobalJSObject());

View File

@ -954,7 +954,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
useMethodJITAlways = true;
useHardening = false;
}
}
}
if (useMethodJIT)
newDefaultJSOptions |= JSOPTION_METHODJIT;
@ -998,7 +998,8 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
else
newDefaultJSOptions &= ~JSOPTION_RELIMIT;
::JS_SetOptions(context->mContext, newDefaultJSOptions & JSRUNOPTION_MASK);
::JS_SetOptions(context->mContext,
newDefaultJSOptions & (JSRUNOPTION_MASK | JSOPTION_ALLOW_XML));
// Save the new defaults for the next page load (InitContext).
context->mDefaultJSOptions = newDefaultJSOptions;
@ -1030,7 +1031,7 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime)
++sContextCount;
mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS;
mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS | JSOPTION_ALLOW_XML;
mContext = ::JS_NewContext(aRuntime, gStackSize);
if (mContext) {

View File

@ -29,6 +29,11 @@
# * notflattened - The native type does not have nsIClassInfo, so when
# wrapping it the right IID needs to be passed in.
# * register - True if this binding should be registered. Defaults to true.
# * binaryNames - Dict for mapping method and attribute names to different
# names when calling the native methods (defaults to an empty
# dict). The keys are the property names as they appear in the
# .webidl file and the values are the names as they should be
# in the WebIDL.
#
# The following fields are either a string, an array (defaults to an empty
# array) or a dictionary with three possible keys (all, getterOnly and
@ -250,7 +255,10 @@ DOMInterfaces = {
'receiveWeakCastableObjectSequence',
'receiveWeakNullableCastableObjectSequence',
'receiveWeakCastableObjectNullableSequence',
'receiveWeakNullableCastableObjectNullableSequence' ]
'receiveWeakNullableCastableObjectNullableSequence' ],
'binaryNames': { 'methodRenamedFrom': 'methodRenamedTo',
'attributeGetterRenamedFrom': 'attributeGetterRenamedTo',
'attributeRenamedFrom': 'attributeRenamedTo' }
},
'TestNonCastableInterface' : {

View File

@ -578,8 +578,8 @@ class CGClassConstructHook(CGAbstractStaticMethod):
"""
preArgs = ["global"]
name = MakeNativeName(self._ctor.identifier.name)
nativeName = self.descriptor.binaryNames.get(name, name)
name = self._ctor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
callGenerator = CGMethodCall(preArgs, nativeName, True,
self.descriptor, self._ctor)
return preamble + callGenerator.define();
@ -1512,18 +1512,18 @@ for (uint32_t i = 0; i < length; ++i) {
# Either external, or new-binding non-castable. We always have a
# holder for these, because we don't actually know whether we have
# to addref when unwrapping or not. So we just pass an
# getter_AddRefs(nsCOMPtr) to XPConnect and if we'll need a release
# getter_AddRefs(nsRefPtr) to XPConnect and if we'll need a release
# it'll put a non-null pointer in there.
if forceOwningType:
# Don't return a holderType in this case; our declName
# will just own stuff.
templateBody += "nsCOMPtr<" + typeName + "> ${holderName};"
templateBody += "nsRefPtr<" + typeName + "> ${holderName};"
else:
holderType = "nsCOMPtr<" + typeName + ">"
holderType = "nsRefPtr<" + typeName + ">"
templateBody += (
"jsval tmpVal = ${val};\n" +
typePtr + " tmp;\n"
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, getter_AddRefs(${holderName}), &tmpVal))) {\n")
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), &tmpVal))) {\n")
templateBody += CGIndenter(onFailure(failureCode,
descriptor.workers)).define()
templateBody += ("}\n"
@ -2703,7 +2703,7 @@ class CGNativeMethod(CGAbstractBindingMethod):
CGAbstractBindingMethod.__init__(self, descriptor, baseName, args)
def generate_code(self):
name = self.method.identifier.name
nativeName = self.descriptor.binaryNames.get(name, MakeNativeName(name))
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
return CGMethodCall([], nativeName, self.method.isStatic(),
self.descriptor, self.method)
@ -2729,9 +2729,9 @@ class CGNativeGetter(CGAbstractBindingMethod):
CGGeneric("%s* self;" % self.descriptor.nativeType))
def generate_code(self):
nativeMethodName = "Get" + MakeNativeName(self.attr.identifier.name)
return CGIndenter(CGGetterCall(self.attr.type, nativeMethodName, self.descriptor,
name = self.attr.identifier.name
nativeName = "Get" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
return CGIndenter(CGGetterCall(self.attr.type, nativeName, self.descriptor,
self.attr))
class CGNativeSetter(CGAbstractBindingMethod):
@ -2758,8 +2758,9 @@ class CGNativeSetter(CGAbstractBindingMethod):
CGGeneric("%s* self;" % self.descriptor.nativeType))
def generate_code(self):
nativeMethodName = "Set" + MakeNativeName(self.attr.identifier.name)
return CGIndenter(CGSetterCall(self.attr.type, nativeMethodName, self.descriptor,
name = self.attr.identifier.name
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
return CGIndenter(CGSetterCall(self.attr.type, nativeName, self.descriptor,
self.attr))
def getEnumValueName(value):
@ -3459,6 +3460,7 @@ class CGBindingRoot(CGThing):
['mozilla/dom/Nullable.h',
'mozilla/dom/PrimitiveConversions.h',
'XPCQuickStubs.h',
'nsDOMQS.h',
'AccessCheck.h',
'WorkerPrivate.h',
'nsContentUtils.h',

View File

@ -267,6 +267,13 @@ public:
JSObject* ReceiveObject(JSContext*, ErrorResult&);
JSObject* ReceiveNullableObject(JSContext*, ErrorResult&);
// binaryNames tests
void MethodRenamedTo(ErrorResult&);
void MethodRenamedTo(int8_t, ErrorResult&);
int8_t GetAttributeGetterRenamedTo(ErrorResult&);
int8_t GetAttributeRenamedTo(ErrorResult&);
void SetAttributeRenamedTo(int8_t, ErrorResult&);
private:
// We add signatures here that _could_ start matching if the codegen
// got data types wrong. That way if it ever does we'll have a call

View File

@ -211,4 +211,10 @@ interface TestInterface {
void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
object receiveObject();
object? receiveNullableObject();
// binaryNames tests
void methodRenamedFrom();
void methodRenamedFrom(byte argument);
readonly attribute byte attributeGetterRenamedFrom;
attribute byte attributeRenamedFrom;
};

View File

@ -142,6 +142,48 @@ nsDOMDeviceStorage::SetRootFileForType(const nsAString& aType, const PRInt32 aIn
#endif
}
// Video directory
if (aType.Equals(NS_LITERAL_STRING("videos"))) {
#ifdef MOZ_WIDGET_GONK
if (aIndex == 0) {
NS_NewLocalFile(NS_LITERAL_STRING("/data/videos"), false, getter_AddRefs(f));
}
else if (aIndex == 1) {
NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/videos"), false, getter_AddRefs(f));
typeResult = DEVICE_STORAGE_TYPE_EXTERNAL;
}
#elif defined (MOZ_WIDGET_COCOA)
if (aIndex == 0) {
dirService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
}
#elif defined (XP_UNIX)
if (aIndex == 0) {
dirService->Get(NS_UNIX_XDG_VIDEOS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
}
#endif
}
// Music directory
if (aType.Equals(NS_LITERAL_STRING("music"))) {
#ifdef MOZ_WIDGET_GONK
if (aIndex == 0) {
NS_NewLocalFile(NS_LITERAL_STRING("/data/music"), false, getter_AddRefs(f));
}
else if (aIndex == 1) {
NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/music"), false, getter_AddRefs(f));
typeResult = DEVICE_STORAGE_TYPE_EXTERNAL;
}
#elif defined (MOZ_WIDGET_COCOA)
if (aIndex == 0) {
dirService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
}
#elif defined (XP_UNIX)
if (aIndex == 0) {
dirService->Get(NS_UNIX_XDG_MUSIC_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
}
#endif
}
// in testing, we have access to a few more directory locations
if (mozilla::Preferences::GetBool("device.storage.testing", false)) {

View File

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Style
*/
[builtinclass, scriptable, uuid(81085b2d-eea9-4aca-ac93-0b1eea6587d3)]
[builtinclass, scriptable, uuid(08fd9493-9276-4861-9b16-add2653e2f53)]
interface nsIDOMCSS2Properties : nsISupports
{
attribute DOMString background;
@ -608,7 +608,7 @@ interface nsIDOMCSS2Properties : nsISupports
attribute DOMString MozStackSizing;
// raises(DOMException) on setting
attribute DOMString MozBorderImage;
attribute DOMString borderImage;
// raises(DOMException) on setting
attribute DOMString MozColumns;
@ -725,18 +725,21 @@ interface nsIDOMCSS2Properties : nsISupports
attribute DOMString MozTextSizeAdjust;
// raises(DOMException) on setting
attribute DOMString MozBorderImageSource;
attribute DOMString borderImageSource;
// raises(DOMException) on setting
attribute DOMString MozBorderImageSlice;
attribute DOMString borderImageSlice;
// raises(DOMException) on setting
attribute DOMString MozBorderImageWidth;
attribute DOMString borderImageWidth;
// raises(DOMException) on setting
attribute DOMString MozBorderImageOutset;
attribute DOMString borderImageOutset;
// raises(DOMException) on setting
attribute DOMString MozBorderImageRepeat;
attribute DOMString borderImageRepeat;
// raises(DOMException) on setting
attribute DOMString MozBorderImage;
// raises(DOMException) on setting
};

View File

@ -102,6 +102,7 @@ endif
LOCAL_INCLUDES += \
-DSK_BUILD_FOR_ANDROID_NDK \
-I$(topsrcdir)/widget/android \
-I$(topsrcdir)/widget/xpwidgets \
-I$(topsrcdir)/xpcom/base/ \
-I$(topsrcdir)/gfx/skia/include/core \
-I$(topsrcdir)/gfx/skia/include/config \

View File

@ -25,7 +25,7 @@ static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
return NULL;

View File

@ -143,6 +143,14 @@ static bool init() {
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
if (!gSurfaceFunctions.lock) {
// Stuff changed in 3.0/4.0
handle = dlopen("libgui.so", RTLD_LAZY);
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionE");
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
}
handle = dlopen("libui.so", RTLD_LAZY);
if (!handle) {
LOG("Failed to open libui.so");
@ -158,6 +166,7 @@ static bool init() {
return gSurfaceFunctions.initialized;
}
// FIXME: All of this should be changed to use the equivalent things in AndroidBridge, bug 758612
static bool anp_surface_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
if (!bitmap || !surfaceView) {
return false;

View File

@ -3,6 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
@ -11,12 +12,20 @@
#include "nsIPluginInstanceOwner.h"
#include "nsPluginInstanceOwner.h"
#include "nsWindow.h"
#include "mozilla/dom/ScreenOrientation.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
using namespace mozilla;
using namespace mozilla::widget;
using namespace mozilla::dom;
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
void
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
@ -54,13 +63,27 @@ anp_window_showKeyboard(NPP instance, bool value)
void
anp_window_requestFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner)))) {
return;
}
owner->RequestFullScreen();
}
void
anp_window_exitFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner)))) {
return;
}
owner->ExitFullScreen();
}
void
@ -69,12 +92,6 @@ anp_window_requestCenterFitZoom(NPP instance)
NOT_IMPLEMENTED();
}
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
ANPRectI
anp_window_visibleRect(NPP instance)
{
@ -98,7 +115,29 @@ anp_window_visibleRect(NPP instance)
void anp_window_requestFullScreenOrientation(NPP instance, ANPScreenOrientation orientation)
{
NOT_IMPLEMENTED();
short newOrientation;
// Convert to the ActivityInfo equivalent
switch (orientation) {
case kFixedLandscape_ANPScreenOrientation:
newOrientation = eScreenOrientation_LandscapePrimary;
break;
case kFixedPortrait_ANPScreenOrientation:
newOrientation = eScreenOrientation_PortraitPrimary;
break;
case kLandscape_ANPScreenOrientation:
newOrientation = eScreenOrientation_Landscape;
break;
case kPortrait_ANPScreenOrientation:
newOrientation = eScreenOrientation_Portrait;
break;
default:
newOrientation = eScreenOrientation_None;
break;
}
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
pinst->SetFullScreenOrientation(newOrientation);
}
void InitWindowInterface(ANPWindowInterfaceV0 *i) {

View File

@ -698,6 +698,28 @@ struct ANPWindowInterfaceV1 : ANPWindowInterfaceV0 {
ANPRectI (*visibleRect)(NPP instance);
};
enum ANPScreenOrientations {
/** No preference specified: let the system decide the best orientation.
*/
kDefault_ANPScreenOrientation = 0,
/** Would like to have the screen in a landscape orientation, but it will
not allow for 180 degree rotations.
*/
kFixedLandscape_ANPScreenOrientation = 1,
/** Would like to have the screen in a portrait orientation, but it will
not allow for 180 degree rotations.
*/
kFixedPortrait_ANPScreenOrientation = 2,
/** Would like to have the screen in landscape orientation, but can use the
sensor to change which direction the screen is facing.
*/
kLandscape_ANPScreenOrientation = 3,
/** Would like to have the screen in portrait orientation, but can use the
sensor to change which direction the screen is facing.
*/
kPortrait_ANPScreenOrientation = 4
};
typedef int32_t ANPScreenOrientation;
struct ANPWindowInterfaceV2 : ANPWindowInterfaceV1 {

View File

@ -3,6 +3,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef MOZ_WIDGET_ANDROID
// For ScreenOrientation.h
#include "base/basictypes.h"
#endif
#include "prlog.h"
#include "prmem.h"
#include "nscore.h"
@ -35,6 +40,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "AndroidBridge.h"
#include "mozilla/dom/ScreenOrientation.h"
class PluginEventRunnable : public nsRunnable
{
@ -74,6 +80,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
mSurface(nsnull),
mANPDrawingModel(0),
mOnScreen(true),
mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary),
#endif
mRunning(NOT_STARTED),
mWindowless(false),
@ -743,63 +750,29 @@ void nsNPAPIPluginInstance::MemoryPressure()
SendLifecycleEvent(this, kFreeMemory_ANPLifecycleAction);
}
void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
{
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::NotifyFullScreen this=%p\n",this));
if (RUNNING != mRunning)
return;
SendLifecycleEvent(this, aFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
}
void nsNPAPIPluginInstance::SetANPDrawingModel(PRUint32 aModel)
{
mANPDrawingModel = aModel;
}
class SurfaceGetter : public nsRunnable {
public:
SurfaceGetter(nsNPAPIPluginInstance* aInstance, NPPluginFuncs* aPluginFunctions, NPP_t aNPP) :
mInstance(aInstance), mPluginFunctions(aPluginFunctions), mNPP(aNPP) {
}
~SurfaceGetter() {
}
nsresult Run() {
void* surface;
(*mPluginFunctions->getvalue)(&mNPP, kJavaSurface_ANPGetValue, &surface);
mInstance->SetJavaSurface(surface);
return NS_OK;
}
void RequestSurface() {
JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (!mozilla::AndroidBridge::Bridge()) {
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance null AndroidBridge"));
return;
}
mozilla::AndroidBridge::Bridge()->PostToJavaThread(env, this);
}
private:
nsNPAPIPluginInstance* mInstance;
NPP_t mNPP;
NPPluginFuncs* mPluginFunctions;
};
void* nsNPAPIPluginInstance::GetJavaSurface()
{
if (mANPDrawingModel != kSurface_ANPDrawingModel)
void* surface = nsnull;
nsresult rv = GetValueFromPlugin(kJavaSurface_ANPGetValue, &surface);
if (NS_FAILED(rv))
return nsnull;
return mSurface;
}
void nsNPAPIPluginInstance::SetJavaSurface(void* aSurface)
{
mSurface = aSurface;
}
void nsNPAPIPluginInstance::RequestJavaSurface()
{
if (mSurfaceGetter.get())
return;
mSurfaceGetter = new SurfaceGetter(this, mPlugin->PluginFuncs(), mNPP);
((SurfaceGetter*)mSurfaceGetter.get())->RequestSurface();
return surface;
}
void nsNPAPIPluginInstance::PostEvent(void* event)

View File

@ -123,6 +123,7 @@ public:
void NotifyForeground(bool aForeground);
void NotifyOnScreen(bool aOnScreen);
void MemoryPressure();
void NotifyFullScreen(bool aFullScreen);
bool IsOnScreen() {
return mOnScreen;
@ -131,12 +132,14 @@ public:
PRUint32 GetANPDrawingModel() { return mANPDrawingModel; }
void SetANPDrawingModel(PRUint32 aModel);
// This stuff is for kSurface_ANPDrawingModel
void* GetJavaSurface();
void SetJavaSurface(void* aSurface);
void RequestJavaSurface();
void PostEvent(void* event);
// These are really mozilla::dom::ScreenOrientation, but it's
// difficult to include that here
PRUint32 FullScreenOrientation() { return mFullScreenOrientation; }
void SetFullScreenOrientation(PRUint32 orientation) { mFullScreenOrientation = orientation; }
#endif
nsresult NewStreamListener(const char* aURL, void* notifyData,
@ -221,6 +224,8 @@ protected:
nsTArray<nsCOMPtr<PluginEventRunnable>> mPostedEvents;
void PopPostedEvent(PluginEventRunnable* r);
PRUint32 mFullScreenOrientation;
#endif
enum {

View File

@ -87,6 +87,10 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#include "ANPBase.h"
#include "AndroidBridge.h"
#include "AndroidMediaLayer.h"
#include "nsWindow.h"
static nsPluginInstanceOwner* sFullScreenInstance = nsnull;
using namespace mozilla::dom;
#include <android/log.h>
@ -305,7 +309,9 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
#ifdef MOZ_WIDGET_ANDROID
mInverted = false;
mFullScreen = false;
mLayer = nsnull;
mJavaView = nsnull;
#endif
}
@ -1725,31 +1731,39 @@ void nsPluginInstanceOwner::SendSize(int width, int height)
mInstance->HandleEvent(&event, nsnull);
}
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect /* = gfxRect(0, 0, 0, 0) */)
{
void* javaSurface = mInstance->GetJavaSurface();
if (!javaSurface) {
mInstance->RequestJavaSurface();
return false;
if (!mJavaView) {
mJavaView = mInstance->GetJavaSurface();
if (!mJavaView)
return false;
mJavaView = (void*)AndroidBridge::GetJNIEnv()->NewGlobalRef((jobject)mJavaView);
}
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->AddPluginView((jobject)javaSurface, aRect);
AndroidBridge::Bridge()->AddPluginView((jobject)mJavaView, aRect, mFullScreen, mInstance->FullScreenOrientation());
if (mFullScreen)
sFullScreenInstance = this;
return true;
}
void nsPluginInstanceOwner::RemovePluginView()
{
if (!mInstance)
return;
void* surface = mInstance->GetJavaSurface();
if (!surface)
if (!mInstance || !mJavaView)
return;
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->RemovePluginView((jobject)surface);
AndroidBridge::Bridge()->RemovePluginView((jobject)mJavaView, mFullScreen);
AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView);
mJavaView = nsnull;
if (mFullScreen)
sFullScreenInstance = nsnull;
}
void nsPluginInstanceOwner::Invalidate() {
@ -1760,6 +1774,47 @@ void nsPluginInstanceOwner::Invalidate() {
InvalidateRect(&rect);
}
void nsPluginInstanceOwner::RequestFullScreen() {
if (mFullScreen)
return;
// Remove whatever view we currently have (if any, fullscreen or otherwise)
RemovePluginView();
mFullScreen = true;
AddPluginView();
mInstance->NotifyFullScreen(mFullScreen);
}
void nsPluginInstanceOwner::ExitFullScreen() {
if (!mFullScreen)
return;
RemovePluginView();
mFullScreen = false;
PRInt32 model = mInstance->GetANPDrawingModel();
if (model == kSurface_ANPDrawingModel) {
// We need to invalidate the plugin rect so Paint() gets called above.
// This will cause the view to be re-added. Gross.
Invalidate();
}
mInstance->NotifyFullScreen(mFullScreen);
}
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
JNIEnv* env = AndroidBridge::GetJNIEnv();
if (env && sFullScreenInstance && sFullScreenInstance->mInstance &&
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
sFullScreenInstance->ExitFullScreen();
}
}
#endif
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
@ -2871,7 +2926,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState)
if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState || mFullScreen)
return;
PRInt32 model = mInstance->GetANPDrawingModel();

View File

@ -277,6 +277,12 @@ public:
}
void Invalidate();
void RequestFullScreen();
void ExitFullScreen();
// Called from AndroidJNI when we removed the fullscreen view.
static void ExitFullScreen(jobject view);
#endif
private:
@ -293,10 +299,13 @@ private:
#ifdef MOZ_WIDGET_ANDROID
void SendSize(int width, int height);
bool AddPluginView(const gfxRect& aRect);
bool AddPluginView(const gfxRect& aRect = gfxRect(0, 0, 0, 0));
void RemovePluginView();
bool mInverted;
bool mFullScreen;
void* mJavaView;
// For kOpenGL_ANPDrawingModel
nsRefPtr<mozilla::AndroidMediaLayer> mLayer;

View File

@ -128,6 +128,8 @@ parent:
sync NPN_SetException(nullable PPluginScriptableObject actor,
nsCString message);
async NPN_ReloadPlugins(bool aReloadPages);
};
} // namespace plugins

View File

@ -1263,7 +1263,8 @@ _reloadplugins(NPBool aReloadPages)
{
PLUGIN_LOG_DEBUG_FUNCTION;
ENSURE_PLUGIN_THREAD_VOID();
NS_WARNING("Not yet implemented!");
PluginModuleChild::current()->SendNPN_ReloadPlugins(!!aReloadPages);
}
void NP_CALLBACK

View File

@ -1153,3 +1153,12 @@ PluginModuleParent::RecvNPN_SetException(PPluginScriptableObjectParent* aActor,
mozilla::plugins::parent::_setexception(aNPObj, NullableStringGet(aMessage));
return true;
}
bool
PluginModuleParent::RecvNPN_ReloadPlugins(const bool& aReloadPages)
{
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
mozilla::plugins::parent::_reloadplugins(aReloadPages);
return true;
}

View File

@ -185,6 +185,9 @@ protected:
RecvNPN_SetException(PPluginScriptableObjectParent* aActor,
const nsCString& aMessage);
NS_OVERRIDE virtual bool
RecvNPN_ReloadPlugins(const bool& aReloadPages);
static PluginInstanceParent* InstCast(NPP instance);
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s);

View File

@ -22,20 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753595
SimpleTest.waitForExplicitFinish();
var iframeScript = function() {
const Ci = Components.interfaces;
function painted() {
sendAsyncMessage('test:mozpainted');
}
var utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
if (!utils.isMozAfterPaintPending) {
sendAsyncMessage('test:mozpainted');
} else {
content.addEventListener("MozAfterPaint", painted, false);
}
}
function runTest() {
browserFrameHelpers.setEnabledPref(true);
@ -44,35 +30,57 @@ function runTest() {
var iframe1 = document.createElement('iframe');
iframe1.mozbrowser = true;
document.body.appendChild(iframe1);
iframe1.src = 'data:text/html,<html>' +
'<body style="background:green">hello</body></html>';
var screenshots = [];
var numLoaded = 0;
function screenshotLoaded(e) {
screenshots.push(e.target.result);
function screenshotTaken(screenshot) {
screenshots.push(screenshot);
if (screenshots.length === 1) {
ok(true, 'Got initial non blank screenshot');
iframe1.src = 'data:text/html,<html>' +
'<body style="background:blue">hello</body></html>';
waitForScreenshot(function(screenshot) {
return screenshot !== screenshots[0];
});
}
else if (screenshots.length === 2) {
ok(screenshots[0] !== screenshots[1], 'Screenshots differ');
ok(true, 'Got updated screenshot after source page changed');
SimpleTest.finish();
}
}
function recvMozPainted() {
// We continually take screenshots until we get one that we are
// happy with
function waitForScreenshot(filter) {
function screenshotLoaded(e) {
if (filter(e.target.result)) {
screenshotTaken(e.target.result);
return;
}
if (--attempts === 0) {
ok(false, 'Timed out waiting for correct screenshot');
SimpleTest.finish();
} else {
content.document.defaultView.setTimeout(function() {
iframe1.getScreenshot().onsuccess = screenshotLoaded;
}, 200);
}
}
var attempts = 10;
iframe1.getScreenshot().onsuccess = screenshotLoaded;
}
function iframeLoadedHandler() {
numLoaded++;
if (numLoaded === 1) {
iframe1.src = 'data:text/html,<html>' +
'<body style="background:green">hello</body></html>';
} else if (numLoaded === 2 || numLoaded === 3) {
var mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
mm.addMessageListener('test:mozpainted', recvMozPainted);
mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
if (numLoaded === 2) {
waitForScreenshot(function(screenshot) {
return screenshot !== 'data:,';
});
}
}

View File

@ -214,6 +214,7 @@ PrefCallback(const char* aPrefName, void* aClosure)
if (Preferences::GetBool(gPrefsToWatch[PREF_typeinference])) {
newOptions |= JSOPTION_TYPE_INFERENCE;
}
newOptions |= JSOPTION_ALLOW_XML;
RuntimeService::SetDefaultJSContextOptions(newOptions);
rts->UpdateAllWorkerJSContextOptions();

View File

@ -498,7 +498,7 @@ nsresult mozHunspell::ConvertCharset(const PRUnichar* aStr, char ** aDst)
NS_ENSURE_TRUE(mEncoder, NS_ERROR_NULL_POINTER);
PRInt32 outLength;
PRInt32 inLength = nsCRT::strlen(aStr);
PRInt32 inLength = NS_strlen(aStr);
nsresult rv = mEncoder->GetMaxLength(aStr, inLength, &outLength);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -245,7 +245,7 @@ NS_IMETHODIMP mozEnglishWordUtils::FromRootForm(const PRUnichar *aWord, const PR
mozEnglishWordUtils::myspCapitalization ct = captype(word);
for(PRUint32 i = 0; i < icount; ++i) {
length = nsCRT::strlen(iwords[i]);
length = NS_strlen(iwords[i]);
tmpPtr[i] = (PRUnichar *) nsMemory::Alloc(sizeof(PRUnichar) * (length + 1));
if (NS_UNLIKELY(!tmpPtr[i])) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, tmpPtr);

View File

@ -30,7 +30,7 @@
#define GR2_VERSION_MAJOR 1
#define GR2_VERSION_MINOR 1
#define GR2_VERSION_BUGFIX 2
#define GR2_VERSION_BUGFIX 3
#ifdef __cplusplus
extern "C"

View File

@ -97,7 +97,7 @@ set_target_properties(graphite2 PROPERTIES PUBLIC_HEADER "${GRAPHITE_HEADERS}"
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
add_definitions(-Wall -Wno-unknown-pragmas -Wparentheses -Wextra -Wendif-labels
-Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fdiagnostics-show-option
-fno-rtti -fno-exceptions -nodefaultlibs
-fno-rtti -fno-exceptions
-fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector)
set_target_properties(graphite2 PROPERTIES LINK_FLAGS "-nodefaultlibs" LINKER_LANGUAGE C)
if (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
@ -111,6 +111,19 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
add_definitions(-Wall -Wno-unknown-pragmas -Wparentheses -Wextra -Wendif-labels
-Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fdiagnostics-show-option
-fno-rtti -fno-exceptions
-fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector)
set_target_properties(graphite2 PROPERTIES LINK_FLAGS "-nodefaultlibs" LINKER_LANGUAGE C)
target_link_libraries(graphite2 "-lc")
include(Graphite)
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DUNICODE -DGRAPHITE2_EXPORTING)
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")

View File

@ -90,28 +90,30 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
// Perform some sanity checks.
if ( m_sTransition > m_sRows
|| m_sSuccess > m_sRows
|| m_sSuccess + m_sTransition < m_sRows)
|| m_sSuccess + m_sTransition < m_sRows
|| numRanges == 0)
return false;
if (p + numRanges * 6 - 4 > pass_end) return false;
m_numGlyphs = be::peek<uint16>(p + numRanges * 6 - 4) + 1;
// Caculate the start of vairous arrays.
// Calculate the start of various arrays.
const byte * const ranges = p;
be::skip<uint16>(p, numRanges*3);
const byte * const o_rule_map = p;
be::skip<uint16>(p, m_sSuccess + 1);
// More sanity checks
if ( reinterpret_cast<const byte *>(o_rule_map + m_sSuccess*sizeof(uint16)) > pass_end
if (reinterpret_cast<const byte *>(o_rule_map + m_sSuccess*sizeof(uint16)) > pass_end
|| p > pass_end)
return false;
const size_t numEntries = be::peek<uint16>(o_rule_map + m_sSuccess*sizeof(uint16));
const byte * const rule_map = p;
be::skip<uint16>(p, numEntries);
if (p + 2 > pass_end) return false;
if (p + 2*sizeof(uint8) > pass_end) return false;
m_minPreCtxt = be::read<uint8>(p);
m_maxPreCtxt = be::read<uint8>(p);
if (m_minPreCtxt > m_maxPreCtxt) return false;
const byte * const start_states = p;
be::skip<int16>(p, m_maxPreCtxt - m_minPreCtxt + 1);
const uint16 * const sort_keys = reinterpret_cast<const uint16 *>(p);
@ -120,7 +122,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
be::skip<byte>(p, m_numRules);
be::skip<byte>(p); // skip reserved byte
if (p + 2 > pass_end) return false;
if (p + sizeof(uint16) > pass_end) return false;
const size_t pass_constraint_len = be::read<uint16>(p);
const uint16 * const o_constraint = reinterpret_cast<const uint16 *>(p);
be::skip<uint16>(p, m_numRules + 1);

View File

@ -36,12 +36,21 @@ of the License or (at your option) any later version.
#include "inc/Main.h"
#if defined(__GNUC__)
#if defined(__clang__)
#define HOT
#if defined(__x86_64)
#define REGPARM(n) __attribute__((regparm(n)))
#else
#define REGPARM(n)
#endif
#else
#define HOT __attribute__((hot))
#if defined(__x86_64)
#define REGPARM(n) __attribute__((hot, regparm(n)))
#else
#define REGPARM(n)
#endif
#endif
#else
#define HOT
#define REGPARM(n)

View File

@ -57,10 +57,10 @@ void json::context(const char current) throw()
void json::indent(const int d) throw()
{
if (*_context == member)
if (*_context == member || (_flatten && _flatten < _context))
fputc(' ', _stream);
else
fprintf(_stream, _flatten && _flatten < _context ? " " : "\n%*s", 4*int(_context - _contexts + d), "");
fprintf(_stream, "\n%*s", 4*int(_context - _contexts + d), "");
}

View File

@ -25,7 +25,9 @@
#if defined(DEBUG) || defined(PR_LOGGING)
# include <stdio.h> // FILE
# include "prlog.h"
# define MOZ_LAYERS_HAVE_LOG
# ifndef MOZ_LAYERS_HAVE_LOG
# define MOZ_LAYERS_HAVE_LOG
# endif
# define MOZ_LAYERS_LOG(_args) \
PR_LOG(LayerManager::GetLog(), PR_LOG_DEBUG, _args)
#else

View File

@ -494,7 +494,6 @@ CompositorParent::AllocPLayers(const LayersBackend& aBackendType, int* aMaxTextu
*aMaxTextureSize = layerManager->GetMaxTextureSize();
return new ShadowLayersParent(slm, this);
} else if (aBackendType == LayerManager::LAYERS_BASIC) {
// This require Cairo to be thread-safe
nsRefPtr<LayerManager> layerManager = new BasicShadowLayerManager(mWidget);
mWidget = NULL;
mLayerManager = layerManager;

View File

@ -199,6 +199,13 @@ class OTSStream {
unsigned chksum_buffer_offset_;
};
#ifdef MOZ_OTS_REPORT_ERRORS
// Signature of the function to be provided by the client in order to report errors.
// The return type is a boolean so that it can be used within an expression,
// but the actual value is ignored. (Suggested convention is to always return 'false'.)
typedef bool (*MessageFunc)(void *user_data, const char *format, ...);
#endif
// -----------------------------------------------------------------------------
// Process a given OpenType file and write out a sanitised version
// output: a pointer to an object implementing the OTSStream interface. The
@ -209,6 +216,9 @@ class OTSStream {
// preserve_graphite_tables: whether to preserve Graphite Layout tables
// -----------------------------------------------------------------------------
bool OTS_API Process(OTSStream *output, const uint8_t *input, size_t length,
#ifdef MOZ_OTS_REPORT_ERRORS
MessageFunc message_func, void *user_data,
#endif
bool preserve_graphite_tables = false);
// Force to disable debug output even when the library is compiled with

View File

@ -88,6 +88,7 @@ include $(topsrcdir)/config/rules.mk
DEFINES += -DPACKAGE_VERSION="\"moz\""
DEFINES += -DPACKAGE_BUGREPORT="\"http://bugzilla.mozilla.org/\""
DEFINES += -DNOMINMAX
DEFINES += -DMOZ_OTS_REPORT_ERRORS
ifeq (WINNT,$(OS_TARGET))
DEFINES += -DOTS_DLL -DOTS_DLL_EXPORTS

View File

@ -15,6 +15,8 @@
// GDEF - The Glyph Definition Table
// http://www.microsoft.com/typography/otspec/gdef.htm
#define TABLE_NAME "GDEF"
namespace {
// The maximum class value in class definition tables.
@ -242,7 +244,11 @@ bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data,
} // namespace
#define DROP_THIS_TABLE \
do { file->gdef->data = 0; file->gdef->length = 0; } while (0)
do { \
file->gdef->data = 0; \
file->gdef->length = 0; \
OTS_FAILURE_MSG("OpenType layout data discarded"); \
} while (0)
namespace ots {
@ -261,7 +267,9 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
uint32_t version = 0;
if (!table.ReadU32(&version)) {
return OTS_FAILURE();
OTS_WARNING("incomplete GDEF table");
DROP_THIS_TABLE;
return true;
}
if (version < 0x00010000 || version == 0x00010001) {
OTS_WARNING("bad GDEF version");
@ -281,12 +289,16 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
!table.ReadU16(&offset_attach_list) ||
!table.ReadU16(&offset_lig_caret_list) ||
!table.ReadU16(&offset_mark_attach_class_def)) {
return OTS_FAILURE();
OTS_WARNING("incomplete GDEF table");
DROP_THIS_TABLE;
return true;
}
uint16_t offset_mark_glyph_sets_def = 0;
if (gdef->version_2) {
if (!table.ReadU16(&offset_mark_glyph_sets_def)) {
return OTS_FAILURE();
OTS_WARNING("incomplete GDEF table");
DROP_THIS_TABLE;
return true;
}
}
@ -298,11 +310,14 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (offset_glyph_class_def) {
if (offset_glyph_class_def >= length ||
offset_glyph_class_def < gdef_header_end) {
return OTS_FAILURE();
OTS_WARNING("invalid offset to glyph classes");
DROP_THIS_TABLE;
return true;
}
if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def,
length - offset_glyph_class_def,
num_glyphs)) {
OTS_WARNING("invalid glyph classes");
DROP_THIS_TABLE;
return true;
}
@ -312,11 +327,14 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (offset_attach_list) {
if (offset_attach_list >= length ||
offset_attach_list < gdef_header_end) {
return OTS_FAILURE();
OTS_WARNING("invalid offset to attachment list");
DROP_THIS_TABLE;
return true;
}
if (!ParseAttachListTable(file, data + offset_attach_list,
length - offset_attach_list,
num_glyphs)) {
OTS_WARNING("invalid attachment list");
DROP_THIS_TABLE;
return true;
}
@ -325,11 +343,14 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (offset_lig_caret_list) {
if (offset_lig_caret_list >= length ||
offset_lig_caret_list < gdef_header_end) {
return OTS_FAILURE();
OTS_WARNING("invalid offset to lig-caret list");
DROP_THIS_TABLE;
return true;
}
if (!ParseLigCaretListTable(file, data + offset_lig_caret_list,
length - offset_lig_caret_list,
num_glyphs)) {
OTS_WARNING("invalid ligature caret list");
DROP_THIS_TABLE;
return true;
}
@ -338,12 +359,14 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (offset_mark_attach_class_def) {
if (offset_mark_attach_class_def >= length ||
offset_mark_attach_class_def < gdef_header_end) {
OTS_WARNING("invalid offset to mark attachment list");
return OTS_FAILURE();
}
if (!ParseMarkAttachClassDefTable(file,
data + offset_mark_attach_class_def,
length - offset_mark_attach_class_def,
num_glyphs)) {
OTS_WARNING("invalid mark attachment list");
DROP_THIS_TABLE;
return true;
}
@ -353,12 +376,14 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (offset_mark_glyph_sets_def) {
if (offset_mark_glyph_sets_def >= length ||
offset_mark_glyph_sets_def < gdef_header_end) {
OTS_WARNING("invalid offset to mark glyph sets");
return OTS_FAILURE();
}
if (!ParseMarkGlyphSetsDefTable(file,
data + offset_mark_glyph_sets_def,
length - offset_mark_glyph_sets_def,
num_glyphs)) {
OTS_WARNING("invalid mark glyph sets");
DROP_THIS_TABLE;
return true;
}

View File

@ -15,6 +15,8 @@
// GPOS - The Glyph Positioning Table
// http://www.microsoft.com/typography/otspec/gpos.htm
#define TABLE_NAME "GPOS"
namespace {
enum GPOS_TYPE {
@ -669,7 +671,11 @@ bool ParseExtensionPositioning(const ots::OpenTypeFile *file,
} // namespace
#define DROP_THIS_TABLE \
do { file->gpos->data = 0; file->gpos->length = 0; } while (0)
do { \
file->gpos->data = 0; \
file->gpos->length = 0; \
OTS_FAILURE_MSG("OpenType layout data discarded"); \
} while (0)
namespace ots {
@ -738,7 +744,9 @@ bool ots_gpos_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
!table.ReadU16(&offset_script_list) ||
!table.ReadU16(&offset_feature_list) ||
!table.ReadU16(&offset_lookup_list)) {
return OTS_FAILURE();
OTS_WARNING("incomplete GPOS table");
DROP_THIS_TABLE;
return true;
}
if (version != 0x00010000) {
@ -761,7 +769,7 @@ bool ots_gpos_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
length - offset_lookup_list,
&kGposLookupSubtableParser,
&gpos->num_lookups)) {
OTS_WARNING("faild to parse lookup list table");
OTS_WARNING("failed to parse lookup list table");
DROP_THIS_TABLE;
return true;
}
@ -770,14 +778,14 @@ bool ots_gpos_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (!ParseFeatureListTable(data + offset_feature_list,
length - offset_feature_list, gpos->num_lookups,
&num_features)) {
OTS_WARNING("faild to parse feature list table");
OTS_WARNING("failed to parse feature list table");
DROP_THIS_TABLE;
return true;
}
if (!ParseScriptListTable(data + offset_script_list,
length - offset_script_list, num_features)) {
OTS_WARNING("faild to parse script list table");
OTS_WARNING("failed to parse script list table");
DROP_THIS_TABLE;
return true;
}

View File

@ -15,6 +15,8 @@
// GSUB - The Glyph Substitution Table
// http://www.microsoft.com/typography/otspec/gsub.htm
#define TABLE_NAME "GSUB"
namespace {
// The GSUB header size
@ -219,7 +221,7 @@ bool ParseAlternateSetTable(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
if (alternate >= num_glyphs) {
OTS_WARNING("too arge alternate: %u", alternate);
OTS_WARNING("too large alternate: %u", alternate);
return OTS_FAILURE();
}
}
@ -529,7 +531,11 @@ bool ParseReverseChainingContextSingleSubstitution(
} // namespace
#define DROP_THIS_TABLE \
do { file->gsub->data = 0; file->gsub->length = 0; } while (0)
do { \
file->gsub->data = 0; \
file->gsub->length = 0; \
OTS_FAILURE_MSG("OpenType layout data discarded"); \
} while (0)
namespace ots {
@ -602,7 +608,9 @@ bool ots_gsub_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
!table.ReadU16(&offset_script_list) ||
!table.ReadU16(&offset_feature_list) ||
!table.ReadU16(&offset_lookup_list)) {
return OTS_FAILURE();
OTS_WARNING("incomplete GSUB table");
DROP_THIS_TABLE;
return true;
}
if (version != 0x00010000) {
@ -625,7 +633,7 @@ bool ots_gsub_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
length - offset_lookup_list,
&kGsubLookupSubtableParser,
&gsub->num_lookups)) {
OTS_WARNING("faild to parse lookup list table");
OTS_WARNING("failed to parse lookup list table");
DROP_THIS_TABLE;
return true;
}
@ -634,14 +642,14 @@ bool ots_gsub_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
if (!ParseFeatureListTable(data + offset_feature_list,
length - offset_feature_list, gsub->num_lookups,
&num_features)) {
OTS_WARNING("faild to parse feature list table");
OTS_WARNING("failed to parse feature list table");
DROP_THIS_TABLE;
return true;
}
if (!ParseScriptListTable(data + offset_script_list,
length - offset_script_list, num_features)) {
OTS_WARNING("faild to parse script list table");
OTS_WARNING("failed to parse script list table");
DROP_THIS_TABLE;
return true;
}

View File

@ -21,6 +21,20 @@ namespace {
bool g_debug_output = true;
#ifdef MOZ_OTS_REPORT_ERRORS
// Generate a message with or without a table tag, when 'header' is the OpenTypeFile pointer
#define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE_MSG_TAG_(header, msg_, tag_)
#define OTS_FAILURE_MSG_HDR(msg_) OTS_FAILURE_MSG_(header, msg_)
#else
#define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE()
#define OTS_FAILURE_MSG_HDR(msg_) OTS_FAILURE()
#endif
struct OpenTypeTable {
uint32_t tag;
uint32_t chksum;
@ -182,27 +196,27 @@ bool ProcessTTF(ots::OpenTypeFile *header,
// we disallow all files > 1GB in size for sanity.
if (length > 1024 * 1024 * 1024) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("file exceeds 1GB");
}
if (!file.ReadTag(&header->version)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading version tag");
}
if (!IsValidVersionTag(header->version)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid version tag");
}
if (!file.ReadU16(&header->num_tables) ||
!file.ReadU16(&header->search_range) ||
!file.ReadU16(&header->entry_selector) ||
!file.ReadU16(&header->range_shift)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading table directory search header");
}
// search_range is (Maximum power of 2 <= numTables) x 16. Thus, to avoid
// overflow num_tables is, at most, 2^16 / 16 = 2^12
if (header->num_tables >= 4096 || header->num_tables < 1) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("excessive (or zero) number of tables");
}
unsigned max_pow2 = 0;
@ -220,7 +234,7 @@ bool ProcessTTF(ots::OpenTypeFile *header,
// entry_selector is Log2(maximum power of 2 <= numTables)
if (header->entry_selector != max_pow2) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("incorrect entrySelector for table directory");
}
// range_shift is NumTables x 16-searchRange. We know that 16*num_tables
@ -242,7 +256,7 @@ bool ProcessTTF(ots::OpenTypeFile *header,
!file.ReadU32(&table.chksum) ||
!file.ReadU32(&table.offset) ||
!file.ReadU32(&table.length)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading table directory");
}
table.uncompressed_length = table.length;
@ -258,23 +272,23 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
// we disallow all files > 1GB in size for sanity.
if (length > 1024 * 1024 * 1024) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("file exceeds 1GB");
}
uint32_t woff_tag;
if (!file.ReadTag(&woff_tag)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading WOFF marker");
}
if (woff_tag != Tag("wOFF")) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid WOFF marker");
}
if (!file.ReadTag(&header->version)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading version tag");
}
if (!IsValidVersionTag(header->version)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid version tag");
}
header->search_range = 0;
@ -283,27 +297,27 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
uint32_t reported_length;
if (!file.ReadU32(&reported_length) || length != reported_length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("incorrect file size in WOFF header");
}
if (!file.ReadU16(&header->num_tables) || !header->num_tables) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading number of tables");
}
uint16_t reserved_value;
if (!file.ReadU16(&reserved_value) || reserved_value) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error in reserved field of WOFF header");
}
uint32_t reported_total_sfnt_size;
if (!file.ReadU32(&reported_total_sfnt_size)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading total sfnt size");
}
// We don't care about these fields of the header:
// uint16_t major_version, minor_version
if (!file.Skip(2 * 2)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error skipping WOFF header fields");
}
// Checks metadata block size.
@ -313,11 +327,11 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
if (!file.ReadU32(&meta_offset) ||
!file.ReadU32(&meta_length) ||
!file.ReadU32(&meta_length_orig)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading WOFF header fields");
}
if (meta_offset) {
if (meta_offset >= length || length - meta_offset < meta_length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid metadata block location/size");
}
}
@ -326,11 +340,11 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
uint32_t priv_length;
if (!file.ReadU32(&priv_offset) ||
!file.ReadU32(&priv_length)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading WOFF header fields");
}
if (priv_offset) {
if (priv_offset >= length || length - priv_offset < priv_length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid private block location/size");
}
}
@ -348,12 +362,12 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
!file.ReadU32(&table.length) ||
!file.ReadU32(&table.uncompressed_length) ||
!file.ReadU32(&table.chksum)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error reading table directory");
}
total_sfnt_size += Round4(table.uncompressed_length);
if (total_sfnt_size > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("sfnt size overflow");
}
tables.push_back(table);
if (i == 0 || tables[first_index].offset > table.offset)
@ -363,17 +377,17 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
}
if (reported_total_sfnt_size != total_sfnt_size) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("uncompressed sfnt size mismatch");
}
// Table data must follow immediately after the header.
if (tables[first_index].offset != Round4(file.offset())) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("junk before tables in WOFF file");
}
if (tables[last_index].offset >= length ||
length - tables[last_index].offset < tables[last_index].length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid table location/size");
}
// Blocks must follow immediately after the previous block.
// (Except for padding with a maximum of three null bytes)
@ -381,30 +395,30 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
static_cast<uint64_t>(tables[last_index].offset) +
static_cast<uint64_t>(tables[last_index].length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid table location/size");
}
if (meta_offset) {
if (block_end != meta_offset) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid metadata block location");
}
block_end = Round4(static_cast<uint64_t>(meta_offset) +
static_cast<uint64_t>(meta_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid metadata block size");
}
}
if (priv_offset) {
if (block_end != priv_offset) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid private block location");
}
block_end = Round4(static_cast<uint64_t>(priv_offset) +
static_cast<uint64_t>(priv_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("invalid private block size");
}
}
if (block_end != Round4(length)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("file length mismatch (trailing junk?)");
}
return ProcessGeneric(header, output, data, length, tables, file);
@ -425,46 +439,46 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
const uint32_t this_tag = ntohl(tables[i].tag);
const uint32_t prev_tag = ntohl(tables[i - 1].tag);
if (this_tag <= prev_tag) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("table directory not correctly ordered");
}
}
// all tag names must be built from printable ASCII characters
if (!CheckTag(tables[i].tag)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("invalid table tag", &tables[i].tag);
}
// tables must be 4-byte aligned
if (tables[i].offset & 3) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("misaligned table", &tables[i].tag);
}
// and must be within the file
if (tables[i].offset < data_offset || tables[i].offset >= length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("invalid table offset", &tables[i].tag);
}
// disallow all tables with a zero length
if (tables[i].length < 1) {
// Note: malayalam.ttf has zero length CVT table...
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("zero-length table", &tables[i].tag);
}
// disallow all tables with a length > 1GB
if (tables[i].length > 1024 * 1024 * 1024) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("table length exceeds 1GB", &tables[i].tag);
}
// disallow tables where the uncompressed size is < the compressed size.
if (tables[i].uncompressed_length < tables[i].length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("invalid compressed table", &tables[i].tag);
}
if (tables[i].uncompressed_length > tables[i].length) {
// We'll probably be decompressing this table.
// disallow all tables which uncompress to > 30 MB
if (tables[i].uncompressed_length > 30 * 1024 * 1024) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("uncompressed length exceeds 30MB", &tables[i].tag);
}
if (uncompressed_sum + tables[i].uncompressed_length < uncompressed_sum) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("overflow of uncompressed sum", &tables[i].tag);
}
uncompressed_sum += tables[i].uncompressed_length;
@ -476,13 +490,13 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
// called TTX seems not to add 0-padding to the final table. It might be
// ok to accept these fonts so we round up the length of the font file.
if (!end_byte || end_byte > length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("table overruns end of file", &tables[i].tag);
}
}
// All decompressed tables uncompressed must be <= 30MB.
if (uncompressed_sum > 30 * 1024 * 1024) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("uncompressed sum exceeds 30MB");
}
std::map<uint32_t, OpenTypeTable> table_map;
@ -504,7 +518,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
for (unsigned i = 0; i < overlap_checker.size(); ++i) {
overlap_count += (overlap_checker[i].second ? 1 : -1);
if (overlap_count > 1) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("overlapping tables");
}
}
@ -518,7 +532,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
if (it == table_map.end()) {
if (table_parsers[i].required) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("missing required table", table_parsers[i].tag);
}
continue;
}
@ -534,7 +548,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
int r = uncompress((Bytef*) table_data, &dest_len,
data + it->second.offset, it->second.length);
if (r != Z_OK || dest_len != table_length) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("uncompress failed", table_parsers[i].tag);
}
} else {
// uncompressed table. We can process directly from memory.
@ -543,24 +557,26 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
}
if (!table_parsers[i].parse(header, table_data, table_length)) {
return OTS_FAILURE();
// TODO: parsers should generate specific messages detailing the failure;
// once those are all added, we won't need a generic failure message here
return OTS_FAILURE_MSG_TAG("failed to parse table", table_parsers[i].tag);
}
}
if (header->cff) {
// font with PostScript glyph
if (header->version != Tag("OTTO")) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data");
}
if (header->glyf || header->loca) {
// mixing outline formats is not recommended
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("font contains both PS and TT glyphs");
}
} else {
if (!header->glyf || !header->loca) {
// No TrueType glyph found.
// Note: bitmap-only fonts are not supported.
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("neither PS nor TT glyphs present");
}
}
@ -581,19 +597,21 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
}
const uint16_t output_search_range = (1u << max_pow2) << 4;
// most of the errors here are highly unlikely - they'd only occur if the
// output stream returns a failure, e.g. lack of space to write
output->ResetChecksum();
if (!output->WriteTag(header->version) ||
!output->WriteU16(num_output_tables) ||
!output->WriteU16(output_search_range) ||
!output->WriteU16(max_pow2) ||
!output->WriteU16((num_output_tables << 4) - output_search_range)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
const uint32_t offset_table_chksum = output->chksum();
const size_t table_record_offset = output->Tell();
if (!output->Pad(16 * num_output_tables)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
std::vector<OutputTable> out_tables;
@ -618,20 +636,20 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
head_table_offset = out.offset;
}
if (!table_parsers[i].serialise(output, header)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_TAG("failed to serialize table", table_parsers[i].tag);
}
const size_t end_offset = output->Tell();
if (end_offset <= out.offset) {
// paranoid check. |end_offset| is supposed to be greater than the offset,
// as long as the Tell() interface is implemented correctly.
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
out.length = end_offset - out.offset;
// align tables to four bytes
if (!output->Pad((4 - (end_offset & 3)) % 4)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
out.chksum = output->chksum();
out_tables.push_back(out);
@ -642,7 +660,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
// Need to sort the output tables for inclusion in the file
std::sort(out_tables.begin(), out_tables.end(), OutputTable::SortByTag);
if (!output->Seek(table_record_offset)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
output->ResetChecksum();
@ -652,7 +670,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
!output->WriteU32(out_tables[i].chksum) ||
!output->WriteU32(out_tables[i].offset) ||
!output->WriteU32(out_tables[i].length)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
tables_chksum += out_tables[i].chksum;
}
@ -665,17 +683,17 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
// seek into the 'head' table and write in the checksum magic value
if (!head_table_offset) {
return OTS_FAILURE(); // not reached.
return OTS_FAILURE_MSG_HDR("internal error!");
}
if (!output->Seek(head_table_offset + 8)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
if (!output->WriteU32(chksum_magic)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
if (!output->Seek(end_of_file)) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_HDR("error writing output");
}
return true;
@ -689,11 +707,20 @@ void DisableDebugOutput() {
g_debug_output = false;
}
bool Process(OTSStream *output, const uint8_t *data, size_t length,
bool preserveGraphite) {
bool OTS_API Process(OTSStream *output, const uint8_t *data, size_t length,
#ifdef MOZ_OTS_REPORT_ERRORS
MessageFunc message_func, void *user_data,
#endif
bool preserveGraphite) {
OpenTypeFile header;
#ifdef MOZ_OTS_REPORT_ERRORS
header.message_func = message_func;
header.user_data = user_data;
#endif
if (length < 4) {
return OTS_FAILURE();
return OTS_FAILURE_MSG_(&header, "file less than 4 bytes");
}
header.preserve_graphite = preserveGraphite;

View File

@ -38,6 +38,40 @@ void Warning(const char *f, int l, const char *format, ...)
#endif
#endif
#ifdef MOZ_OTS_REPORT_ERRORS
// All OTS_FAILURE_* macros ultimately evaluate to 'false', just like the original
// message-less OTS_FAILURE(), so that the current parser will return 'false' as
// its result (indicating a failure).
// If the message-callback feature is enabled, and a message_func pointer has been
// provided, this will be called before returning the 'false' status.
// Generate a simple message
#define OTS_FAILURE_MSG_(otf_,msg_) \
((otf_)->message_func && \
(*(otf_)->message_func)((otf_)->user_data, "%s", msg_) && \
false)
// Generate a message with an associated table tag
#define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \
((otf_)->message_func && \
(*(otf_)->message_func)((otf_)->user_data, "table '%4.4s': %s", tag_, msg_) && \
false)
// Convenience macro for use in files that only handle a single table tag,
// defined as TABLE_NAME at the top of the file; the 'file' variable is
// expected to be the current OpenTypeFile pointer.
#define OTS_FAILURE_MSG(msg_) OTS_FAILURE_MSG_TAG_(file, msg_, TABLE_NAME)
#else
// If the message-callback feature is not enabled, error messages are just dropped.
#define OTS_FAILURE_MSG_(otf_,msg_) OTS_FAILURE()
#define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) OTS_FAILURE()
#define OTS_FAILURE_MSG(msg_) OTS_FAILURE()
#endif
// Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you
// want to omit TrueType hinting instructions and variables in glyf, fpgm, prep,
// and cvt tables.
@ -207,6 +241,11 @@ struct OpenTypeFile {
uint16_t entry_selector;
uint16_t range_shift;
#ifdef MOZ_OTS_REPORT_ERRORS
MessageFunc message_func;
void *user_data;
#endif
// This is used to tell the relevant parsers whether to preserve the
// Graphite layout tables (currently _without_ any checking)
bool preserve_graphite;

View File

@ -0,0 +1,66 @@
From 27a914815e757ed12523edf968c9da134dabeaf8 Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:10:44 -0400
Subject: [PATCH 01/10] Bug 755869 - [4] Re-apply bug 687189 - Implement
SkPaint::getPosTextPath r=mattwoodrow
---
gfx/skia/include/core/SkPaint.h | 3 +++
gfx/skia/src/core/SkPaint.cpp | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
index 1930db1..ff37d77 100644
--- a/gfx/skia/include/core/SkPaint.h
+++ b/gfx/skia/include/core/SkPaint.h
@@ -813,6 +813,9 @@ public:
void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
SkPath* path) const;
+ void getPosTextPath(const void* text, size_t length,
+ const SkPoint pos[], SkPath* path) const;
+
#ifdef SK_BUILD_FOR_ANDROID
const SkGlyph& getUnicharMetrics(SkUnichar);
const SkGlyph& getGlyphMetrics(uint16_t);
diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
index 1b74fa1..4c119aa 100644
--- a/gfx/skia/src/core/SkPaint.cpp
+++ b/gfx/skia/src/core/SkPaint.cpp
@@ -1355,6 +1355,33 @@ void SkPaint::getTextPath(const void* textData, size_t length,
}
}
+void SkPaint::getPosTextPath(const void* textData, size_t length,
+ const SkPoint pos[], SkPath* path) const {
+ SkASSERT(length == 0 || textData != NULL);
+
+ const char* text = (const char*)textData;
+ if (text == NULL || length == 0 || path == NULL) {
+ return;
+ }
+
+ SkTextToPathIter iter(text, length, *this, false);
+ SkMatrix matrix;
+ SkPoint prevPos;
+ prevPos.set(0, 0);
+
+ matrix.setScale(iter.getPathScale(), iter.getPathScale());
+ path->reset();
+
+ unsigned int i = 0;
+ const SkPath* iterPath;
+ while ((iterPath = iter.next(NULL)) != NULL) {
+ matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
+ path->addPath(*iterPath, matrix);
+ prevPos = pos[i];
+ i++;
+ }
+}
+
static void add_flattenable(SkDescriptor* desc, uint32_t tag,
SkFlattenableWriteBuffer* buffer) {
buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
--
1.7.5.4

View File

@ -0,0 +1,30 @@
From f310d7e8b8d9cf6870c739650324bb585b591c0c Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:11:32 -0400
Subject: [PATCH 02/10] Bug 755869 - [5] Re-apply bug 688366 - Fix Skia
marking radial gradients with the same radius as
invalid. r=mattwoodrow
---
gfx/skia/src/effects/SkGradientShader.cpp | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
index 6de820b..59ba48c 100644
--- a/gfx/skia/src/effects/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/SkGradientShader.cpp
@@ -1911,7 +1911,10 @@ public:
SkPMColor* SK_RESTRICT dstC = dstCParam;
// Zero difference between radii: fill with transparent black.
- if (fDiffRadius == 0) {
+ // TODO: Is removing this actually correct? Two circles with the
+ // same radius, but different centers doesn't sound like it
+ // should be cleared
+ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
sk_bzero(dstC, count * sizeof(*dstC));
return;
}
--
1.7.5.4

View File

@ -0,0 +1,39 @@
From ef53776c06cffc7607c3777702f93e04c0852981 Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:13:49 -0400
Subject: [PATCH 03/10] Bug 755869 - [6] Re-apply SkUserConfig (no
original bug) r=mattwoodrow
---
gfx/skia/include/config/SkUserConfig.h | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/gfx/skia/include/config/SkUserConfig.h b/gfx/skia/include/config/SkUserConfig.h
index 9fdbd0a..f98ba85 100644
--- a/gfx/skia/include/config/SkUserConfig.h
+++ b/gfx/skia/include/config/SkUserConfig.h
@@ -156,6 +156,10 @@
//#define SK_SUPPORT_UNITTEST
#endif
+/* Don't dither 32bit gradients, to match what the canvas test suite expects.
+ */
+#define SK_DISABLE_DITHER_32BIT_GRADIENT
+
/* If your system embeds skia and has complex event logging, define this
symbol to name a file that maps the following macros to your system's
equivalents:
@@ -177,4 +181,10 @@
#define SK_A32_SHIFT 24
#endif
+/* Don't include stdint.h on windows as it conflicts with our build system.
+ */
+#ifdef SK_BUILD_FOR_WIN32
+ #define SK_IGNORE_STDINT_DOT_H
+#endif
+
#endif
--
1.7.5.4

View File

@ -0,0 +1,280 @@
From 81d61682a94d47be5b47fb7882ea7e7c7e6c3351 Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:15:28 -0400
Subject: [PATCH 04/10] Bug 755869 - [7] Re-apply bug 722011 - Fix
trailing commas at end of enum lists r=mattwoodrow
---
gfx/skia/include/core/SkAdvancedTypefaceMetrics.h | 8 ++++----
gfx/skia/include/core/SkBlitRow.h | 2 +-
gfx/skia/include/core/SkCanvas.h | 2 +-
gfx/skia/include/core/SkDevice.h | 2 +-
gfx/skia/include/core/SkDeviceProfile.h | 4 ++--
gfx/skia/include/core/SkFlattenable.h | 2 +-
gfx/skia/include/core/SkFontHost.h | 4 ++--
gfx/skia/include/core/SkMaskFilter.h | 2 +-
gfx/skia/include/core/SkPaint.h | 4 ++--
gfx/skia/include/core/SkScalerContext.h | 9 +++++----
gfx/skia/include/core/SkTypes.h | 2 +-
gfx/skia/include/effects/SkLayerDrawLooper.h | 2 +-
gfx/skia/src/core/SkBitmap.cpp | 2 +-
gfx/skia/src/core/SkGlyphCache.cpp | 2 +-
14 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
index 09fc9a9..5ffdb45 100644
--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
@@ -34,7 +34,7 @@ public:
kCFF_Font,
kTrueType_Font,
kOther_Font,
- kNotEmbeddable_Font,
+ kNotEmbeddable_Font
};
// The type of the underlying font program. This field determines which
// of the following fields are valid. If it is kOther_Font or
@@ -56,7 +56,7 @@ public:
kItalic_Style = 0x00040,
kAllCaps_Style = 0x10000,
kSmallCaps_Style = 0x20000,
- kForceBold_Style = 0x40000,
+ kForceBold_Style = 0x40000
};
uint16_t fStyle; // Font style characteristics.
int16_t fItalicAngle; // Counterclockwise degrees from vertical of the
@@ -75,7 +75,7 @@ public:
kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
- kToUnicode_PerGlyphInfo = 0x8, // Populate ToUnicode table, ignored
+ kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored
// for Type 1 fonts
};
@@ -84,7 +84,7 @@ public:
enum MetricType {
kDefault, // Default advance: fAdvance.count = 1
kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
- kRun, // fStartID-fEndID have same advance: fAdvance.count = 1
+ kRun // fStartID-fEndID have same advance: fAdvance.count = 1
};
MetricType fType;
uint16_t fStartId;
diff --git a/gfx/skia/include/core/SkBlitRow.h b/gfx/skia/include/core/SkBlitRow.h
index 973ab4c..febc405 100644
--- a/gfx/skia/include/core/SkBlitRow.h
+++ b/gfx/skia/include/core/SkBlitRow.h
@@ -42,7 +42,7 @@ public:
enum Flags32 {
kGlobalAlpha_Flag32 = 1 << 0,
- kSrcPixelAlpha_Flag32 = 1 << 1,
+ kSrcPixelAlpha_Flag32 = 1 << 1
};
/** Function pointer that blends 32bit colors onto a 32bit destination.
diff --git a/gfx/skia/include/core/SkCanvas.h b/gfx/skia/include/core/SkCanvas.h
index 25cc94a..d942783 100644
--- a/gfx/skia/include/core/SkCanvas.h
+++ b/gfx/skia/include/core/SkCanvas.h
@@ -148,7 +148,7 @@ public:
* low byte to high byte: R, G, B, A.
*/
kRGBA_Premul_Config8888,
- kRGBA_Unpremul_Config8888,
+ kRGBA_Unpremul_Config8888
};
/**
diff --git a/gfx/skia/include/core/SkDevice.h b/gfx/skia/include/core/SkDevice.h
index 1e4e0a3..b4d44bf 100644
--- a/gfx/skia/include/core/SkDevice.h
+++ b/gfx/skia/include/core/SkDevice.h
@@ -139,7 +139,7 @@ public:
protected:
enum Usage {
kGeneral_Usage,
- kSaveLayer_Usage, // <! internal use only
+ kSaveLayer_Usage // <! internal use only
};
struct TextFlags {
diff --git a/gfx/skia/include/core/SkDeviceProfile.h b/gfx/skia/include/core/SkDeviceProfile.h
index 46b9781..f6a0bca 100644
--- a/gfx/skia/include/core/SkDeviceProfile.h
+++ b/gfx/skia/include/core/SkDeviceProfile.h
@@ -17,7 +17,7 @@ public:
kRGB_Horizontal_LCDConfig,
kBGR_Horizontal_LCDConfig,
kRGB_Vertical_LCDConfig,
- kBGR_Vertical_LCDConfig,
+ kBGR_Vertical_LCDConfig
};
enum FontHintLevel {
@@ -25,7 +25,7 @@ public:
kSlight_FontHintLevel,
kNormal_FontHintLevel,
kFull_FontHintLevel,
- kAuto_FontHintLevel,
+ kAuto_FontHintLevel
};
/**
diff --git a/gfx/skia/include/core/SkFlattenable.h b/gfx/skia/include/core/SkFlattenable.h
index 5714f9d..dc115fc 100644
--- a/gfx/skia/include/core/SkFlattenable.h
+++ b/gfx/skia/include/core/SkFlattenable.h
@@ -272,7 +272,7 @@ public:
* Instructs the writer to inline Factory names as there are seen the
* first time (after that we store an index). The pipe code uses this.
*/
- kInlineFactoryNames_Flag = 0x02,
+ kInlineFactoryNames_Flag = 0x02
};
Flags getFlags() const { return (Flags)fFlags; }
void setFlags(Flags flags) { fFlags = flags; }
diff --git a/gfx/skia/include/core/SkFontHost.h b/gfx/skia/include/core/SkFontHost.h
index 732de5c..10f9bdf 100644
--- a/gfx/skia/include/core/SkFontHost.h
+++ b/gfx/skia/include/core/SkFontHost.h
@@ -240,7 +240,7 @@ public:
*/
enum LCDOrientation {
kHorizontal_LCDOrientation = 0, //!< this is the default
- kVertical_LCDOrientation = 1,
+ kVertical_LCDOrientation = 1
};
static void SetSubpixelOrientation(LCDOrientation orientation);
@@ -259,7 +259,7 @@ public:
enum LCDOrder {
kRGB_LCDOrder = 0, //!< this is the default
kBGR_LCDOrder = 1,
- kNONE_LCDOrder = 2,
+ kNONE_LCDOrder = 2
};
static void SetSubpixelOrder(LCDOrder order);
diff --git a/gfx/skia/include/core/SkMaskFilter.h b/gfx/skia/include/core/SkMaskFilter.h
index 9a470a4..3422e27 100644
--- a/gfx/skia/include/core/SkMaskFilter.h
+++ b/gfx/skia/include/core/SkMaskFilter.h
@@ -61,7 +61,7 @@ public:
kNormal_BlurType, //!< fuzzy inside and outside
kSolid_BlurType, //!< solid inside, fuzzy outside
kOuter_BlurType, //!< nothing inside, fuzzy outside
- kInner_BlurType, //!< fuzzy inside, nothing outside
+ kInner_BlurType //!< fuzzy inside, nothing outside
};
struct BlurInfo {
diff --git a/gfx/skia/include/core/SkPaint.h b/gfx/skia/include/core/SkPaint.h
index ff37d77..7c96e193 100644
--- a/gfx/skia/include/core/SkPaint.h
+++ b/gfx/skia/include/core/SkPaint.h
@@ -76,7 +76,7 @@ public:
kNo_Hinting = 0,
kSlight_Hinting = 1,
kNormal_Hinting = 2, //!< this is the default
- kFull_Hinting = 3,
+ kFull_Hinting = 3
};
Hinting getHinting() const {
@@ -289,7 +289,7 @@ public:
kStroke_Style, //!< stroke the geometry
kStrokeAndFill_Style, //!< fill and stroke the geometry
- kStyleCount,
+ kStyleCount
};
/** Return the paint's style, used for controlling how primitives'
diff --git a/gfx/skia/include/core/SkScalerContext.h b/gfx/skia/include/core/SkScalerContext.h
index 2cb171b..3dbce27 100644
--- a/gfx/skia/include/core/SkScalerContext.h
+++ b/gfx/skia/include/core/SkScalerContext.h
@@ -182,21 +182,22 @@ public:
kGenA8FromLCD_Flag = 0x0800,
#ifdef SK_USE_COLOR_LUMINANCE
- kLuminance_Bits = 3,
+ kLuminance_Bits = 3
#else
// luminance : 0 for black text, kLuminance_Max for white text
kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags
- kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits
+ kLuminance_Bits = 3 // ensure Flags doesn't exceed 16bits
#endif
};
// computed values
enum {
- kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
#ifdef SK_USE_COLOR_LUMINANCE
+ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag
#else
+ kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
kLuminance_Max = (1 << kLuminance_Bits) - 1,
- kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
+ kLuminance_Mask = kLuminance_Max << kLuminance_Shift
#endif
};
diff --git a/gfx/skia/include/core/SkTypes.h b/gfx/skia/include/core/SkTypes.h
index 7963a7d..0c5c2d7 100644
--- a/gfx/skia/include/core/SkTypes.h
+++ b/gfx/skia/include/core/SkTypes.h
@@ -438,7 +438,7 @@ public:
* current block is dynamically allocated, just return the old
* block.
*/
- kReuse_OnShrink,
+ kReuse_OnShrink
};
/**
diff --git a/gfx/skia/include/effects/SkLayerDrawLooper.h b/gfx/skia/include/effects/SkLayerDrawLooper.h
index 0bc4af2..6cb8ef6 100644
--- a/gfx/skia/include/effects/SkLayerDrawLooper.h
+++ b/gfx/skia/include/effects/SkLayerDrawLooper.h
@@ -41,7 +41,7 @@ public:
* - Flags and Color are always computed using the LayerInfo's
* fFlagsMask and fColorMode.
*/
- kEntirePaint_Bits = -1,
+ kEntirePaint_Bits = -1
};
typedef int32_t BitFlags;
diff --git a/gfx/skia/src/core/SkBitmap.cpp b/gfx/skia/src/core/SkBitmap.cpp
index 6b99145..aff52fd 100644
--- a/gfx/skia/src/core/SkBitmap.cpp
+++ b/gfx/skia/src/core/SkBitmap.cpp
@@ -1376,7 +1376,7 @@ enum {
SERIALIZE_PIXELTYPE_RAW_WITH_CTABLE,
SERIALIZE_PIXELTYPE_RAW_NO_CTABLE,
SERIALIZE_PIXELTYPE_REF_DATA,
- SERIALIZE_PIXELTYPE_REF_PTR,
+ SERIALIZE_PIXELTYPE_REF_PTR
};
/*
diff --git a/gfx/skia/src/core/SkGlyphCache.cpp b/gfx/skia/src/core/SkGlyphCache.cpp
index f3363cd..1fddc9d 100644
--- a/gfx/skia/src/core/SkGlyphCache.cpp
+++ b/gfx/skia/src/core/SkGlyphCache.cpp
@@ -417,7 +417,7 @@ class SkGlyphCache_Globals {
public:
enum UseMutex {
kNo_UseMutex, // thread-local cache
- kYes_UseMutex, // shared cache
+ kYes_UseMutex // shared cache
};
SkGlyphCache_Globals(UseMutex um) {
--
1.7.5.4

View File

@ -0,0 +1,36 @@
From 80350275c72921ed5ac405c029ae33727467d7c5 Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:15:50 -0400
Subject: [PATCH 05/10] Bug 755869 - [8] Re-apply bug 731384 - Fix compile
errors on older versions of clang r=mattwoodrow
---
gfx/skia/include/core/SkPostConfig.h | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
index 8316f7a..041fe2a 100644
--- a/gfx/skia/include/core/SkPostConfig.h
+++ b/gfx/skia/include/core/SkPostConfig.h
@@ -288,9 +288,18 @@
#if defined(_MSC_VER)
#define SK_OVERRIDE override
#elif defined(__clang__)
+#if __has_feature(cxx_override_control)
// Some documentation suggests we should be using __attribute__((override)),
// but it doesn't work.
#define SK_OVERRIDE override
+#elif defined(__has_extension)
+#if __has_extension(cxx_override_control)
+#define SK_OVERRIDE override
+#endif
+#endif
+#ifndef SK_OVERRIDE
+#define SK_OVERRIDE
+#endif
#else
// Linux GCC ignores "__attribute__((override))" and rejects "override".
#define SK_OVERRIDE
--
1.7.5.4

View File

@ -0,0 +1,147 @@
From 94916fbbc7865c6fe23a57d6edc48c6daf93dda8 Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:16:08 -0400
Subject: [PATCH 06/10] Bug 755869 - [9] Re-apply bug 751814 - Various
Skia fixes for ARM without EDSP and ARMv6+
r=mattwoodrow
---
gfx/skia/include/core/SkMath.h | 5 +--
gfx/skia/include/core/SkPostConfig.h | 45 ++++++++++++++++++++++
gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp | 6 +-
gfx/skia/src/opts/SkBlitRow_opts_arm.cpp | 9 ++++
4 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h
index 5889103..7a4b707 100644
--- a/gfx/skia/include/core/SkMath.h
+++ b/gfx/skia/include/core/SkMath.h
@@ -153,10 +153,7 @@ static inline bool SkIsPow2(int value) {
With this requirement, we can generate faster instructions on some
architectures.
*/
-#if defined(__arm__) \
- && !defined(__thumb__) \
- && !defined(__ARM_ARCH_4T__) \
- && !defined(__ARM_ARCH_5T__)
+#ifdef SK_ARM_HAS_EDSP
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
SkASSERT((int16_t)x == x);
SkASSERT((int16_t)y == y);
diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
index 041fe2a..03105e4 100644
--- a/gfx/skia/include/core/SkPostConfig.h
+++ b/gfx/skia/include/core/SkPostConfig.h
@@ -311,3 +311,48 @@
#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
#endif
+
+//////////////////////////////////////////////////////////////////////
+// ARM defines
+
+#if defined(__GNUC__) && defined(__arm__)
+
+# define SK_ARM_ARCH 3
+
+# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
+ || defined(_ARM_ARCH_4)
+# undef SK_ARM_ARCH
+# define SK_ARM_ARCH 4
+# endif
+
+# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
+# undef SK_ARM_ARCH
+# define SK_ARM_ARCH 5
+# endif
+
+# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
+# undef SK_ARM_ARCH
+# define SK_ARM_ARCH 6
+# endif
+
+# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
+# undef SK_ARM_ARCH
+# define SK_ARM_ARCH 7
+# endif
+
+# undef SK_ARM_HAS_EDSP
+# if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
+ || !defined(__thumb__) \
+ && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
+# define SK_ARM_HAS_EDSP 1
+# endif
+
+#endif
diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
index 20d62e1..deb1bfe 100644
--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
+++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
@@ -11,7 +11,7 @@
#include "SkColorPriv.h"
#include "SkUtils.h"
-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
+#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
void SI8_D16_nofilter_DX_arm(
const SkBitmapProcState& s,
const uint32_t* SK_RESTRICT xy,
@@ -182,7 +182,7 @@ void SI8_opaque_D32_nofilter_DX_arm(const SkBitmapProcState& s,
s.fBitmap->getColorTable()->unlockColors(false);
}
-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
+#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
///////////////////////////////////////////////////////////////////////////////
@@ -200,7 +200,7 @@ void SkBitmapProcState::platformProcs() {
switch (fBitmap->config()) {
case SkBitmap::kIndex8_Config:
-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
+#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
if (justDx && !doFilter) {
#if 0 /* crashing on android device */
fSampleProc16 = SI8_D16_nofilter_DX_arm;
diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
index 2490371..c928888 100644
--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
+++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
@@ -675,8 +675,13 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_
/* dst1_scale and dst2_scale*/
"lsr r9, r5, #24 \n\t" /* src >> 24 */
"lsr r10, r6, #24 \n\t" /* src >> 24 */
+#ifdef SK_ARM_HAS_EDSP
"smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
"smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
+#else
+ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
+ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
+#endif
"lsr r9, r9, #8 \n\t" /* r9 >> 8 */
"lsr r10, r10, #8 \n\t" /* r10 >> 8 */
"rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */
@@ -745,7 +750,11 @@ static void __attribute((noinline,optimize("-fomit-frame-pointer"))) S32A_Blend_
"lsr r6, r5, #24 \n\t" /* src >> 24 */
"and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */
+#ifdef SK_ARM_HAS_EDSP
"smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
+#else
+ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
+#endif
"and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */
"lsr r6, r6, #8 \n\t" /* r6 >> 8 */
"mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */
--
1.7.5.4

View File

@ -0,0 +1,702 @@
From 6982ad469adcdfa2b7bdbf8bbd843bc22d3832fc Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Fri, 18 May 2012 14:52:40 -0400
Subject: [PATCH 07/10] Bug 755869 - [10] Re-apply bug 719872 - Fix crash
on Android by reverting to older FontHost impl
r=mattwoodrow
---
gfx/skia/Makefile.in | 5 +-
gfx/skia/src/ports/SkFontHost_android_old.cpp | 664 +++++++++++++++++++++++++
2 files changed, 668 insertions(+), 1 deletions(-)
create mode 100644 gfx/skia/src/ports/SkFontHost_android_old.cpp
diff --git a/gfx/skia/Makefile.in b/gfx/skia/Makefile.in
index 9da098a..8184f1c 100644
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -327,7 +327,10 @@ endif
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += \
SkDebug_android.cpp \
- SkFontHost_none.cpp \
+ SkFontHost_android_old.cpp \
+ SkFontHost_gamma.cpp \
+ SkFontHost_FreeType.cpp \
+ SkFontHost_tables.cpp \
SkMMapStream.cpp \
SkTime_Unix.cpp \
SkThread_pthread.cpp \
diff --git a/gfx/skia/src/ports/SkFontHost_android_old.cpp b/gfx/skia/src/ports/SkFontHost_android_old.cpp
new file mode 100644
index 0000000..b5c4f3c
--- /dev/null
+++ b/gfx/skia/src/ports/SkFontHost_android_old.cpp
@@ -0,0 +1,664 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkFontHost.h"
+#include "SkDescriptor.h"
+#include "SkMMapStream.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkStream.h"
+#include "SkThread.h"
+#include "SkTSearch.h"
+#include <stdio.h>
+
+#define FONT_CACHE_MEMORY_BUDGET (768 * 1024)
+
+#ifndef SK_FONT_FILE_PREFIX
+ #define SK_FONT_FILE_PREFIX "/fonts/"
+#endif
+
+bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style,
+ bool* isFixedWidth);
+
+static void GetFullPathForSysFonts(SkString* full, const char name[]) {
+ full->set(getenv("ANDROID_ROOT"));
+ full->append(SK_FONT_FILE_PREFIX);
+ full->append(name);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct FamilyRec;
+
+/* This guy holds a mapping of a name -> family, used for looking up fonts.
+ Since it is stored in a stretchy array that doesn't preserve object
+ semantics, we don't use constructor/destructors, but just have explicit
+ helpers to manage our internal bookkeeping.
+*/
+struct NameFamilyPair {
+ const char* fName; // we own this
+ FamilyRec* fFamily; // we don't own this, we just reference it
+
+ void construct(const char name[], FamilyRec* family) {
+ fName = strdup(name);
+ fFamily = family; // we don't own this, so just record the referene
+ }
+
+ void destruct() {
+ free((char*)fName);
+ // we don't own family, so just ignore our reference
+ }
+};
+
+// we use atomic_inc to grow this for each typeface we create
+static int32_t gUniqueFontID;
+
+// this is the mutex that protects these globals
+static SkMutex gFamilyMutex;
+static FamilyRec* gFamilyHead;
+static SkTDArray<NameFamilyPair> gNameList;
+
+struct FamilyRec {
+ FamilyRec* fNext;
+ SkTypeface* fFaces[4];
+
+ FamilyRec()
+ {
+ fNext = gFamilyHead;
+ memset(fFaces, 0, sizeof(fFaces));
+ gFamilyHead = this;
+ }
+};
+
+static SkTypeface* find_best_face(const FamilyRec* family,
+ SkTypeface::Style style) {
+ SkTypeface* const* faces = family->fFaces;
+
+ if (faces[style] != NULL) { // exact match
+ return faces[style];
+ }
+ // look for a matching bold
+ style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
+ if (faces[style] != NULL) {
+ return faces[style];
+ }
+ // look for the plain
+ if (faces[SkTypeface::kNormal] != NULL) {
+ return faces[SkTypeface::kNormal];
+ }
+ // look for anything
+ for (int i = 0; i < 4; i++) {
+ if (faces[i] != NULL) {
+ return faces[i];
+ }
+ }
+ // should never get here, since the faces list should not be empty
+ SkASSERT(!"faces list is empty");
+ return NULL;
+}
+
+static FamilyRec* find_family(const SkTypeface* member) {
+ FamilyRec* curr = gFamilyHead;
+ while (curr != NULL) {
+ for (int i = 0; i < 4; i++) {
+ if (curr->fFaces[i] == member) {
+ return curr;
+ }
+ }
+ curr = curr->fNext;
+ }
+ return NULL;
+}
+
+/* Returns the matching typeface, or NULL. If a typeface is found, its refcnt
+ is not modified.
+ */
+static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
+ FamilyRec* curr = gFamilyHead;
+ while (curr != NULL) {
+ for (int i = 0; i < 4; i++) {
+ SkTypeface* face = curr->fFaces[i];
+ if (face != NULL && face->uniqueID() == uniqueID) {
+ return face;
+ }
+ }
+ curr = curr->fNext;
+ }
+ return NULL;
+}
+
+/* Remove reference to this face from its family. If the resulting family
+ is empty (has no faces), return that family, otherwise return NULL
+*/
+static FamilyRec* remove_from_family(const SkTypeface* face) {
+ FamilyRec* family = find_family(face);
+ SkASSERT(family->fFaces[face->style()] == face);
+ family->fFaces[face->style()] = NULL;
+
+ for (int i = 0; i < 4; i++) {
+ if (family->fFaces[i] != NULL) { // family is non-empty
+ return NULL;
+ }
+ }
+ return family; // return the empty family
+}
+
+// maybe we should make FamilyRec be doubly-linked
+static void detach_and_delete_family(FamilyRec* family) {
+ FamilyRec* curr = gFamilyHead;
+ FamilyRec* prev = NULL;
+
+ while (curr != NULL) {
+ FamilyRec* next = curr->fNext;
+ if (curr == family) {
+ if (prev == NULL) {
+ gFamilyHead = next;
+ } else {
+ prev->fNext = next;
+ }
+ SkDELETE(family);
+ return;
+ }
+ prev = curr;
+ curr = next;
+ }
+ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
+}
+
+static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
+ NameFamilyPair* list = gNameList.begin();
+ int count = gNameList.count();
+
+ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
+
+ if (index >= 0) {
+ return find_best_face(list[index].fFamily, style);
+ }
+ return NULL;
+}
+
+static SkTypeface* find_typeface(const SkTypeface* familyMember,
+ SkTypeface::Style style) {
+ const FamilyRec* family = find_family(familyMember);
+ return family ? find_best_face(family, style) : NULL;
+}
+
+static void add_name(const char name[], FamilyRec* family) {
+ SkAutoAsciiToLC tolc(name);
+ name = tolc.lc();
+
+ NameFamilyPair* list = gNameList.begin();
+ int count = gNameList.count();
+
+ int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
+
+ if (index < 0) {
+ list = gNameList.insert(~index);
+ list->construct(name, family);
+ }
+}
+
+static void remove_from_names(FamilyRec* emptyFamily)
+{
+#ifdef SK_DEBUG
+ for (int i = 0; i < 4; i++) {
+ SkASSERT(emptyFamily->fFaces[i] == NULL);
+ }
+#endif
+
+ SkTDArray<NameFamilyPair>& list = gNameList;
+
+ // must go backwards when removing
+ for (int i = list.count() - 1; i >= 0; --i) {
+ NameFamilyPair* pair = &list[i];
+ if (pair->fFamily == emptyFamily) {
+ pair->destruct();
+ list.remove(i);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class FamilyTypeface : public SkTypeface {
+public:
+ FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember,
+ bool isFixedWidth)
+ : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) {
+ fIsSysFont = sysFont;
+
+ SkAutoMutexAcquire ac(gFamilyMutex);
+
+ FamilyRec* rec = NULL;
+ if (familyMember) {
+ rec = find_family(familyMember);
+ SkASSERT(rec);
+ } else {
+ rec = SkNEW(FamilyRec);
+ }
+ rec->fFaces[style] = this;
+ }
+
+ virtual ~FamilyTypeface() {
+ SkAutoMutexAcquire ac(gFamilyMutex);
+
+ // remove us from our family. If the family is now empty, we return
+ // that and then remove that family from the name list
+ FamilyRec* family = remove_from_family(this);
+ if (NULL != family) {
+ remove_from_names(family);
+ detach_and_delete_family(family);
+ }
+ }
+
+ bool isSysFont() const { return fIsSysFont; }
+
+ virtual SkStream* openStream() = 0;
+ virtual const char* getUniqueString() const = 0;
+ virtual const char* getFilePath() const = 0;
+
+private:
+ bool fIsSysFont;
+
+ typedef SkTypeface INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class StreamTypeface : public FamilyTypeface {
+public:
+ StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember,
+ SkStream* stream, bool isFixedWidth)
+ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
+ SkASSERT(stream);
+ stream->ref();
+ fStream = stream;
+ }
+ virtual ~StreamTypeface() {
+ fStream->unref();
+ }
+
+ // overrides
+ virtual SkStream* openStream() {
+ // we just ref our existing stream, since the caller will call unref()
+ // when they are through
+ fStream->ref();
+ // must rewind each time, since the caller assumes a "new" stream
+ fStream->rewind();
+ return fStream;
+ }
+ virtual const char* getUniqueString() const { return NULL; }
+ virtual const char* getFilePath() const { return NULL; }
+
+private:
+ SkStream* fStream;
+
+ typedef FamilyTypeface INHERITED;
+};
+
+class FileTypeface : public FamilyTypeface {
+public:
+ FileTypeface(Style style, bool sysFont, SkTypeface* familyMember,
+ const char path[], bool isFixedWidth)
+ : INHERITED(style, sysFont, familyMember, isFixedWidth) {
+ SkString fullpath;
+
+ if (sysFont) {
+ GetFullPathForSysFonts(&fullpath, path);
+ path = fullpath.c_str();
+ }
+ fPath.set(path);
+ }
+
+ // overrides
+ virtual SkStream* openStream() {
+ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
+
+ // check for failure
+ if (stream->getLength() <= 0) {
+ SkDELETE(stream);
+ // maybe MMAP isn't supported. try FILE
+ stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
+ if (stream->getLength() <= 0) {
+ SkDELETE(stream);
+ stream = NULL;
+ }
+ }
+ return stream;
+ }
+ virtual const char* getUniqueString() const {
+ const char* str = strrchr(fPath.c_str(), '/');
+ if (str) {
+ str += 1; // skip the '/'
+ }
+ return str;
+ }
+ virtual const char* getFilePath() const {
+ return fPath.c_str();
+ }
+
+private:
+ SkString fPath;
+
+ typedef FamilyTypeface INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+static bool get_name_and_style(const char path[], SkString* name,
+ SkTypeface::Style* style,
+ bool* isFixedWidth, bool isExpected) {
+ SkString fullpath;
+ GetFullPathForSysFonts(&fullpath, path);
+
+ SkMMAPStream stream(fullpath.c_str());
+ if (stream.getLength() > 0) {
+ find_name_and_attributes(&stream, name, style, isFixedWidth);
+ return true;
+ }
+ else {
+ SkFILEStream stream(fullpath.c_str());
+ if (stream.getLength() > 0) {
+ find_name_and_attributes(&stream, name, style, isFixedWidth);
+ return true;
+ }
+ }
+
+ if (isExpected) {
+ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
+ }
+ return false;
+}
+
+// used to record our notion of the pre-existing fonts
+struct FontInitRec {
+ const char* fFileName;
+ const char* const* fNames; // null-terminated list
+};
+
+static const char* gSansNames[] = {
+ "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
+};
+
+static const char* gSerifNames[] = {
+ "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
+ "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
+};
+
+static const char* gMonoNames[] = {
+ "monospace", "courier", "courier new", "monaco", NULL
+};
+
+// deliberately empty, but we use the address to identify fallback fonts
+static const char* gFBNames[] = { NULL };
+
+/* Fonts must be grouped by family, with the first font in a family having the
+ list of names (even if that list is empty), and the following members having
+ null for the list. The names list must be NULL-terminated
+*/
+static const FontInitRec gSystemFonts[] = {
+ { "DroidSans.ttf", gSansNames },
+ { "DroidSans-Bold.ttf", NULL },
+ { "DroidSerif-Regular.ttf", gSerifNames },
+ { "DroidSerif-Bold.ttf", NULL },
+ { "DroidSerif-Italic.ttf", NULL },
+ { "DroidSerif-BoldItalic.ttf", NULL },
+ { "DroidSansMono.ttf", gMonoNames },
+ /* These are optional, and can be ignored if not found in the file system.
+ These are appended to gFallbackFonts[] as they are seen, so we list
+ them in the order we want them to be accessed by NextLogicalFont().
+ */
+ { "DroidSansArabic.ttf", gFBNames },
+ { "DroidSansHebrew.ttf", gFBNames },
+ { "DroidSansThai.ttf", gFBNames },
+ { "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
+ { "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
+ { "DroidSansJapanese.ttf", gFBNames },
+ { "DroidSansFallback.ttf", gFBNames }
+};
+
+#define DEFAULT_NAMES gSansNames
+
+// these globals are assigned (once) by load_system_fonts()
+static FamilyRec* gDefaultFamily;
+static SkTypeface* gDefaultNormal;
+
+/* This is sized conservatively, assuming that it will never be a size issue.
+ It will be initialized in load_system_fonts(), and will be filled with the
+ fontIDs that can be used for fallback consideration, in sorted order (sorted
+ meaning element[0] should be used first, then element[1], etc. When we hit
+ a fontID==0 in the array, the list is done, hence our allocation size is
+ +1 the total number of possible system fonts. Also see NextLogicalFont().
+ */
+static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
+
+/* Called once (ensured by the sentinel check at the beginning of our body).
+ Initializes all the globals, and register the system fonts.
+ */
+static void load_system_fonts() {
+ // check if we've already be called
+ if (NULL != gDefaultNormal) {
+ return;
+ }
+
+ const FontInitRec* rec = gSystemFonts;
+ SkTypeface* firstInFamily = NULL;
+ int fallbackCount = 0;
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
+ // if we're the first in a new family, clear firstInFamily
+ if (rec[i].fNames != NULL) {
+ firstInFamily = NULL;
+ }
+
+ bool isFixedWidth;
+ SkString name;
+ SkTypeface::Style style;
+
+ // we expect all the fonts, except the "fallback" fonts
+ bool isExpected = (rec[i].fNames != gFBNames);
+ if (!get_name_and_style(rec[i].fFileName, &name, &style,
+ &isFixedWidth, isExpected)) {
+ continue;
+ }
+
+ SkTypeface* tf = SkNEW_ARGS(FileTypeface,
+ (style,
+ true, // system-font (cannot delete)
+ firstInFamily, // what family to join
+ rec[i].fFileName,
+ isFixedWidth) // filename
+ );
+
+ if (rec[i].fNames != NULL) {
+ // see if this is one of our fallback fonts
+ if (rec[i].fNames == gFBNames) {
+ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
+ // rec[i].fFileName, fallbackCount, tf->uniqueID());
+ gFallbackFonts[fallbackCount++] = tf->uniqueID();
+ }
+
+ firstInFamily = tf;
+ FamilyRec* family = find_family(tf);
+ const char* const* names = rec[i].fNames;
+
+ // record the default family if this is it
+ if (names == DEFAULT_NAMES) {
+ gDefaultFamily = family;
+ }
+ // add the names to map to this family
+ while (*names) {
+ add_name(*names, family);
+ names += 1;
+ }
+ }
+ }
+
+ // do this after all fonts are loaded. This is our default font, and it
+ // acts as a sentinel so we only execute load_system_fonts() once
+ gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
+ // now terminate our fallback list with the sentinel value
+ gFallbackFonts[fallbackCount] = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
+ const char* name = ((FamilyTypeface*)face)->getUniqueString();
+
+ stream->write8((uint8_t)face->style());
+
+ if (NULL == name || 0 == *name) {
+ stream->writePackedUInt(0);
+// SkDebugf("--- fonthost serialize null\n");
+ } else {
+ uint32_t len = strlen(name);
+ stream->writePackedUInt(len);
+ stream->write(name, len);
+// SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
+ }
+}
+
+SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
+ load_system_fonts();
+
+ int style = stream->readU8();
+
+ int len = stream->readPackedUInt();
+ if (len > 0) {
+ SkString str;
+ str.resize(len);
+ stream->read(str.writable_str(), len);
+
+ const FontInitRec* rec = gSystemFonts;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
+ if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
+ // backup until we hit the fNames
+ for (int j = i; j >= 0; --j) {
+ if (rec[j].fNames != NULL) {
+ return SkFontHost::CreateTypeface(NULL,
+ rec[j].fNames[0], (SkTypeface::Style)style);
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+ const char familyName[],
+ SkTypeface::Style style) {
+ load_system_fonts();
+
+ SkAutoMutexAcquire ac(gFamilyMutex);
+
+ // clip to legal style bits
+ style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
+
+ SkTypeface* tf = NULL;
+
+ if (NULL != familyFace) {
+ tf = find_typeface(familyFace, style);
+ } else if (NULL != familyName) {
+// SkDebugf("======= familyName <%s>\n", familyName);
+ tf = find_typeface(familyName, style);
+ }
+
+ if (NULL == tf) {
+ tf = find_best_face(gDefaultFamily, style);
+ }
+
+ // we ref(), since the symantic is to return a new instance
+ tf->ref();
+ return tf;
+}
+
+SkStream* SkFontHost::OpenStream(uint32_t fontID) {
+ SkAutoMutexAcquire ac(gFamilyMutex);
+
+ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
+ SkStream* stream = tf ? tf->openStream() : NULL;
+
+ if (stream && stream->getLength() == 0) {
+ stream->unref();
+ stream = NULL;
+ }
+ return stream;
+}
+
+size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
+ int32_t* index) {
+ SkAutoMutexAcquire ac(gFamilyMutex);
+
+ FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
+ const char* src = tf ? tf->getFilePath() : NULL;
+
+ if (src) {
+ size_t size = strlen(src);
+ if (path) {
+ memcpy(path, src, SkMin32(size, length));
+ }
+ if (index) {
+ *index = 0; // we don't have collections (yet)
+ }
+ return size;
+ } else {
+ return 0;
+ }
+}
+
+SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
+ load_system_fonts();
+
+ /* First see if fontID is already one of our fallbacks. If so, return
+ its successor. If fontID is not in our list, then return the first one
+ in our list. Note: list is zero-terminated, and returning zero means
+ we have no more fonts to use for fallbacks.
+ */
+ const uint32_t* list = gFallbackFonts;
+ for (int i = 0; list[i] != 0; i++) {
+ if (list[i] == currFontID) {
+ return list[i+1];
+ }
+ }
+ return list[0];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ if (NULL == stream || stream->getLength() <= 0) {
+ return NULL;
+ }
+
+ bool isFixedWidth;
+ SkString name;
+ SkTypeface::Style style;
+ find_name_and_attributes(stream, &name, &style, &isFixedWidth);
+
+ if (!name.isEmpty()) {
+ return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth));
+ } else {
+ return NULL;
+ }
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
+ SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
+ // since we created the stream, we let go of our ref() here
+ stream->unref();
+ return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
--
1.7.5.4

View File

@ -0,0 +1,173 @@
From f941ea32e44a2436d235e83ef1a434289a9d9c1e Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Wed, 23 May 2012 11:40:25 -0400
Subject: [PATCH 08/10] Bug 755869 - [11] Re-apply bug 687188 - Skia
radial gradients should use the 0/1 color stop values
for clamping. r=mattwoodrow
---
gfx/skia/src/effects/SkGradientShader.cpp | 76 +++++++++++++++++++++++------
1 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
index 59ba48c..ea05a39 100644
--- a/gfx/skia/src/effects/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/SkGradientShader.cpp
@@ -204,6 +204,7 @@ private:
mutable SkMallocPixelRef* fCache32PixelRef;
mutable unsigned fCacheAlpha; // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value
+ static SkPMColor PremultiplyColor(SkColor c0, U8CPU alpha);
static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
U8CPU alpha);
@@ -507,6 +508,21 @@ static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) {
return ((n << 1) - (n | (n >> 8))) >> 8;
}
+SkPMColor Gradient_Shader::PremultiplyColor(SkColor c0, U8CPU paintAlpha)
+{
+ SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
+ SkFixed r = SkColorGetR(c0);
+ SkFixed g = SkColorGetG(c0);
+ SkFixed b = SkColorGetB(c0);
+
+ a = SkIntToFixed(a) + 0x8000;
+ r = SkIntToFixed(r) + 0x8000;
+ g = SkIntToFixed(g) + 0x8000;
+ b = SkIntToFixed(b) + 0x8000;
+
+ return SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16);
+}
+
void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
int count, U8CPU paintAlpha) {
SkASSERT(count > 1);
@@ -628,14 +644,14 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) {
const SkPMColor* Gradient_Shader::getCache32() const {
if (fCache32 == NULL) {
// double the count for dither entries
- const int entryCount = kCache32Count * 2;
+ const int entryCount = kCache32Count * 2 + 2;
const size_t allocSize = sizeof(SkPMColor) * entryCount;
if (NULL == fCache32PixelRef) {
fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
(NULL, allocSize, NULL));
}
- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
+ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
if (fColorCount == 2) {
Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
kGradient32Length, fCacheAlpha);
@@ -659,7 +675,7 @@ const SkPMColor* Gradient_Shader::getCache32() const {
SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
(NULL, allocSize, NULL));
SkPMColor* linear = fCache32; // just computed linear data
- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
+ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
SkUnitMapper* map = fMapper;
for (int i = 0; i < kGradient32Length; i++) {
int index = map->mapUnit16((i << 8) | i) >> 8;
@@ -668,10 +684,13 @@ const SkPMColor* Gradient_Shader::getCache32() const {
}
fCache32PixelRef->unref();
fCache32PixelRef = newPR;
- fCache32 = (SkPMColor*)newPR->getAddr();
+ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
}
complete_32bit_cache(fCache32, kCache32Count);
}
+ //Write the clamp colours into the first and last entries of fCache32
+ fCache32[-1] = PremultiplyColor(fOrigColors[0], fCacheAlpha);
+ fCache32[kCache32Count * 2] = PremultiplyColor(fOrigColors[fColorCount - 1], fCacheAlpha);
return fCache32;
}
@@ -857,6 +876,18 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
+ if (proc == clamp_tileproc) {
+ // Read out clamp values from beginning/end of the cache. No need to lerp
+ // or dither
+ if (fx < 0) {
+ sk_memset32(dstC, cache[-1], count);
+ return;
+ } else if (fx > 0xFFFF) {
+ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
+ return;
+ }
+ }
+
// We're a vertical gradient, so no change in a span.
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
@@ -875,6 +906,18 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
+ if (proc == clamp_tileproc) {
+ // Read out clamp values from beginning/end of the cache. No need to lerp
+ // or dither
+ if (fx < 0) {
+ sk_memset32(dstC, cache[-1], count);
+ return;
+ } else if (fx > 0xFFFF) {
+ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
+ return;
+ }
+ }
+
// We're a vertical gradient, so no change in a span.
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
@@ -900,10 +943,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
range.init(fx, dx, count, 0, Gradient_Shader::kGradient32Length);
if ((count = range.fCount0) > 0) {
- sk_memset32_dither(dstC,
- cache[toggle + range.fV0],
- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV0],
- count);
+ // Shouldn't be any need to dither for clamping?
+ sk_memset32(dstC, cache[-1], count);
dstC += count;
}
if ((count = range.fCount1) > 0) {
@@ -922,10 +963,8 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
}
}
if ((count = range.fCount2) > 0) {
- sk_memset32_dither(dstC,
- cache[toggle + range.fV1],
- cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV1],
- count);
+ // Shouldn't be any need to dither for clamping?
+ sk_memset32(dstC, cache[Gradient_Shader::kCache32Count * 2], count);
}
}
@@ -1796,9 +1835,16 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
fOneOverTwoA, posRoot);
- SkFixed index = SkClampMax(t, 0xFFFF);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
+
+ if (t < 0) {
+ *dstC++ = cache[-1];
+ } else if (t > 0xFFFF) {
+ *dstC++ = cache[Gradient_Shader::kCache32Count * 2];
+ } else {
+ SkASSERT(t <= 0xFFFF);
+ *dstC++ = cache[t >> Gradient_Shader::kCache32Shift];
+ }
+
fx += dx;
fy += dy;
b += db;
--
1.7.5.4

View File

@ -0,0 +1,28 @@
From df3be24040f7cb2f9c7ed86ad3e47206630e885f Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Wed, 23 May 2012 14:49:57 -0400
Subject: [PATCH 09/10] Bug 755869 - [12] Re-apply bug 749533 - Add
support for GNU/kFreeBSD and Hurd in Skia.
r=mattwoodrow
---
gfx/skia/include/core/SkPreConfig.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/gfx/skia/include/core/SkPreConfig.h b/gfx/skia/include/core/SkPreConfig.h
index 46c6929..16c4d6c 100644
--- a/gfx/skia/include/core/SkPreConfig.h
+++ b/gfx/skia/include/core/SkPreConfig.h
@@ -35,7 +35,8 @@
#elif defined(ANDROID)
#define SK_BUILD_FOR_ANDROID
#elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
- defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
+ defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \
+ defined(__GLIBC__) || defined(__GNU__)
#define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS
--
1.7.5.4

View File

@ -0,0 +1,36 @@
From dc1292fc8c2b9da900ebcac953120eaffd0d329e Mon Sep 17 00:00:00 2001
From: George Wright <gwright@mozilla.com>
Date: Wed, 23 May 2012 14:52:36 -0400
Subject: [PATCH 10/10] Bug 755869 - [13] Re-apply bug 750733 - Use
handles in API object hooks where possible
r=mattwoodrow
---
gfx/skia/src/xml/SkJS.cpp | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gfx/skia/src/xml/SkJS.cpp b/gfx/skia/src/xml/SkJS.cpp
index f2e7a83..b2717d7 100644
--- a/gfx/skia/src/xml/SkJS.cpp
+++ b/gfx/skia/src/xml/SkJS.cpp
@@ -74,7 +74,7 @@ extern "C" {
#endif
static JSBool
-global_enumerate(JSContext *cx, JSObject *obj)
+global_enumerate(JSContext *cx, JSHandleObject *obj)
{
#ifdef LAZY_STANDARD_CLASSES
return JS_EnumerateStandardClasses(cx, obj);
@@ -84,7 +84,7 @@ global_enumerate(JSContext *cx, JSObject *obj)
}
static JSBool
-global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
+global_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSObject **objp)
{
#ifdef LAZY_STANDARD_CLASSES
if ((flags & JSRESOLVE_ASSIGNING) == 0) {
--
1.7.5.4

View File

@ -0,0 +1,28 @@
From cf855f31194ff071f2c787a7413d70a43f15f204 Mon Sep 17 00:00:00 2001
From: Ehsan Akhgari <ehsan@mozilla.com>
Date: Tue, 29 May 2012 15:39:55 -0400
Subject: [PATCH] Bug 755869 - Re-apply patch from bug 719575 to fix clang
builds for the new Skia r=gw280
---
gfx/skia/src/ports/SkFontHost_mac_coretext.cpp | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
index c43d1a6..ce5f409 100644
--- a/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
+++ b/gfx/skia/src/ports/SkFontHost_mac_coretext.cpp
@@ -807,8 +807,8 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkIPoint* offset) const {
CGSize vertOffset;
CTFontGetVerticalTranslationsForGlyphs(fCTVerticalFont, &glyphID, &vertOffset, 1);
- const SkPoint trans = {SkFloatToScalar(vertOffset.width),
- SkFloatToScalar(vertOffset.height)};
+ const SkPoint trans = {SkScalar(SkFloatToScalar(vertOffset.width)),
+ SkScalar(SkFloatToScalar(vertOffset.height))};
SkPoint floatOffset;
fVerticalMatrix.mapPoints(&floatOffset, &trans, 1);
if (!isSnowLeopard()) {
--
1.7.5.4

16
gfx/skia/patches/README Normal file
View File

@ -0,0 +1,16 @@
This directory contains the patches currently applied against upstream Skia.
The original patches are archived in archive/
See the relevant bugs in bugzilla for information on these patches:
0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch
0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch
0003-SkUserConfig-for-Mozilla.patch
0004-Bug-722011-Fix-trailing-commas-in-enums.patch
0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch
0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch
0007-Bug-719872-Old-Android-FontHost.patch
0008-Bug-687188-Skia-radial-gradients.patch
0009-Bug-755869-FreeBSD-Hurd.patch
0010-Bug-689069-ARM-Opts.patch
0011-Bug-719575-Fix-clang-build.patch

Some files were not shown because too many files have changed in this diff Show More