Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2010-07-11 16:23:48 -07:00
Родитель a3e45c6097 599142a072
Коммит 86b530a417
48 изменённых файлов: 945 добавлений и 535 удалений

Просмотреть файл

@ -4490,21 +4490,16 @@ var CombinedStopReload = {
};
var TabsProgressListener = {
onProgressChange: function (aBrowser, aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress) {
},
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
#ifdef MOZ_CRASHREPORTER
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
if (aRequest instanceof Ci.nsIChannel &&
aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
gCrashReporter.enabled) {
gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
}
#endif
},
#endif
onLocationChange: function (aBrowser, aWebProgress, aRequest, aLocationURI) {
// Filter out any sub-frame loads
@ -4512,9 +4507,6 @@ var TabsProgressListener = {
FullZoom.onLocationChange(aLocationURI, false, aBrowser);
},
onStatusChange: function (aBrowser, aWebProgress, aRequest, aStatus, aMessage) {
},
onRefreshAttempted: function (aBrowser, aWebProgress, aURI, aDelay, aSameURI) {
if (gPrefService.getBoolPref("accessibility.blockautorefresh")) {
let brandBundle = document.getElementById("bundle_brand");
@ -4561,9 +4553,6 @@ var TabsProgressListener = {
return false;
}
return true;
},
onSecurityChange: function (aBrowser, aWebProgress, aRequest, aState) {
}
}

Просмотреть файл

@ -38,11 +38,6 @@ var gFrontProgressListener = {
}
var gAllProgressListener = {
onProgressChange: function (aBrowser, aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress) {
},
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
var state = "onStateChange";
info("AllProgress: " + state + " 0x" + aStateFlags.toString(16));

Просмотреть файл

@ -57,12 +57,7 @@ var gProgressListener = {
ok(gBrowser.tabs.length == kURIs.length, "Correctly opened all expected tabs");
finishTest();
}
},
onProgressChange: function () {},
onLocationChange: function () {},
onStatusChange: function () {},
onSecurityChange: function () {}
}
}
function test() {

Просмотреть файл

@ -35,13 +35,10 @@ var progressListener = {
if (aBrowser == tab.linkedBrowser)
record(arguments.callee.name);
},
onProgressChange: function () {},
onSecurityChange: function () {},
onStateChange: function onStateChange(aBrowser) {
if (aBrowser == tab.linkedBrowser)
record(arguments.callee.name);
},
onStatusChange: function () {},
onLinkIconAvailable: function onLinkIconAvailable(aBrowser) {
if (aBrowser == tab.linkedBrowser)
record(arguments.callee.name);

Просмотреть файл

@ -95,21 +95,6 @@ var gTabsListener = {
// Test finished. This will move to the next one.
waitForFocus(gCurrentTest.finish, gBrowser.ownerDocument.defaultView);
}
},
onProgressChange: function(aBrowser, aWebProgress, aRequest,
aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress) {
},
onStateChange: function(aBrowser, aWebProgress, aRequest,
aStateFlags, aStatus) {
},
onStatusChange: function(aBrowser, aWebProgress, aRequest,
aStatus, aMessage) {
},
onSecurityChange: function(aBrowser, aWebProgress, aRequest, aState) {
},
noLinkIconAvailable: function(aBrowser) {
}
}

Просмотреть файл

@ -92,11 +92,6 @@ function test() {
Services.ww.registerNotification(observer);
gBrowser.addTabsProgressListener({
onLocationChange: function() {},
onProgressChange: function() {},
onSecurityChange: function() {},
onStatusChange: function() {},
onRefreshAttempted: function() {},
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {

Просмотреть файл

@ -62,11 +62,7 @@ function test() {
gBrowser.removeTabsProgressListener(this);
executeSoon(aSetStateCallback);
}
},
onProgressChange: function () {},
onSecurityChange: function () {},
onStateChange: function () {},
onStatusChange: function () {}
}
});
ss.setBrowserState(JSON.stringify(aState));
}
@ -211,11 +207,7 @@ function test() {
gBrowser.removeTabsProgressListener(this);
firstLocationChange();
}
},
onProgressChange: function () {},
onSecurityChange: function () {},
onStateChange: function () {},
onStatusChange: function () {}
}
});
function firstLocationChange() {

Просмотреть файл

@ -530,16 +530,6 @@ TabWindow.prototype = {
},
//// Browser progress listener
onLocationChange: function () {
},
onProgressChange: function () {
},
onSecurityChange: function () {
},
onStateChange: function () {
},
onStatusChange: function () {
},
onLinkIconAvailable: function (aBrowser, aIconURL) {
let self = this;
getFaviconAsImage(aIconURL, function (img) {

Просмотреть файл

@ -1,2 +1,2 @@
repo: f5ab154deef2ffa97f1b2139589ae4a1962090a4
node: 3476582628db128ad061c30cab1a74a0c5d14b9b
node: 7ae0b4af32617677698f9de3ab76bcb154bbf085

Просмотреть файл

@ -1402,7 +1402,7 @@ class Makefile(object):
Inform the makefile of a target which is a candidate for being the default target,
if there isn't already a default target.
"""
if self.defaulttarget is None:
if self.defaulttarget is None and t != '.PHONY':
self.defaulttarget = t
def getpatternvariables(self, pattern):

Просмотреть файл

@ -284,7 +284,7 @@ def ifeq(d, offset):
if token == '(':
arg1, t, offset = parsemakesyntax(d, offset, (',',), itermakefilechars)
if t is None:
raise SyntaxError("Expected two arguments in conditional", d.getloc(offset))
raise SyntaxError("Expected two arguments in conditional", d.getloc(d.lend))
arg1.rstrip()
@ -604,6 +604,9 @@ class ParseStackFrame(object):
self.function = function
self.loc = loc
def __str__(self):
return "<state=%i expansion=%s tokenlist=%s openbrace=%s closebrace=%s>" % (self.parsestate, self.expansion, self.tokenlist, self.openbrace, self.closebrace)
_matchingbrace = {
'(': ')',
'{': '}',
@ -689,7 +692,7 @@ def parsemakesyntax(d, offset, stopon, iterfunc):
stacktop.expansion.appendstr(token)
stacktop = ParseStackFrame(_PARSESTATE_PARENMATCH, stacktop,
stacktop.expansion,
(token, stacktop.closebrace),
(token, stacktop.closebrace, '$'),
openbrace=token, closebrace=stacktop.closebrace, loc=d.getloc(tokenoffset))
elif parsestate == _PARSESTATE_PARENMATCH:
assert token == stacktop.closebrace

Просмотреть файл

@ -3,6 +3,8 @@ test: VAR = value
%.do:
@echo TEST-FAIL: ran target "$@", should have run "all"
.PHONY: test
all:
@echo TEST-PASS: the default target is all

Просмотреть файл

@ -0,0 +1,6 @@
#T returncode: 2
ifeq ($(FOO,VAR))
all:
@echo TEST_FAIL
endif

Просмотреть файл

@ -1,5 +1,5 @@
$(shell \
if test ! -f include-dynamic.inc; then \
if ! test -f include-dynamic.inc; then \
echo "TESTVAR = oldval" > include-dynamic.inc; \
sleep 2; \
echo "TESTVAR = newval" > include-dynamic.inc.in; \

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1006,7 +1006,10 @@ nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
// check the attributes we allow that contain URIs
if (IsAttrURI(keyAtom)) {
// special case src attributes for img tags, because they can't
// run any dangerous code.
if (IsAttrURI(keyAtom) &&
!(nodeType == eHTMLTag_img && keyAtom == nsGkAtoms::src)) {
if (!baseURI) {
baseURI = aContent->GetBaseURI();
}

Просмотреть файл

@ -7,10 +7,6 @@ function test() {
let numLocationChanges = 0;
let listener = {
onStateChange: function() {},
onProgressChange: function() {},
onStatusChange: function() {},
onSecurityChange: function() {},
onLocationChange: function() {
numLocationChanges++;
}

Просмотреть файл

@ -281,7 +281,9 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset = 0;
@ -339,7 +341,9 @@ nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsID
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
NS_ENSURE_TRUE(aOldRightNode && aNewLeftNode, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsCOMPtr<nsIDOMNode> parent;
PRInt32 offset;
@ -395,7 +399,9 @@ nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode *aLeftNode,
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
NS_ENSURE_TRUE(aLeftNode && aRightNode && aParent, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsRangeStore *item;
@ -465,7 +471,9 @@ nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
PRUint32 count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
@ -491,7 +499,9 @@ nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsRangeStore *item;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
@ -533,7 +543,9 @@ nsRangeUpdater::DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewN
NS_ENSURE_TRUE(aOriginalNode && aNewNode, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsRangeStore *item;
@ -568,7 +580,9 @@ nsRangeUpdater::DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt
NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsRangeStore *item;
@ -632,7 +646,9 @@ nsRangeUpdater::DidMoveNode(nsIDOMNode *aOldParent, PRInt32 aOldOffset, nsIDOMNo
NS_ENSURE_TRUE(aOldParent && aNewParent, NS_ERROR_NULL_POINTER);
PRUint32 i, count = mArray.Length();
NS_ENSURE_TRUE(count, NS_OK);
if (!count) {
return NS_OK;
}
nsRangeStore *item;

Просмотреть файл

@ -125,6 +125,9 @@
#include "nsIPrefService.h"
#include "nsIContentFilter.h"
#include "nsEventDispatcher.h"
#include "plbase64.h"
#include "prmem.h"
#include "nsStreamUtils.h"
const PRUnichar nbsp = 160;
@ -1402,60 +1405,25 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
nsCOMPtr<nsIInputStream> imageStream(do_QueryInterface(genericDataObj));
NS_ENSURE_TRUE(imageStream, NS_ERROR_FAILURE);
nsCOMPtr<nsIFile> fileToUse;
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(fileToUse));
if (0 == nsCRT::strcmp(bestFlavor, kJPEGImageMime))
fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.jpg"));
else if (0 == nsCRT::strcmp(bestFlavor, kPNGImageMime))
fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.png"));
else if (0 == nsCRT::strcmp(bestFlavor, kGIFImageMime))
fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.gif"));
nsCOMPtr<nsILocalFile> path = do_QueryInterface(fileToUse);
path->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
nsCOMPtr<nsIOutputStream> outputStream;
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), fileToUse);
nsCString imageData;
rv = NS_ConsumeStream(imageStream, PR_UINT32_MAX, imageData);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 length;
imageStream->Available(&length);
char * base64 = PL_Base64Encode(imageData.get(), imageData.Length(), nsnull);
NS_ENSURE_TRUE(base64, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outputStream, length);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 numWritten;
rv = bufferedOutputStream->WriteFrom(imageStream, length, &numWritten);
NS_ENSURE_SUCCESS(rv, rv);
// force the stream close before we try to insert the image
// into the document.
rv = bufferedOutputStream->Close();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewFileURI(getter_AddRefs(uri), fileToUse);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(uri));
if (fileURL)
{
nsCAutoString urltext;
rv = fileURL->GetSpec(urltext);
if (NS_SUCCEEDED(rv) && !urltext.IsEmpty())
{
stuffToPaste.AssignLiteral("<IMG src=\"");
AppendUTF8toUTF16(urltext, stuffToPaste);
stuffToPaste.AppendLiteral("\" alt=\"\" >");
nsAutoEditBatch beginBatching(this);
rv = InsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(),
NS_LITERAL_STRING(kFileMime),
aSourceDoc,
aDestinationNode, aDestOffset,
aDoDeleteSelection);
}
}
stuffToPaste.AssignLiteral("<IMG src=\"data:");
AppendUTF8toUTF16(bestFlavor, stuffToPaste);
stuffToPaste.AppendLiteral(";base64,");
AppendUTF8toUTF16(base64, stuffToPaste);
stuffToPaste.AppendLiteral("\" alt=\"\" >");
nsAutoEditBatch beginBatching(this);
rv = InsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(),
NS_LITERAL_STRING(kFileMime),
aSourceDoc,
aDestinationNode, aDestOffset,
aDoDeleteSelection);
PR_Free(base64);
}
}

Просмотреть файл

@ -74,6 +74,11 @@ _DATA_FILES = \
data/cfhtml-ooo.txt \
$(NULL)
_CHROME_TEST_FILES = \
test_bug490879.xul \
green.png \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - browserscope 2> /dev/null) | (cd $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) && tar -xf -)
@ -81,3 +86,6 @@ libs:: $(_TEST_FILES)
libs:: $(_DATA_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/data
libs:: $(_CHROME_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)

Двоичные данные
editor/libeditor/html/tests/green.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 334 B

Просмотреть файл

@ -0,0 +1,73 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin"
type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=490879
-->
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Mozilla Bug 490879" onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"/>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=490879"
target="_blank">Mozilla Bug 490879</a>
<p/>
<iframe id="i1" width="200" height="100" src="about:blank" /><br />
<img id="i" src="green.png" />
<p/>
<pre id="test">
</pre>
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
function runTest() {
function verifyContent() {
const kExpectedImgSpec = "data:image/png;base64,";
var e = document.getElementById('i1');
var doc = e.contentDocument;
is(doc.getElementsByTagName("img")[0].src.substring(0, kExpectedImgSpec.length),
kExpectedImgSpec, "The pasted image is a base64-encoded data: URI");
}
function pasteInto() {
var e = document.getElementById('i1');
var doc = e.contentDocument;
doc.designMode = "on";
doc.defaultView.focus();
var selection = doc.defaultView.getSelection();
selection.removeAllRanges();
selection.selectAllChildren(doc.body);
selection.collapseToEnd();
doc.execCommand("paste", false, null);
}
function copyToClipBoard() {
var tmpNode = document.popupNode;
document.popupNode = document.getElementById("i");
const kCmd = "cmd_copyImageContents";
var controller = top.document.commandDispatcher
.getControllerForCommand(kCmd);
ok((controller && controller.isCommandEnabled(kCmd)), "have copy command");
controller.doCommand(kCmd);
document.popupNode = tmpNode;
}
copyToClipBoard();
pasteInto();
verifyContent();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
]]>
</script>
</window>

Просмотреть файл

@ -46,6 +46,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=520182
<div id="dd" contenteditable="true"></div>
<iframe id="ee" src="about:blank"></iframe>
<div id="ff" contenteditable="true"></div>
<iframe id="gg" src="about:blank"></iframe>
<div id="hh" contenteditable="true"></div>
<iframe id="ii" src="about:blank"></iframe>
<div id="jj" contenteditable="true"></div>
<iframe id="kk" src="about:blank"></iframe>
<div id="ll" contenteditable="true"></div>
</div>
<pre id="test">
<script type="application/javascript">
@ -68,6 +74,9 @@ const invalidStyle4Payload = "foo<span style=\"@import 'xxx.css';\">bar</span>ba
const invalidStyle5Payload = "foo<span style=\"@font-face{font-family:xxx;src:'xxx.ttf';}\">bar</span>baz";
const invalidStyle6Payload = "foo<span style=\"@namespace xxx url(http://example.com/);\">bar</span>baz";
const nestedStylePayload = "foo<style>#bar1{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-1&quot;/>');<style></style>#bar2{-moz-binding:url('data:text/xml,<?xml version=&quot;1.0&quot;><binding xmlns=&quot;http://www.mozilla.org/xbl&quot; id=&quot;binding-2&quot;/>');</style>baz";
const validImgSrc1Payload = "foo<img src=\"data:image/png,bar\">baz";
const validImgSrc2Payload = "foo<img src=\"javascript:void('bar');\">baz";
const validImgSrc3Payload = "foo<img src=\"file:///bar.png\">baz";
var tests = [
{
@ -285,6 +294,45 @@ var tests = [
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("ff"),
checkResult: function(html) is(html.indexOf("xxx"), -1, "Should not have retained the namespace style")
},
{
id: "gg",
isIFrame: true,
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("gg").contentDocument.documentElement,
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
},
{
id: "hh",
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("hh"),
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
},
{
id: "ii",
isIFrame: true,
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("ii").contentDocument.documentElement,
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
},
{
id: "jj",
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("jj"),
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
},
{
id: "kk",
isIFrame: true,
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("kk").contentDocument.documentElement,
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
},
{
id: "ll",
payload: invalidStyle6Payload,
rootElement: function() document.getElementById("ll"),
checkResult: function(html) isnot(html.indexOf("bar"), -1, "Should have retained the src attribute for the image")
}
];

Просмотреть файл

@ -72,7 +72,7 @@ public:
nsIOSurface *surf,
CGColorSpaceRef aColorSpace,
int aX, int aY,
uint32_t aWidth, uint32_t aHeight);
int aWidth, int aHeight);
private:
void Destroy();

Просмотреть файл

@ -676,7 +676,7 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
nsIOSurface *surf,
CGColorSpaceRef aColorSpace,
int aX, int aY,
uint32_t aWidth, uint32_t aHeight) {
int aWidth, int aHeight) {
surf->Lock();
size_t bytesPerRow = surf->GetBytesPerRow();
size_t ioWidth = surf->GetWidth();

Просмотреть файл

@ -68,6 +68,8 @@
#include "nsCRT.h"
using namespace mozilla;
gfxFontCache *gfxFontCache::gGlobalCache = nsnull;
static PRLogModuleInfo *gFontSelection = PR_NewLogModule("fontSelectionLog");
@ -1399,6 +1401,152 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, PRUint32 aGlyphID, PRBool aNeed
aExtents->SetTightGlyphExtents(aGlyphID, bounds);
}
// Try to initialize font metrics by reading sfnt tables directly;
// set mIsValid=TRUE and return TRUE on success.
// Return FALSE if the gfxFontEntry subclass does not
// implement GetFontTable(), or for non-sfnt fonts where tables are
// not available.
PRBool
gfxFont::InitMetricsFromSfntTables(Metrics& aMetrics)
{
mIsValid = PR_FALSE; // font is NOT valid in case of early return
const PRUint32 kHeadTableTag = TRUETYPE_TAG('h','e','a','d');
const PRUint32 kHheaTableTag = TRUETYPE_TAG('h','h','e','a');
const PRUint32 kPostTableTag = TRUETYPE_TAG('p','o','s','t');
const PRUint32 kOS_2TableTag = TRUETYPE_TAG('O','S','/','2');
if (mFUnitsConvFactor == 0.0) {
// If the conversion factor from FUnits is not yet set,
// 'head' table is required; otherwise we cannot read any metrics
// because we don't know unitsPerEm
nsAutoTArray<PRUint8,sizeof(HeadTable)> headData;
if (NS_FAILED(mFontEntry->GetFontTable(kHeadTableTag, headData)) ||
headData.Length() < sizeof(HeadTable)) {
return PR_FALSE; // no 'head' table -> not an sfnt
}
HeadTable *head = reinterpret_cast<HeadTable*>(headData.Elements());
PRUint32 unitsPerEm = head->unitsPerEm;
if (!unitsPerEm) {
return PR_TRUE; // is an sfnt, but not valid
}
mFUnitsConvFactor = mAdjustedSize / unitsPerEm;
}
// 'hhea' table is required to get vertical extents
nsAutoTArray<PRUint8,sizeof(HheaTable)> hheaData;
if (NS_FAILED(mFontEntry->GetFontTable(kHheaTableTag, hheaData)) ||
hheaData.Length() < sizeof(HheaTable)) {
return PR_FALSE; // no 'hhea' table -> not an sfnt
}
HheaTable *hhea = reinterpret_cast<HheaTable*>(hheaData.Elements());
#define SET_UNSIGNED(field,src) aMetrics.field = PRUint16(src) * mFUnitsConvFactor
#define SET_SIGNED(field,src) aMetrics.field = PRInt16(src) * mFUnitsConvFactor
SET_UNSIGNED(maxAdvance, hhea->advanceWidthMax);
SET_SIGNED(maxAscent, hhea->ascender);
SET_SIGNED(maxDescent, -PRInt16(hhea->descender));
SET_SIGNED(externalLeading, hhea->lineGap);
// 'post' table is required for underline metrics
nsAutoTArray<PRUint8,sizeof(PostTable)> postData;
if (NS_FAILED(mFontEntry->GetFontTable(kPostTableTag, postData))) {
return PR_TRUE; // no 'post' table -> sfnt is not valid
}
if (postData.Length() <
offsetof(PostTable, underlineThickness) + sizeof(PRUint16)) {
return PR_TRUE; // bad post table -> sfnt is not valid
}
PostTable *post = reinterpret_cast<PostTable*>(postData.Elements());
SET_SIGNED(underlineOffset, post->underlinePosition);
SET_UNSIGNED(underlineSize, post->underlineThickness);
// 'OS/2' table is optional, if not found we'll estimate xHeight
// and aveCharWidth by measuring glyphs
nsAutoTArray<PRUint8,sizeof(OS2Table)> os2data;
if (NS_SUCCEEDED(mFontEntry->GetFontTable(kOS_2TableTag, os2data))) {
OS2Table *os2 = reinterpret_cast<OS2Table*>(os2data.Elements());
if (os2data.Length() >= offsetof(OS2Table, sxHeight) +
sizeof(PRInt16) &&
PRUint16(os2->version) >= 2) {
// version 2 and later includes the x-height field
SET_SIGNED(xHeight, os2->sxHeight);
// PR_ABS because of negative xHeight seen in Kokonor (Tibetan) font
aMetrics.xHeight = PR_ABS(aMetrics.xHeight);
}
// this should always be present
if (os2data.Length() >= offsetof(OS2Table, yStrikeoutPosition) +
sizeof(PRInt16)) {
SET_SIGNED(aveCharWidth, os2->xAvgCharWidth);
SET_SIGNED(subscriptOffset, os2->ySubscriptYOffset);
SET_SIGNED(superscriptOffset, os2->ySuperscriptYOffset);
SET_SIGNED(strikeoutSize, os2->yStrikeoutSize);
SET_SIGNED(strikeoutOffset, os2->yStrikeoutPosition);
}
}
mIsValid = PR_TRUE;
return PR_TRUE;
}
static double
RoundToNearestMultiple(double aValue, double aFraction)
{
return floor(aValue/aFraction + 0.5) * aFraction;
}
void gfxFont::CalculateDerivedMetrics(Metrics& aMetrics)
{
aMetrics.maxAscent =
NS_ceil(RoundToNearestMultiple(aMetrics.maxAscent, 1/1024.0));
aMetrics.maxDescent =
NS_ceil(RoundToNearestMultiple(aMetrics.maxDescent, 1/1024.0));
if (aMetrics.xHeight <= 0) {
// only happens if we couldn't find either font metrics
// or a char to measure;
// pick an arbitrary value that's better than zero
aMetrics.xHeight = aMetrics.maxAscent * DEFAULT_XHEIGHT_FACTOR;
}
aMetrics.maxHeight = aMetrics.maxAscent + aMetrics.maxDescent;
if (aMetrics.maxHeight - aMetrics.emHeight > 0.0) {
aMetrics.internalLeading = aMetrics.maxHeight - aMetrics.emHeight;
} else {
aMetrics.internalLeading = 0.0;
}
aMetrics.emAscent = aMetrics.maxAscent * aMetrics.emHeight
/ aMetrics.maxHeight;
aMetrics.emDescent = aMetrics.emHeight - aMetrics.emAscent;
if (GetFontEntry()->IsFixedPitch()) {
// Some Quartz fonts are fixed pitch, but there's some glyph with a bigger
// advance than the average character width... this forces
// those fonts to be recognized like fixed pitch fonts by layout.
aMetrics.maxAdvance = aMetrics.aveCharWidth;
}
if (!aMetrics.subscriptOffset) {
aMetrics.subscriptOffset = aMetrics.xHeight;
}
if (!aMetrics.superscriptOffset) {
aMetrics.superscriptOffset = aMetrics.xHeight;
}
if (!aMetrics.strikeoutOffset) {
aMetrics.strikeoutOffset = aMetrics.xHeight * 0.5;
}
if (!aMetrics.strikeoutSize) {
aMetrics.strikeoutSize = aMetrics.underlineSize;
}
}
void
gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont)
{

Просмотреть файл

@ -223,6 +223,10 @@ public:
return PR_TRUE;
}
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer) {
return NS_ERROR_FAILURE; // all platform subclasses should reimplement this!
}
void SetFamily(gfxFontFamily* aFamily) {
mFamily = aFamily;
}
@ -284,10 +288,6 @@ protected:
mFamily(nsnull)
{ }
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer) {
return NS_ERROR_FAILURE; // all platform subclasses should reimplement this!
}
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold) {
NS_NOTREACHED("oops, somebody didn't override CreateFontInstance");
return nsnull;
@ -1109,11 +1109,28 @@ protected:
// been updated.)
virtual void CreatePlatformShaper() { }
// Helper for subclasses that want to initialize standard metrics from the
// tables of sfnt (TrueType/OpenType) fonts.
// This will use mFUnitsConvFactor if it is already set, else compute it
// from mAdjustedSize and the unitsPerEm in the font's 'head' table.
// Returns TRUE and sets mIsValid=TRUE if successful;
// Returns TRUE but leaves mIsValid=FALSE if the font seems to be broken.
// Returns FALSE if the font does not appear to be an sfnt at all,
// and should be handled (if possible) using other APIs.
PRBool InitMetricsFromSfntTables(Metrics& aMetrics);
// Helper to calculate various derived metrics from the results of
// InitMetricsFromSfntTables or equivalent platform code
void CalculateDerivedMetrics(Metrics& aMetrics);
// some fonts have bad metrics, this method sanitize them.
// if this font has bad underline offset, aIsBadUnderlineFont should be true.
void SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont);
};
// proportion of ascent used for x-height, if unable to read value from font
#define DEFAULT_XHEIGHT_FACTOR 0.56f
class THEBES_API gfxTextRunFactory {
NS_INLINE_DECL_REFCOUNTING(gfxTextRunFactory)

Просмотреть файл

@ -927,31 +927,6 @@ struct TableDirEntry {
AutoSwap_PRUint32 length; // Length of this table.
};
struct HeadTable {
enum {
HEAD_MAGIC_NUMBER = 0x5F0F3CF5,
HEAD_CHECKSUM_CALC_CONST = 0xB1B0AFBA
};
AutoSwap_PRUint32 tableVersionNumber; // Fixed, 0x00010000 for version 1.0.
AutoSwap_PRUint32 fontRevision; // Set by font manufacturer.
AutoSwap_PRUint32 checkSumAdjustment; // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
AutoSwap_PRUint32 magicNumber; // Set to 0x5F0F3CF5.
AutoSwap_PRUint16 flags;
AutoSwap_PRUint16 unitsPerEm; // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
AutoSwap_PRUint64 created; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
AutoSwap_PRUint64 modified; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
AutoSwap_PRInt16 xMin; // For all glyph bounding boxes.
AutoSwap_PRInt16 yMin; // For all glyph bounding boxes.
AutoSwap_PRInt16 xMax; // For all glyph bounding boxes.
AutoSwap_PRInt16 yMax; // For all glyph bounding boxes.
AutoSwap_PRUint16 macStyle; // Bit 0: Bold (if set to 1);
AutoSwap_PRUint16 lowestRecPPEM; // Smallest readable size in pixels.
AutoSwap_PRInt16 fontDirectionHint;
AutoSwap_PRInt16 indexToLocFormat;
AutoSwap_PRInt16 glyphDataFormat;
};
// name table stores set of name record structures, followed by
// large block containing all the strings. name record offset and length
// indicates the offset and length within that block.
@ -961,46 +936,6 @@ struct NameRecordData {
PRUint32 length;
};
struct OS2Table {
AutoSwap_PRUint16 version; // 0004 = OpenType 1.5
AutoSwap_PRInt16 xAvgCharWidth;
AutoSwap_PRUint16 usWeightClass;
AutoSwap_PRUint16 usWidthClass;
AutoSwap_PRUint16 fsType;
AutoSwap_PRInt16 ySubscriptXSize;
AutoSwap_PRInt16 ySubscriptYSize;
AutoSwap_PRInt16 ySubscriptXOffset;
AutoSwap_PRInt16 ySubscriptYOffset;
AutoSwap_PRInt16 ySuperscriptXSize;
AutoSwap_PRInt16 ySuperscriptYSize;
AutoSwap_PRInt16 ySuperscriptXOffset;
AutoSwap_PRInt16 ySuperscriptYOffset;
AutoSwap_PRInt16 yStrikeoutSize;
AutoSwap_PRInt16 yStrikeoutPosition;
AutoSwap_PRInt16 sFamilyClass;
PRUint8 panose[10];
AutoSwap_PRUint32 unicodeRange1;
AutoSwap_PRUint32 unicodeRange2;
AutoSwap_PRUint32 unicodeRange3;
AutoSwap_PRUint32 unicodeRange4;
PRUint8 achVendID[4];
AutoSwap_PRUint16 fsSelection;
AutoSwap_PRUint16 usFirstCharIndex;
AutoSwap_PRUint16 usLastCharIndex;
AutoSwap_PRInt16 sTypoAscender;
AutoSwap_PRInt16 sTypoDescender;
AutoSwap_PRInt16 sTypoLineGap;
AutoSwap_PRUint16 usWinAscent;
AutoSwap_PRUint16 usWinDescent;
AutoSwap_PRUint32 codePageRange1;
AutoSwap_PRUint32 codePageRange2;
AutoSwap_PRInt16 sxHeight;
AutoSwap_PRInt16 sCapHeight;
AutoSwap_PRUint16 usDefaultChar;
AutoSwap_PRUint16 usBreakChar;
AutoSwap_PRUint16 usMaxContext;
};
// old 'kern' table, supported on Windows
// see http://www.microsoft.com/typography/otspec/kern.htm
struct KernTableVersion0 {

Просмотреть файл

@ -339,6 +339,17 @@ struct AutoSwap_PRUint32 {
PRUint32 value;
};
struct AutoSwap_PRInt32 {
#ifdef __SUNPRO_CC
AutoSwap_PRInt32& operator = (const PRInt32 aValue)
{ this->value = NS_SWAP32(aValue); return *this; }
#else
AutoSwap_PRInt32(PRInt32 aValue) { value = NS_SWAP32(aValue); }
#endif
operator PRInt32() const { return NS_SWAP32(value); }
PRInt32 value;
};
struct AutoSwap_PRUint64 {
#ifdef __SUNPRO_CC
AutoSwap_PRUint64& operator = (const PRUint64 aValue)
@ -357,6 +368,103 @@ private:
PRUint8 value[3];
};
struct HeadTable {
enum {
HEAD_MAGIC_NUMBER = 0x5F0F3CF5,
HEAD_CHECKSUM_CALC_CONST = 0xB1B0AFBA
};
AutoSwap_PRUint32 tableVersionNumber; // Fixed, 0x00010000 for version 1.0.
AutoSwap_PRUint32 fontRevision; // Set by font manufacturer.
AutoSwap_PRUint32 checkSumAdjustment; // To compute: set it to 0, sum the entire font as ULONG, then store 0xB1B0AFBA - sum.
AutoSwap_PRUint32 magicNumber; // Set to 0x5F0F3CF5.
AutoSwap_PRUint16 flags;
AutoSwap_PRUint16 unitsPerEm; // Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.
AutoSwap_PRUint64 created; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
AutoSwap_PRUint64 modified; // Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer
AutoSwap_PRInt16 xMin; // For all glyph bounding boxes.
AutoSwap_PRInt16 yMin; // For all glyph bounding boxes.
AutoSwap_PRInt16 xMax; // For all glyph bounding boxes.
AutoSwap_PRInt16 yMax; // For all glyph bounding boxes.
AutoSwap_PRUint16 macStyle; // Bit 0: Bold (if set to 1);
AutoSwap_PRUint16 lowestRecPPEM; // Smallest readable size in pixels.
AutoSwap_PRInt16 fontDirectionHint;
AutoSwap_PRInt16 indexToLocFormat;
AutoSwap_PRInt16 glyphDataFormat;
};
struct OS2Table {
AutoSwap_PRUint16 version; // 0004 = OpenType 1.5
AutoSwap_PRInt16 xAvgCharWidth;
AutoSwap_PRUint16 usWeightClass;
AutoSwap_PRUint16 usWidthClass;
AutoSwap_PRUint16 fsType;
AutoSwap_PRInt16 ySubscriptXSize;
AutoSwap_PRInt16 ySubscriptYSize;
AutoSwap_PRInt16 ySubscriptXOffset;
AutoSwap_PRInt16 ySubscriptYOffset;
AutoSwap_PRInt16 ySuperscriptXSize;
AutoSwap_PRInt16 ySuperscriptYSize;
AutoSwap_PRInt16 ySuperscriptXOffset;
AutoSwap_PRInt16 ySuperscriptYOffset;
AutoSwap_PRInt16 yStrikeoutSize;
AutoSwap_PRInt16 yStrikeoutPosition;
AutoSwap_PRInt16 sFamilyClass;
PRUint8 panose[10];
AutoSwap_PRUint32 unicodeRange1;
AutoSwap_PRUint32 unicodeRange2;
AutoSwap_PRUint32 unicodeRange3;
AutoSwap_PRUint32 unicodeRange4;
PRUint8 achVendID[4];
AutoSwap_PRUint16 fsSelection;
AutoSwap_PRUint16 usFirstCharIndex;
AutoSwap_PRUint16 usLastCharIndex;
AutoSwap_PRInt16 sTypoAscender;
AutoSwap_PRInt16 sTypoDescender;
AutoSwap_PRInt16 sTypoLineGap;
AutoSwap_PRUint16 usWinAscent;
AutoSwap_PRUint16 usWinDescent;
AutoSwap_PRUint32 codePageRange1;
AutoSwap_PRUint32 codePageRange2;
AutoSwap_PRInt16 sxHeight;
AutoSwap_PRInt16 sCapHeight;
AutoSwap_PRUint16 usDefaultChar;
AutoSwap_PRUint16 usBreakChar;
AutoSwap_PRUint16 usMaxContext;
};
struct PostTable {
AutoSwap_PRUint32 version;
AutoSwap_PRInt32 italicAngle;
AutoSwap_PRInt16 underlinePosition;
AutoSwap_PRUint16 underlineThickness;
AutoSwap_PRUint32 isFixedPitch;
AutoSwap_PRUint32 minMemType42;
AutoSwap_PRUint32 maxMemType42;
AutoSwap_PRUint32 minMemType1;
AutoSwap_PRUint32 maxMemType1;
};
struct HheaTable {
AutoSwap_PRUint32 version;
AutoSwap_PRInt16 ascender;
AutoSwap_PRInt16 descender;
AutoSwap_PRInt16 lineGap;
AutoSwap_PRUint16 advanceWidthMax;
AutoSwap_PRInt16 minLeftSideBearing;
AutoSwap_PRInt16 minRightSideBearing;
AutoSwap_PRInt16 xMaxExtent;
AutoSwap_PRInt16 caretSlopeRise;
AutoSwap_PRInt16 caretSlopeRun;
AutoSwap_PRInt16 caretOffset;
AutoSwap_PRInt16 reserved1;
AutoSwap_PRInt16 reserved2;
AutoSwap_PRInt16 reserved3;
AutoSwap_PRInt16 reserved4;
AutoSwap_PRInt16 metricDataFormat;
AutoSwap_PRUint16 numOfLongHorMetrics;
};
#pragma pack()
// Return just the highest bit of the given value, i.e., the highest

Просмотреть файл

@ -324,7 +324,8 @@ gfxGDIFont::Initialize()
DWORD len = GetGlyphOutlineW(dc.GetDC(), PRUnichar('x'), GGO_METRICS, &gm, 0, nsnull, &kIdentityMatrix);
if (len == GDI_ERROR || gm.gmptGlyphOrigin.y <= 0) {
// 56% of ascent, best guess for true type
mMetrics->xHeight = ROUND((double)metrics.tmAscent * 0.56);
mMetrics->xHeight =
ROUND((double)metrics.tmAscent * DEFAULT_XHEIGHT_FACTOR);
} else {
mMetrics->xHeight = gm.gmptGlyphOrigin.y;
}
@ -349,7 +350,8 @@ gfxGDIFont::Initialize()
return;
}
mMetrics->xHeight = ROUND((float)metrics.tmAscent * 0.56f); // 56% of ascent, best guess for non-true type
mMetrics->xHeight =
ROUND((float)metrics.tmAscent * DEFAULT_XHEIGHT_FACTOR);
mMetrics->superscriptOffset = mMetrics->xHeight;
mMetrics->subscriptOffset = mMetrics->xHeight;
mMetrics->strikeoutSize = 1;

Просмотреть файл

@ -204,7 +204,7 @@ public:
// All other fonts will be grouped correctly using family...
switch (mWindowsFamily) {
case FF_DONTCARE:
return PR_TRUE;
return PR_FALSE;
case FF_ROMAN:
return aGeneric.EqualsLiteral("serif");
case FF_SWISS:
@ -221,7 +221,7 @@ public:
}
virtual PRBool SupportsLangGroup(nsIAtom* aLangGroup) const {
if (!aLangGroup) {
if (!aLangGroup || aLangGroup == gfxAtoms::x_unicode) {
return PR_TRUE;
}

Просмотреть файл

@ -91,7 +91,8 @@ gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyl
// synthetic oblique by skewing via the font matrix
PRBool needsOblique =
(mFontEntry != NULL) &&
(!mFontEntry->IsItalic() && (mStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
(!mFontEntry->IsItalic() &&
(mStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
if (needsOblique) {
double skewfactor = (needsOblique ? Fix2X(kATSItalicQDSkew) : 0);
@ -110,11 +111,13 @@ gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyl
cairo_font_options_t *fontOptions = cairo_font_options_create();
// turn off font anti-aliasing based on user pref setting
if (mAdjustedSize <= (float) gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
if (mAdjustedSize <=
(gfxFloat)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_NONE);
}
mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions);
mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm,
fontOptions);
cairo_font_options_destroy(fontOptions);
cairoerr = cairo_scaled_font_status(mScaledFont);
@ -164,20 +167,14 @@ gfxMacFont::SetupCairoFont(gfxContext *aContext)
return PR_TRUE;
}
static double
RoundToNearestMultiple(double aValue, double aFraction)
{
return floor(aValue/aFraction + 0.5) * aFraction;
}
void
gfxMacFont::InitMetrics()
{
gfxFloat size =
PR_MAX(((mAdjustedSize != 0.0f) ? mAdjustedSize : mStyle.size), 1.0f);
mIsValid = PR_FALSE;
::memset(&mMetrics, 0, sizeof(mMetrics));
PRUint32 upem = ::CGFontGetUnitsPerEm(mCGFont);
if (!upem) {
mIsValid = PR_FALSE;
#ifdef DEBUG
char warnBuf[1024];
sprintf(warnBuf, "Bad font metrics for: %s (no unitsPerEm value)",
@ -187,103 +184,87 @@ gfxMacFont::InitMetrics()
return;
}
ATSFontMetrics atsMetrics;
OSStatus err;
mAdjustedSize = PR_MAX(mStyle.size, 1.0f);
mFUnitsConvFactor = mAdjustedSize / upem;
err = ::ATSFontGetHorizontalMetrics(mATSFont, kATSOptionFlagsDefault,
&atsMetrics);
if (err != noErr) {
mIsValid = PR_FALSE;
#ifdef DEBUG
char warnBuf[1024];
sprintf(warnBuf, "Bad font metrics for: %s err: %8.8x",
NS_ConvertUTF16toUTF8(mFontEntry->Name()).get(), PRUint32(err));
NS_WARNING(warnBuf);
#endif
// Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
// platform APIs. The InitMetrics...() functions will set mIsValid on success.
if (!InitMetricsFromSfntTables(mMetrics) &&
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
InitMetricsFromATSMetrics();
}
if (!mIsValid) {
return;
}
if (atsMetrics.xHeight > 0)
mMetrics.xHeight = atsMetrics.xHeight * size;
else
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * size / upem;
if (mAdjustedSize == 0.0f) {
if (mMetrics.xHeight != 0.0f && mStyle.sizeAdjust != 0.0f) {
gfxFloat aspect = mMetrics.xHeight / size;
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
// the recursive call to InitMetrics will see the adjusted size,
// and set up the rest of the metrics fields accordingly
InitMetrics();
return;
}
mAdjustedSize = size;
if (mMetrics.xHeight == 0.0) {
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
}
mMetrics.superscriptOffset = mMetrics.xHeight;
mMetrics.subscriptOffset = mMetrics.xHeight;
mMetrics.underlineOffset = atsMetrics.underlinePosition * size;
mMetrics.underlineSize = atsMetrics.underlineThickness * size;
mMetrics.strikeoutSize = mMetrics.underlineSize;
mMetrics.strikeoutOffset = mMetrics.xHeight / 2;
if (mStyle.sizeAdjust != 0.0 && mStyle.size > 0.0 &&
mMetrics.xHeight > 0.0) {
// apply font-size-adjust, and recalculate metrics
gfxFloat aspect = mMetrics.xHeight / mStyle.size;
mAdjustedSize = mStyle.GetAdjustedSize(aspect);
mFUnitsConvFactor = mAdjustedSize / upem;
mMetrics.xHeight = 0.0;
if (!InitMetricsFromSfntTables(mMetrics) &&
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
InitMetricsFromATSMetrics();
}
if (!mIsValid) {
// this shouldn't happen, as we succeeded earlier before applying
// the size-adjust factor! But check anyway, for paranoia's sake.
return;
}
if (mMetrics.xHeight == 0.0) {
mMetrics.xHeight = ::CGFontGetXHeight(mCGFont) * mFUnitsConvFactor;
}
}
mMetrics.externalLeading = atsMetrics.leading * size;
mMetrics.emHeight = size;
mMetrics.maxAscent =
NS_ceil(RoundToNearestMultiple(atsMetrics.ascent * size, 1/1024.0));
mMetrics.maxDescent =
NS_ceil(-RoundToNearestMultiple(atsMetrics.descent * size, 1/1024.0));
// Once we reach here, we've got basic metrics and set mIsValid = TRUE;
// there should be no further points of actual failure in InitMetrics().
// (If one is introduced, be sure to reset mIsValid to FALSE!)
mMetrics.maxHeight = mMetrics.maxAscent + mMetrics.maxDescent;
if (mMetrics.maxHeight - mMetrics.emHeight > 0.0)
mMetrics.internalLeading = mMetrics.maxHeight - mMetrics.emHeight;
else
mMetrics.internalLeading = 0.0;
mMetrics.emHeight = mAdjustedSize;
mMetrics.maxAdvance = atsMetrics.maxAdvanceWidth * size + mSyntheticBoldOffset;
mMetrics.emAscent = mMetrics.maxAscent * mMetrics.emHeight / mMetrics.maxHeight;
mMetrics.emDescent = mMetrics.emHeight - mMetrics.emAscent;
// Measure/calculate additional metrics, independent of whether we used
// the tables directly or ATS metrics APIs
CFDataRef cmap =
::CGFontCopyTableForTag(mCGFont, TRUETYPE_TAG('c','m','a','p'));
PRUint32 glyphID;
gfxFloat xWidth = GetCharWidth(cmap, upem, size, 'x', &glyphID);
if (atsMetrics.avgAdvanceWidth != 0.0)
mMetrics.aveCharWidth = PR_MIN(atsMetrics.avgAdvanceWidth * size, xWidth);
else if (glyphID != 0)
mMetrics.aveCharWidth = xWidth;
else
mMetrics.aveCharWidth = mMetrics.maxAdvance;
mMetrics.aveCharWidth += mSyntheticBoldOffset;
if (mFontEntry->IsFixedPitch()) {
// Some Quartz fonts are fixed pitch, but there's some glyph with a bigger
// advance than the average character width... this forces
// those fonts to be recognized like fixed pitch fonts by layout.
mMetrics.maxAdvance = mMetrics.aveCharWidth;
if (mMetrics.aveCharWidth <= 0) {
mMetrics.aveCharWidth = GetCharWidth(cmap, 'x', &glyphID);
if (glyphID == 0) {
// we didn't find 'x', so use maxAdvance rather than zero
mMetrics.aveCharWidth = mMetrics.maxAdvance;
}
}
mMetrics.aveCharWidth += mSyntheticBoldOffset;
mMetrics.maxAdvance += mSyntheticBoldOffset;
mMetrics.spaceWidth = GetCharWidth(cmap, upem, size, ' ', &glyphID);
mMetrics.spaceWidth = GetCharWidth(cmap, ' ', &glyphID);
if (glyphID == 0) {
// no space glyph?!
mMetrics.spaceWidth = mMetrics.aveCharWidth;
}
mSpaceGlyph = glyphID;
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, upem, size, '0', &glyphID);
if (glyphID == 0)
mMetrics.zeroOrAveCharWidth = GetCharWidth(cmap, '0', &glyphID);
if (glyphID == 0) {
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
}
if (cmap) {
::CFRelease(cmap);
}
mFUnitsConvFactor = mAdjustedSize / upem;
CalculateDerivedMetrics(mMetrics);
SanitizeMetrics(&mMetrics, mFontEntry->mIsBadUnderlineFont);
mIsValid = PR_TRUE;
#if 0
fprintf (stderr, "Font: %p (%s) size: %f\n", this,
NS_ConvertUTF16toUTF8(GetName()).get(), mStyle.size);
@ -297,8 +278,8 @@ gfxMacFont::InitMetrics()
}
gfxFloat
gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUint32 aUpem, gfxFloat aSize,
PRUnichar aUniChar, PRUint32 *aGlyphID)
gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
PRUint32 *aGlyphID)
{
CGGlyph glyph = 0;
@ -315,7 +296,7 @@ gfxMacFont::GetCharWidth(CFDataRef aCmap, PRUint32 aUpem, gfxFloat aSize,
if (glyph) {
int advance;
if (::CGFontGetGlyphAdvances(mCGFont, &glyph, 1, &advance)) {
return advance * aSize / aUpem;
return advance * mFUnitsConvFactor;
}
}
@ -341,3 +322,42 @@ gfxMacFont::GetFontTable(PRUint32 aTag)
return nsnull;
}
// Try to initialize font metrics via ATS font metrics APIs,
// and set mIsValid = TRUE on success.
// We ONLY call this for local (platform) fonts that are not sfnt format;
// for sfnts, including ALL downloadable fonts, use InitMetricsFromSfntTables
// because ATSFontGetHorizontalMetrics() has been known to crash when
// presented with bad fonts.
void
gfxMacFont::InitMetricsFromATSMetrics()
{
ATSFontMetrics atsMetrics;
OSStatus err;
err = ::ATSFontGetHorizontalMetrics(mATSFont, kATSOptionFlagsDefault,
&atsMetrics);
if (err != noErr) {
#ifdef DEBUG
char warnBuf[1024];
sprintf(warnBuf, "Bad font metrics for: %s err: %8.8x",
NS_ConvertUTF16toUTF8(mFontEntry->Name()).get(), PRUint32(err));
NS_WARNING(warnBuf);
#endif
return;
}
mMetrics.underlineOffset = atsMetrics.underlinePosition * mAdjustedSize;
mMetrics.underlineSize = atsMetrics.underlineThickness * mAdjustedSize;
mMetrics.externalLeading = atsMetrics.leading * mAdjustedSize;
mMetrics.maxAscent = atsMetrics.ascent * mAdjustedSize;
mMetrics.maxDescent = -atsMetrics.descent * mAdjustedSize;
mMetrics.maxAdvance = atsMetrics.maxAdvanceWidth * mAdjustedSize;
mMetrics.aveCharWidth = atsMetrics.avgAdvanceWidth * mAdjustedSize;
mMetrics.xHeight = atsMetrics.xHeight * mAdjustedSize;
mIsValid = PR_TRUE;
}

Просмотреть файл

@ -76,9 +76,12 @@ protected:
virtual void CreatePlatformShaper();
void InitMetrics();
void InitMetricsFromATSMetrics();
gfxFloat GetCharWidth(CFDataRef aCmap, PRUint32 aUpem, gfxFloat aSize,
PRUnichar aUniChar, PRUint32 *aGlyphID);
// Get width and glyph ID for a character; requires that
// mFUnitsConvFactor has been set before this is called
gfxFloat GetCharWidth(CFDataRef aCmap, PRUnichar aUniChar,
PRUint32 *aGlyphID);
static void DestroyBlobFunc(void* aUserData);

Просмотреть файл

@ -66,14 +66,14 @@ public:
ATSFontRef GetFontRef();
nsresult ReadCMAP();
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
protected:
// for use with data fonts
MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
gfxUserFontData *aUserFontData);
virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
ATSFontRef mATSFontRef;

Просмотреть файл

@ -71,7 +71,7 @@ public:
> MapType;
OpaqueSeenType() {
NS_ASSERTION(map.init(1), "Failed to initialize map");
(void) map.init(1);
}
bool ok() { return map.initialized(); }
@ -452,24 +452,18 @@ JetpackActorCommon::RecvMessage(JSContext* cx,
JSObject* implGlobal = JS_GetGlobalObject(cx);
js::AutoValueRooter rval(cx);
const uint32 savedOptions =
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
for (PRUint32 i = 0; i < snapshot.Length(); ++i) {
Variant* vp = results ? results->AppendElement() : NULL;
rval.set(JSVAL_VOID);
if (!JS_CallFunctionValue(cx, implGlobal, snapshot[i], argc, argv,
rval.addr())) {
// If a receiver throws, we drop the exception on the floor.
JS_ClearPendingException(cx);
(void) JS_ReportPendingException(cx);
if (vp)
*vp = void_t();
} else if (vp && !jsval_to_Variant(cx, rval.value(), vp))
*vp = void_t();
}
JS_SetOptions(cx, savedOptions);
return true;
}

Просмотреть файл

@ -37,12 +37,15 @@
#include "base/basictypes.h"
#include "jscntxt.h"
#include "nsXULAppAPI.h"
#include "mozilla/jetpack/JetpackChild.h"
#include "mozilla/jetpack/Handle.h"
#include "jsarray.h"
#include <stdio.h>
namespace mozilla {
namespace jetpack {
@ -54,18 +57,6 @@ JetpackChild::~JetpackChild()
{
}
#define IMPL_PROP_FLAGS (JSPROP_SHARED | \
JSPROP_ENUMERATE | \
JSPROP_READONLY | \
JSPROP_PERMANENT)
const JSPropertySpec
JetpackChild::sImplProperties[] = {
{ "jetpack", 0, IMPL_PROP_FLAGS, UserJetpackGetter, NULL },
{ 0, 0, 0, NULL, NULL }
};
#undef IMPL_PROP_FLAGS
#define IMPL_METHOD_FLAGS (JSFUN_FAST_NATIVE | \
JSPROP_ENUMERATE | \
JSPROP_READONLY | \
@ -79,6 +70,8 @@ JetpackChild::sImplMethods[] = {
JS_FN("unregisterReceivers", UnregisterReceivers, 1, IMPL_METHOD_FLAGS),
JS_FN("wrap", Wrap, 1, IMPL_METHOD_FLAGS),
JS_FN("createHandle", CreateHandle, 0, IMPL_METHOD_FLAGS),
JS_FN("createSandbox", CreateSandbox, 0, IMPL_METHOD_FLAGS),
JS_FN("evalInSandbox", EvalInSandbox, 2, IMPL_METHOD_FLAGS),
JS_FS_END
};
@ -91,7 +84,21 @@ JetpackChild::sGlobalClass = {
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS
};
static void
ReportJetpackErrors(JSContext* cx, const char* message, JSErrorReport* report)
{
const char* filename = "<unknown>";
if (report && report->filename)
filename = report->filename;
int lineno = -1;
if (report)
lineno = report->lineno;
fprintf(stderr, "Jetpack JavaScript Error: %s:%i, %s\n",
filename, lineno, message);
}
bool
JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
MessageLoop* aIOLoop,
@ -101,31 +108,20 @@ JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
return false;
if (!(mRuntime = JS_NewRuntime(32L * 1024L * 1024L)) ||
!(mImplCx = JS_NewContext(mRuntime, 8192)) ||
!(mUserCx = JS_NewContext(mRuntime, 8192)))
!(mCx = JS_NewContext(mRuntime, 8192)))
return false;
{
JSAutoRequest request(mImplCx);
JS_SetContextPrivate(mImplCx, this);
JSObject* implGlobal =
JS_NewGlobalObject(mImplCx, const_cast<JSClass*>(&sGlobalClass));
if (!implGlobal ||
!JS_InitStandardClasses(mImplCx, implGlobal) ||
!JS_DefineProperties(mImplCx, implGlobal,
const_cast<JSPropertySpec*>(sImplProperties)) ||
!JS_DefineFunctions(mImplCx, implGlobal,
const_cast<JSFunctionSpec*>(sImplMethods)))
return false;
}
JS_SetErrorReporter(mCx, ReportJetpackErrors);
{
JSAutoRequest request(mUserCx);
JS_SetContextPrivate(mUserCx, this);
JSObject* userGlobal =
JS_NewGlobalObject(mUserCx, const_cast<JSClass*>(&sGlobalClass));
if (!userGlobal ||
!JS_InitStandardClasses(mUserCx, userGlobal))
JSAutoRequest request(mCx);
JS_SetContextPrivate(mCx, this);
JSObject* implGlobal =
JS_NewGlobalObject(mCx, const_cast<JSClass*>(&sGlobalClass));
if (!implGlobal ||
!JS_InitStandardClasses(mCx, implGlobal) ||
!JS_DefineFunctions(mCx, implGlobal,
const_cast<JSFunctionSpec*>(sImplMethods)))
return false;
}
@ -135,42 +131,37 @@ JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
void
JetpackChild::CleanUp()
{
JS_DestroyContext(mUserCx);
JS_DestroyContext(mImplCx);
ClearReceivers();
JS_DestroyContext(mCx);
JS_DestroyRuntime(mRuntime);
JS_ShutDown();
}
void
JetpackChild::ActorDestroy(ActorDestroyReason why)
{
XRE_ShutdownChildProcess();
}
bool
JetpackChild::RecvSendMessage(const nsString& messageName,
const nsTArray<Variant>& data)
{
JSAutoRequest request(mImplCx);
return JetpackActorCommon::RecvMessage(mImplCx, messageName, data, NULL);
JSAutoRequest request(mCx);
return JetpackActorCommon::RecvMessage(mCx, messageName, data, NULL);
}
static bool
Evaluate(JSContext* cx, const nsCString& code)
bool
JetpackChild::RecvEvalScript(const nsString& code)
{
JSAutoRequest request(cx);
js::AutoValueRooter ignored(cx);
JS_EvaluateScript(cx, JS_GetGlobalObject(cx), code.get(),
code.Length(), "", 1, ignored.addr());
JSAutoRequest request(mCx);
js::AutoValueRooter ignored(mCx);
(void) JS_EvaluateUCScript(mCx, JS_GetGlobalObject(mCx), code.get(),
code.Length(), "", 1, ignored.addr());
return true;
}
bool
JetpackChild::RecvLoadImplementation(const nsCString& code)
{
return Evaluate(mImplCx, code);
}
bool
JetpackChild::RecvLoadUserScript(const nsCString& code)
{
return Evaluate(mUserCx, code);
}
PHandleChild*
JetpackChild::AllocPHandle()
{
@ -189,20 +180,10 @@ JetpackChild::GetThis(JSContext* cx)
{
JetpackChild* self =
static_cast<JetpackChild*>(JS_GetContextPrivate(cx));
JS_ASSERT(cx == self->mImplCx ||
cx == self->mUserCx);
JS_ASSERT(cx == self->mCx);
return self;
}
JSBool
JetpackChild::UserJetpackGetter(JSContext* cx, JSObject* obj, jsval id,
jsval* vp)
{
JSObject* userGlobal = JS_GetGlobalObject(GetThis(cx)->mUserCx);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(userGlobal));
return JS_TRUE;
}
struct MessageResult {
nsString msgName;
nsTArray<Variant> data;
@ -420,5 +401,49 @@ JetpackChild::CreateHandle(JSContext* cx, uintN argc, jsval* vp)
return JS_TRUE;
}
JSBool
JetpackChild::CreateSandbox(JSContext* cx, uintN argc, jsval* vp)
{
if (argc > 0) {
JS_ReportError(cx, "createSandbox takes zero arguments");
return JS_FALSE;
}
JSObject* obj = JS_NewGlobalObject(cx, const_cast<JSClass*>(&sGlobalClass));
if (!obj)
return JS_FALSE;
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_InitStandardClasses(cx, obj);
}
JSBool
JetpackChild::EvalInSandbox(JSContext* cx, uintN argc, jsval* vp)
{
if (argc != 2) {
JS_ReportError(cx, "evalInSandbox takes two arguments");
return JS_FALSE;
}
jsval* argv = JS_ARGV(cx, vp);
JSObject* obj;
if (!JSVAL_IS_OBJECT(argv[0]) ||
!(obj = JSVAL_TO_OBJECT(argv[0])) ||
&sGlobalClass != JS_GetClass(cx, obj) ||
obj == JS_GetGlobalObject(cx)) {
JS_ReportError(cx, "The first argument to evalInSandbox must be a global object created using createSandbox.");
return JS_FALSE;
}
JSString* str = JS_ValueToString(cx, argv[1]);
if (!str)
return JS_FALSE;
js::AutoValueRooter ignored(cx);
return JS_EvaluateUCScript(cx, obj, JS_GetStringChars(str), JS_GetStringLength(str), "", 1,
ignored.addr());
}
} // namespace jetpack
} // namespace mozilla

Просмотреть файл

@ -65,24 +65,21 @@ public:
void CleanUp();
protected:
NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
NS_OVERRIDE virtual bool RecvSendMessage(const nsString& messageName,
const nsTArray<Variant>& data);
NS_OVERRIDE virtual bool RecvLoadImplementation(const nsCString& code);
NS_OVERRIDE virtual bool RecvLoadUserScript(const nsCString& code);
NS_OVERRIDE virtual bool RecvEvalScript(const nsString& script);
NS_OVERRIDE virtual PHandleChild* AllocPHandle();
NS_OVERRIDE virtual bool DeallocPHandle(PHandleChild* actor);
private:
JSRuntime* mRuntime;
JSContext *mImplCx, *mUserCx;
JSContext *mCx;
static JetpackChild* GetThis(JSContext* cx);
static const JSPropertySpec sImplProperties[];
static JSBool UserJetpackGetter(JSContext* cx, JSObject* obj, jsval idval,
jsval* vp);
static const JSFunctionSpec sImplMethods[];
static JSBool SendMessage(JSContext* cx, uintN argc, jsval *vp);
static JSBool CallMessage(JSContext* cx, uintN argc, jsval *vp);
@ -91,6 +88,8 @@ private:
static JSBool UnregisterReceivers(JSContext* cx, uintN argc, jsval *vp);
static JSBool Wrap(JSContext* cx, uintN argc, jsval *vp);
static JSBool CreateHandle(JSContext* cx, uintN argc, jsval *vp);
static JSBool CreateSandbox(JSContext* cx, uintN argc, jsval *vp);
static JSBool EvalInSandbox(JSContext* cx, uintN argc, jsval *vp);
static const JSClass sGlobalClass;

Просмотреть файл

@ -57,44 +57,12 @@ JetpackParent::JetpackParent(JSContext* cx)
JetpackParent::~JetpackParent()
{
XRE_GetIOMessageLoop()
->PostTask(FROM_HERE, new DeleteTask<JetpackProcessParent>(mSubprocess));
if (mSubprocess)
Destroy();
}
NS_IMPL_ISUPPORTS1(JetpackParent, nsIJetpack)
static nsresult
ReadFromURI(const nsAString& aURI,
nsCString* content)
{
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri),
NS_ConvertUTF16toUTF8(aURI));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> channel;
NS_NewChannel(getter_AddRefs(channel), uri);
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
nsCOMPtr<nsIInputStream> input;
rv = channel->Open(getter_AddRefs(input));
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(input, "Channel opened successfully but stream was null?");
char buffer[256];
PRUint32 avail = 0;
input->Available(&avail);
if (avail) {
PRUint32 read = 0;
while (NS_SUCCEEDED(input->Read(buffer, sizeof(buffer), &read)) && read) {
content->Append(buffer, read);
read = 0;
}
}
return NS_OK;
}
NS_IMETHODIMP
JetpackParent::SendMessage(const nsAString& aMessageName)
{
@ -159,31 +127,12 @@ JetpackParent::UnregisterReceivers(const nsAString& aMessageName)
}
NS_IMETHODIMP
JetpackParent::LoadImplementation(const nsAString& aURI)
JetpackParent::EvalScript(const nsAString& aScript)
{
nsCString code;
nsresult rv = ReadFromURI(aURI, &code);
NS_ENSURE_SUCCESS(rv, rv);
if (!SendEvalScript(nsString(aScript)))
return NS_ERROR_FAILURE;
if (!code.IsEmpty() &&
!SendLoadImplementation(code))
rv = NS_ERROR_FAILURE;
return rv;
}
NS_IMETHODIMP
JetpackParent::LoadUserScript(const nsAString& aURI)
{
nsCString code;
nsresult rv = ReadFromURI(aURI, &code);
NS_ENSURE_SUCCESS(rv, rv);
if (!code.IsEmpty() &&
!SendLoadUserScript(code))
rv = NS_ERROR_FAILURE;
return rv;
return NS_OK;
}
bool
@ -223,6 +172,20 @@ JetpackParent::CreateHandle(nsIVariant** aResult)
return xpc->JSToVariant(mContext, OBJECT_TO_JSVAL(hobj), aResult);
}
NS_IMETHODIMP
JetpackParent::Destroy()
{
if (!mSubprocess)
return NS_ERROR_NOT_INITIALIZED;
Close();
XRE_GetIOMessageLoop()
->PostTask(FROM_HERE, new DeleteTask<JetpackProcessParent>(mSubprocess));
mSubprocess = NULL;
return NS_OK;
}
PHandleParent*
JetpackParent::AllocPHandle()
{

Просмотреть файл

@ -78,8 +78,7 @@ both:
async PHandle();
child:
async LoadImplementation(nsCString code);
async LoadUserScript(nsCString code);
async EvalScript(nsString code);
parent:
sync CallMessage(nsString messageName,

Просмотреть файл

@ -39,7 +39,7 @@
interface nsIVariant;
[scriptable, uuid(563afdf8-5d2f-4bb2-9ac0-fb82461d2922)]
[scriptable, uuid(61A5BE65-FAF2-4FD1-96DF-B13A7AD7D88D)]
interface nsIJetpack : nsISupports
{
void sendMessage(in AString aMessageName
@ -53,8 +53,9 @@ interface nsIJetpack : nsISupports
in jsval aReceiver);
void unregisterReceivers(in AString aMessageName);
void loadImplementation(in AString aURI);
void loadUserScript(in AString aURI);
void evalScript(in AString aScript);
nsIVariant createHandle();
void destroy();
};

Просмотреть файл

@ -41,3 +41,43 @@ registerReceiver("drop methods", echo);
registerReceiver("exception coping", echo);
registerReceiver("duplicate receivers", echo);
function ok(c, msg)
{
sendMessage("test result", c, msg);
}
registerReceiver("test sandbox", function() {
var addon = createSandbox();
ok(typeof(addon) == "object", "typeof(addon)");
ok("Date" in addon, "addon.Date exists");
ok(addon.Date !== Date, "Date objects are different");
var fn = "var x; var c = 3; function doit() { x = 12; return 4; }";
evalInSandbox(addon, fn);
ok(addon.x === undefined, "x is undefined");
ok(addon.c == 3, "c is 3");
ok(addon.doit() == 4, "doit called successfully");
ok(addon.x == 12, "x is now 12");
var fn2 = "let function barbar{}";
try {
evalInSandbox(addon, fn2);
ok(false, "bad syntax should throw");
}
catch(e) {
ok(true, "bad syntax should throw");
}
var fn3 = "throw new Error('just kidding')";
try {
evalInSandbox(addon, fn3);
ok(false, "thrown error should be caught");
}
catch(e) {
ok(true, "thrown error should be caught");
}
sendMessage("sandbox done");
});

Просмотреть файл

@ -1,20 +1,41 @@
/*
var jps = jps || Components.classes["@mozilla.org/jetpack/service;1"]
.getService(Components.interfaces.nsIJetpackService),
jetpack = null;
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
var jps = Components.classes["@mozilla.org/jetpack/service;1"]
.getService(Components.interfaces.nsIJetpackService);
var jetpack = null;
load("handle_tests.js");
function createHandle() {
return jetpack.createHandle();
}
const PR_RDONLY = 0x1;
function read_file(f)
{
var fis = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
fis.init(f, PR_RDONLY, 0444, Ci.nsIFileInputStream.CLOSE_ON_EOF);
var lis = Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Ci.nsIConverterInputStream);
lis.init(fis, "UTF-8", 1024, 0);
var data = "";
var r = {};
while (lis.readString(0x0FFFFFFF, r))
data += r.value;
return data;
}
function run_test() {
//jetpack = jps.createJetpack();
return;
jetpack = jps.createJetpack();
run_handle_tests();
jetpack.loadImplementation("file://" + do_get_file("impl.js").path);
jetpack.evalScript(read_file(do_get_file("impl.js")));
var circ1 = {},
circ2 = {},
@ -165,6 +186,13 @@ function run_test() {
jetpack.registerReceiver("duplicate receivers",
function() { do_test_finished() });
jetpack.registerReceiver("test result", function(name, c, msg) {
dump("TEST-INFO | test_jetpack.js | remote check '" + msg + "' result: " + c + "\n");
do_check_true(c);
});
jetpack.registerReceiver("sandbox done", do_test_finished);
do_test_pending();
do_test_pending();
do_test_pending();
do_test_pending();
@ -186,5 +214,12 @@ function run_test() {
undefined, null, true, false, 1, 2, 999, 1/4, "oyez");
jetpack.sendMessage("drop methods", drop);
jetpack.sendMessage("exception coping");
jetpack.sendMessage("duplicate receivers");
jetpack.sendMessage("test sandbox");
do_register_cleanup(function() {
jetpack.destroy();
});
}

Просмотреть файл

@ -204,29 +204,12 @@ nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance*
mResponseHeaderBuf(nsnull)
{
memset(&mNPStream, 0, sizeof(mNPStream));
NS_IF_ADDREF(mInst);
}
nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener(void)
nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener()
{
// remove itself from the instance stream list
nsNPAPIPluginInstance *inst = mInst;
if (inst) {
nsInstanceStream * prev = nsnull;
for (nsInstanceStream *is = inst->mStreams; is != nsnull; is = is->mNext) {
if (is->mPluginStreamListener == this) {
if (!prev)
inst->mStreams = is->mNext;
else
prev->mNext = is->mNext;
delete is;
break;
}
prev = is;
}
}
// remove this from the plugin instance's stream list
mInst->mStreamListeners.RemoveElement(this);
// For those cases when NewStream is never called, we still may need
// to fire a notification callback. Return network error as fallback
@ -240,8 +223,6 @@ nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener(void)
mStreamBuffer=nsnull;
}
NS_IF_RELEASE(inst);
if (mNotifyURL)
PL_strfree(mNotifyURL);
@ -319,7 +300,6 @@ void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason)
return;
if (callbacks->urlnotify) {
NPP npp;
mInst->GetNPP(&npp);
@ -473,8 +453,11 @@ nsNPAPIPluginStreamListener::StopDataPump()
PRBool
nsNPAPIPluginStreamListener::PluginInitJSLoadInProgress()
{
for (nsInstanceStream *is = mInst->mStreams; is; is = is->mNext) {
if (is->mPluginStreamListener->mIsPluginInitJSStream) {
if (!mInst)
return PR_FALSE;
for (unsigned int i = 0; i < mInst->mStreamListeners.Length(); i++) {
if (mInst->mStreamListeners[i]->mIsPluginInitJSStream) {
return PR_TRUE;
}
}
@ -873,16 +856,6 @@ nsNPAPIPluginStreamListener::NewResponseHeader(const char* headerName,
return NS_OK;
}
nsInstanceStream::nsInstanceStream()
{
mNext = nsnull;
mPluginStreamListener = nsnull;
}
nsInstanceStream::~nsInstanceStream()
{
}
NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance)
nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
@ -903,7 +876,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
mWantsAllNetworkStreams(PR_FALSE),
mInPluginInitCall(PR_FALSE),
mLibrary(aLibrary),
mStreams(nsnull),
mStreamListeners(nsnull),
mMIMEType(nsnull),
mOwner(nsnull),
mCurrentPluginEvent(nsnull)
@ -918,17 +891,10 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
}
nsNPAPIPluginInstance::~nsNPAPIPluginInstance(void)
nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
{
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
// clean the stream list if any
for (nsInstanceStream *is = mStreams; is != nsnull;) {
nsInstanceStream * next = is->mNext;
delete is;
is = next;
}
if (mMIMEType) {
PR_Free((void *)mMIMEType);
mMIMEType = nsnull;
@ -1004,19 +970,10 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Stop()
OnPluginDestroy(&mNPP);
// clean up open streams
for (nsInstanceStream *is = mStreams; is != nsnull;) {
nsRefPtr<nsNPAPIPluginStreamListener> listener = is->mPluginStreamListener;
nsInstanceStream *next = is->mNext;
delete is;
is = next;
mStreams = is;
// Clean up our stream after removing it from the list because
// it may be released and destroyed at this point.
if (listener)
listener->CleanUpStream(NPRES_USER_BREAK);
for (unsigned int i = 0; i < mStreamListeners.Length(); i++) {
mStreamListeners[i]->CleanUpStream(NPRES_USER_BREAK);
}
mStreamListeners.Clear();
NPError error = NPERR_GENERIC_ERROR;
if (mCallbacks->destroy) {
@ -1296,23 +1253,10 @@ nsresult nsNPAPIPluginInstance::NewNotifyStream(nsIPluginStreamListener** listen
nsNPAPIPluginStreamListener* stream = new nsNPAPIPluginStreamListener(this, notifyData, aURL);
NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY);
// add it to the list
nsInstanceStream * is = new nsInstanceStream();
NS_ENSURE_TRUE(is, NS_ERROR_OUT_OF_MEMORY);
is->mNext = mStreams;
is->mPluginStreamListener = stream;
mStreams = is;
mStreamListeners.AppendElement(stream);
stream->SetCallNotify(aCallNotify); // set flag in stream to call URLNotify
NS_ADDREF(stream); // Stabilize
nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener);
// Destabilize and avoid leaks. Avoid calling delete <interface pointer>
NS_RELEASE(stream);
return res;
return stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener);
}
NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint)

Просмотреть файл

@ -56,15 +56,6 @@
class nsNPAPIPluginStreamListener;
class nsPIDOMWindow;
struct nsInstanceStream
{
nsInstanceStream *mNext;
nsNPAPIPluginStreamListener *mPluginStreamListener;
nsInstanceStream();
~nsInstanceStream();
};
class nsNPAPITimer
{
public:
@ -180,7 +171,7 @@ public:
// True while creating the plugin, or calling NPP_SetWindow() on it.
PRPackedBool mInPluginInitCall;
PluginLibrary* mLibrary;
nsInstanceStream *mStreams;
nsTArray<nsNPAPIPluginStreamListener*> mStreamListeners;
private:
nsTArray<PopupControlState> mPopupStates;

Просмотреть файл

@ -43,6 +43,7 @@
#include "nsIHTTPHeaderListener.h"
#include "nsIRequest.h"
#include "nsITimer.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#define MAX_PLUGIN_NECKO_BUFFER 16384
@ -85,7 +86,7 @@ protected:
void* mNotifyData;
char* mStreamBuffer;
char* mNotifyURL;
nsNPAPIPluginInstance* mInst;
nsRefPtr<nsNPAPIPluginInstance> mInst;
NPStream mNPStream;
PRUint32 mStreamBufferSize;
PRInt32 mStreamBufferByteCount;

Просмотреть файл

@ -69,6 +69,10 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
CPPSRCS += nptest_gtk2.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),android)
CPPSRCS += nptest_droid.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),os2)
CPPSRCS += nptest_os2.cpp
endif

Просмотреть файл

@ -0,0 +1,111 @@
/* ***** BEGIN LICENSE BLOCK *****
*
* Copyright (c) 2010, Mozilla Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the Mozilla Corporation nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributor(s):
* Brad Lassey <blassey@mozilla.com>
*
* ***** END LICENSE BLOCK ***** */
#include "nptest_platform.h"
#include "npapi.h"
struct _PlatformData {
};
using namespace std;
bool
pluginSupportsWindowMode()
{
return false;
}
bool
pluginSupportsWindowlessMode()
{
return true;
}
NPError
pluginInstanceInit(InstanceData* instanceData)
{
printf("NPERR_INCOMPATIBLE_VERSION_ERROR\n");
return NPERR_INCOMPATIBLE_VERSION_ERROR;
}
void
pluginInstanceShutdown(InstanceData* instanceData)
{
NPN_MemFree(instanceData->platformData);
instanceData->platformData = 0;
}
void
pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
{
instanceData->window = *newWindow;
}
void
pluginWidgetInit(InstanceData* instanceData, void* oldWindow)
{
// XXX nothing here yet since we don't support windowed plugins
}
static void
pluginDrawWindow(InstanceData* instanceData, void* event)
{
return;
}
int16_t
pluginHandleEvent(InstanceData* instanceData, void* event)
{
return 0;
}
int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
int32_t pluginGetClipRegionRectCount(InstanceData* instanceData)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
int32_t pluginGetClipRegionRectEdge(InstanceData* instanceData,
int32_t rectIndex, RectEdge edge)
{
// XXX nothing here yet since we don't support windowed plugins
return NPTEST_INT32_ERROR;
}
void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error)
{
}

Просмотреть файл

@ -175,7 +175,7 @@ class XPCShellTests(object):
'-e', 'print("To start the test, type |_execute_test();|.");',
'-i']
else:
self.xpcsRunArgs = ['-e', '_execute_test();']
self.xpcsRunArgs = ['-e', '_execute_test(); quit(0);']
def getPipes(self):
"""