Merge last green changeset from mozilla-inbound to mozilla-central

This commit is contained in:
Marco Bonardo 2011-06-25 12:04:08 +02:00
Родитель 16b758d276 ce0576e983
Коммит a7a1cf546a
233 изменённых файлов: 15796 добавлений и 1604 удалений

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

@ -376,8 +376,13 @@ BrowserGlue.prototype = {
// Browser startup complete. All initial windows have opened. // Browser startup complete. All initial windows have opened.
_onBrowserStartup: function BG__onBrowserStartup() { _onBrowserStartup: function BG__onBrowserStartup() {
// Show about:rights notification, if needed. // Show about:rights notification, if needed.
if (this._shouldShowRights()) if (this._shouldShowRights()) {
this._showRightsNotification(); this._showRightsNotification();
} else {
// Only show telemetry notification when about:rights notification is not shown.
this._showTelemetryNotification();
}
// Show update notification, if needed. // Show update notification, if needed.
if (Services.prefs.prefHasUserValue("app.update.postupdate")) if (Services.prefs.prefHasUserValue("app.update.postupdate"))
@ -735,6 +740,72 @@ BrowserGlue.prototype = {
} }
}, },
_showTelemetryNotification: function BG__showTelemetryNotification() {
const PREF_TELEMETRY_PROMPTED = "toolkit.telemetry.prompted";
const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
const PREF_TELEMETRY_INFOURL = "toolkit.telemetry.infoURL";
const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner";
try {
// If the user hasn't already been prompted, ask if they want to
// send telemetry data.
if (Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED) ||
Services.prefs.getBoolPref(PREF_TELEMETRY_PROMPTED))
return;
} catch(e) {}
// Stick the notification onto the selected tab of the active browser window.
var win = this.getMostRecentBrowserWindow();
var browser = win.gBrowser; // for closure in notification bar callback
var notifyBox = browser.getNotificationBox();
var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
var productName = brandBundle.GetStringFromName("brandFullName");
var serverOwner = Services.prefs.getCharPref(PREF_TELEMETRY_SERVER_OWNER);
var telemetryText = browserBundle.formatStringFromName("telemetryText", [productName, serverOwner], 2);
var buttons = [
{
label: browserBundle.GetStringFromName("telemetryYesButtonLabel"),
accessKey: browserBundle.GetStringFromName("telemetryYesButtonAccessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {
Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, true);
}
},
{
label: browserBundle.GetStringFromName("telemetryNoButtonLabel"),
accessKey: browserBundle.GetStringFromName("telemetryNoButtonAccessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {}
}
];
// Set pref to indicate we've shown the notification.
Services.prefs.setBoolPref(PREF_TELEMETRY_PROMPTED, true);
var notification = notifyBox.appendNotification(telemetryText, "telemetry", null, notifyBox.PRIORITY_INFO_LOW, buttons);
notification.persistence = 3; // arbitrary number, just so bar sticks around for a bit
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let link = notification.ownerDocument.createElementNS(XULNS, "label");
link.className = "text-link telemetry-text-link";
link.setAttribute("value", browserBundle.GetStringFromName("telemetryLinkLabel"));
link.addEventListener('click', function() {
// Open the learn more url in a new tab
browser.selectedTab = browser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL));
// Remove the notification on which the user clicked
notification.parentNode.removeNotification(notification, true);
// Add a new notification to that tab, with no "Learn more" link
var notifyBox = browser.getNotificationBox();
notifyBox.appendNotification(telemetryText, "telemetry", null, notifyBox.PRIORITY_INFO_LOW, buttons);
}, false);
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
description.appendChild(link);
},
_showPluginUpdatePage: function BG__showPluginUpdatePage() { _showPluginUpdatePage: function BG__showPluginUpdatePage() {
Services.prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false); Services.prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);

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

@ -82,6 +82,10 @@
type="bool"/> type="bool"/>
#endif #endif
<preference id="toolkit.telemetry.enabled"
name="toolkit.telemetry.enabled"
type="bool"/>
<!-- Network tab --> <!-- Network tab -->
<preference id="browser.cache.disk.capacity" name="browser.cache.disk.capacity" type="int"/> <preference id="browser.cache.disk.capacity" name="browser.cache.disk.capacity" type="int"/>
<preference id="browser.offline-apps.notify" name="browser.offline-apps.notify" type="bool"/> <preference id="browser.offline-apps.notify" name="browser.offline-apps.notify" type="bool"/>
@ -193,11 +197,11 @@
preference="layout.spellcheckDefault"/> preference="layout.spellcheckDefault"/>
</groupbox> </groupbox>
#ifdef HAVE_SHELL_SERVICE
<!-- System Defaults --> <!-- System Defaults -->
<groupbox id="systemDefaultsGroup" orient="vertical"> <groupbox id="systemDefaultsGroup" orient="vertical">
<caption label="&systemDefaults.label;"/> <caption label="&systemDefaults.label;"/>
#ifdef HAVE_SHELL_SERVICE
<hbox id="checkDefaultBox" align="center" flex="1"> <hbox id="checkDefaultBox" align="center" flex="1">
<checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser" <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;" label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
@ -212,8 +216,11 @@
oncommand="gAdvancedPane.updateSubmitCrashes();" oncommand="gAdvancedPane.updateSubmitCrashes();"
label="&submitCrashes.label;" accesskey="&submitCrashes.accesskey;"/> label="&submitCrashes.label;" accesskey="&submitCrashes.accesskey;"/>
#endif #endif
</groupbox>
#endif #endif
<checkbox id="submitTelemetryBox" flex="1"
preference="toolkit.telemetry.enabled"
label="&submitTelemetry.label;" accesskey="&submitTelemetry.accesskey;"/>
</groupbox>
</tabpanel> </tabpanel>
<!-- Network --> <!-- Network -->

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

@ -2933,8 +2933,7 @@ SessionStoreService.prototype = {
// force session history to update its internal index and call reload // force session history to update its internal index and call reload
// instead of gotoIndex. See bug 597315. // instead of gotoIndex. See bug 597315.
browser.webNavigation.sessionHistory.getEntryAtIndex(activeIndex, true); browser.webNavigation.sessionHistory.getEntryAtIndex(activeIndex, true);
browser.webNavigation.sessionHistory. browser.webNavigation.sessionHistory.reloadCurrentEntry();
QueryInterface(Ci.nsISHistory).reloadCurrentEntry();
} }
catch (ex) { catch (ex) {
// ignore page load errors // ignore page load errors

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

@ -325,3 +325,13 @@ syncPromoNotification.bookmarks.description=You can access your bookmarks on all
# The final space separates this text from the Learn More link. # The final space separates this text from the Learn More link.
syncPromoNotification.passwords.description=You can access your passwords on all your devices with %S.\u0020 syncPromoNotification.passwords.description=You can access your passwords on all your devices with %S.\u0020
syncPromoNotification.learnMoreLinkText=Learn More syncPromoNotification.learnMoreLinkText=Learn More
# Telemetry prompt
# LOCALIZATION NOTE (telemetryText): %1$S will be replaced by brandFullName,
# and %2$S by the value of the toolkit.telemetry.server_owner preference.
telemetryText = Would you like to help improve %1$S by automatically reporting memory usage, performance, and responsiveness to %2$S?
telemetryLinkLabel = Learn More
telemetryYesButtonLabel = Yes
telemetryYesButtonAccessKey = Y
telemetryNoButtonLabel = No
telemetryNoButtonAccessKey = N

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

@ -29,6 +29,8 @@
<!ENTITY checkNow.accesskey "N"> <!ENTITY checkNow.accesskey "N">
<!ENTITY submitCrashes.label "Submit crash reports"> <!ENTITY submitCrashes.label "Submit crash reports">
<!ENTITY submitCrashes.accesskey "S"> <!ENTITY submitCrashes.accesskey "S">
<!ENTITY submitTelemetry.label "Submit performance data">
<!ENTITY submitTelemetry.accesskey "P">
<!ENTITY networkTab.label "Network"> <!ENTITY networkTab.label "Network">

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

@ -2167,6 +2167,10 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
-moz-margin-start: 0; /* override default label margin to match description margin */ -moz-margin-start: 0; /* override default label margin to match description margin */
} }
.telemetry-text-link {
color: #fff;
}
#addons-notification-icon { #addons-notification-icon {
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png); list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric-16.png);
} }

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

@ -979,6 +979,8 @@ public:
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
nsresult Normalize();
/** /**
* Get the base URI for any relative URIs within this piece of * Get the base URI for any relative URIs within this piece of
* content. Generally, this is the document's base URI, but certain * content. Generally, this is the document's base URI, but certain

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

@ -5362,10 +5362,14 @@ public:
mFlags = WANT_ALL_TRACES; mFlags = WANT_ALL_TRACES;
} }
NS_IMETHOD_(void) DescribeNode(CCNodeType type, NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt refCount,
nsrefcnt refcount, size_t objSz,
size_t objsz, const char *objName)
const char* objname) {
}
NS_IMETHOD_(void) DescribeGCedNode(PRBool isMarked,
size_t objSz,
const char *objName)
{ {
} }
NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root) NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root)

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

@ -1808,11 +1808,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
else { else {
PR_snprintf(name, sizeof(name), "nsDocument %s", uri.get()); PR_snprintf(name, sizeof(name), "nsDocument %s", uri.get());
} }
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsDocument), name); cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsDocument), name);
} }
else { else {
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsDocument), NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsDocument, tmp->mRefCnt.get())
"nsDocument");
} }
// Always need to traverse script objects, so do that before we check // Always need to traverse script objects, so do that before we check
@ -5774,12 +5773,7 @@ nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::Normalize() nsDocument::Normalize()
{ {
for (PRUint32 i = 0; i < mChildren.ChildCount(); ++i) { return nsIDocument::Normalize();
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mChildren.ChildAt(i)));
node->Normalize();
}
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -369,7 +369,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
jsval targetv; jsval targetv;
nsContentUtils::WrapNative(ctx, nsContentUtils::WrapNative(ctx,
JS_GetGlobalForObject(ctx, object), JS_GetGlobalForObject(ctx, object),
aTarget, &targetv); aTarget, &targetv, nsnull, PR_TRUE);
// To keep compatibility with e10s message manager, // To keep compatibility with e10s message manager,
// define empty objects array. // define empty objects array.
@ -382,6 +382,11 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
} }
} }
js::AutoValueRooter objectsv(ctx);
objectsv.set(OBJECT_TO_JSVAL(aObjectsArray));
if (!JS_WrapValue(ctx, objectsv.jsval_addr()))
return NS_ERROR_UNEXPECTED;
jsval json = JSVAL_NULL; jsval json = JSVAL_NULL;
if (!aJSON.IsEmpty()) { if (!aJSON.IsEmpty()) {
if (!JS_ParseJSON(ctx, (jschar*)nsString(aJSON).get(), if (!JS_ParseJSON(ctx, (jschar*)nsString(aJSON).get(),
@ -400,8 +405,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
JS_DefineProperty(ctx, param, "sync", JS_DefineProperty(ctx, param, "sync",
BOOLEAN_TO_JSVAL(aSync), NULL, NULL, JSPROP_ENUMERATE); BOOLEAN_TO_JSVAL(aSync), NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(ctx, param, "json", json, NULL, NULL, JSPROP_ENUMERATE); JS_DefineProperty(ctx, param, "json", json, NULL, NULL, JSPROP_ENUMERATE);
JS_DefineProperty(ctx, param, "objects", OBJECT_TO_JSVAL(aObjectsArray), JS_DefineProperty(ctx, param, "objects", objectsv.jsval_value(), NULL, NULL, JSPROP_ENUMERATE);
NULL, NULL, JSPROP_ENUMERATE);
jsval thisValue = JSVAL_VOID; jsval thisValue = JSVAL_VOID;
@ -421,7 +425,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
} }
nsContentUtils::WrapNative(ctx, nsContentUtils::WrapNative(ctx,
JS_GetGlobalForObject(ctx, object), JS_GetGlobalForObject(ctx, object),
defaultThisValue, &thisValue); defaultThisValue, &thisValue, nsnull, PR_TRUE);
} else { } else {
// If the listener is a JS object which has receiveMessage function: // If the listener is a JS object which has receiveMessage function:
NS_ENSURE_STATE(JS_GetProperty(ctx, object, "receiveMessage", NS_ENSURE_STATE(JS_GetProperty(ctx, object, "receiveMessage",

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

@ -172,12 +172,6 @@ nsGenericDOMDataNode::GetPrefix(nsAString& aPrefix)
return NS_OK; return NS_OK;
} }
nsresult
nsGenericDOMDataNode::Normalize()
{
return NS_OK;
}
nsresult nsresult
nsGenericDOMDataNode::IsSupported(const nsAString& aFeature, nsGenericDOMDataNode::IsSupported(const nsAString& aFeature,
const nsAString& aVersion, const nsAString& aVersion,

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

@ -143,7 +143,6 @@ public:
return NS_OK; return NS_OK;
} }
nsresult GetPrefix(nsAString& aPrefix); nsresult GetPrefix(nsAString& aPrefix);
nsresult Normalize();
nsresult IsSupported(const nsAString& aFeature, nsresult IsSupported(const nsAString& aFeature,
const nsAString& aVersion, const nsAString& aVersion,
PRBool* aReturn); PRBool* aReturn);

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

@ -541,6 +541,96 @@ nsINode::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
return rv; return rv;
} }
nsresult
nsINode::Normalize()
{
// First collect list of nodes to be removed
nsAutoTArray<nsCOMPtr<nsIContent>, 50> nodes;
PRBool canMerge = PR_FALSE;
for (nsIContent* node = this->GetFirstChild();
node;
node = node->GetNextNode(this)) {
if (node->NodeType() != nsIDOMNode::TEXT_NODE) {
canMerge = PR_FALSE;
continue;
}
if (canMerge || node->TextLength() == 0) {
// No need to touch canMerge. That way we can merge across empty
// textnodes if and only if the node before is a textnode
nodes.AppendElement(node);
}
else {
canMerge = PR_TRUE;
}
// If there's no following sibling, then we need to ensure that we don't
// collect following siblings of our (grand)parent as to-be-removed
canMerge = canMerge && !!node->GetNextSibling();
}
if (nodes.IsEmpty()) {
return NS_OK;
}
// We're relying on mozAutoSubtreeModified to keep the doc alive here.
nsIDocument* doc = GetOwnerDoc();
// Batch possible DOMSubtreeModified events.
mozAutoSubtreeModified subtree(doc, nsnull);
// Fire all DOMNodeRemoved events. Optimize the common case of there being
// no listeners
PRBool hasRemoveListeners = nsContentUtils::
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED);
if (hasRemoveListeners) {
for (PRUint32 i = 0; i < nodes.Length(); ++i) {
nsContentUtils::MaybeFireNodeRemoved(nodes[i], nodes[i]->GetNodeParent(),
doc);
}
}
mozAutoDocUpdate batch(doc, UPDATE_CONTENT_MODEL, PR_TRUE);
// Merge and remove all nodes
nsAutoString tmpStr;
for (PRUint32 i = 0; i < nodes.Length(); ++i) {
nsIContent* node = nodes[i];
// Merge with previous node unless empty
const nsTextFragment* text = node->GetText();
if (text->GetLength()) {
nsIContent* target = node->GetPreviousSibling();
NS_ASSERTION((target && target->NodeType() == nsIDOMNode::TEXT_NODE) ||
hasRemoveListeners,
"Should always have a previous text sibling unless "
"mutation events messed us up");
if (!hasRemoveListeners ||
(target && target->NodeType() == nsIDOMNode::TEXT_NODE)) {
if (text->Is2b()) {
target->AppendText(text->Get2b(), text->GetLength(), PR_TRUE);
}
else {
tmpStr.Truncate();
text->AppendTo(tmpStr);
target->AppendText(tmpStr.get(), tmpStr.Length(), PR_TRUE);
}
}
}
// Remove node
nsINode* parent = node->GetNodeParent();
NS_ASSERTION(parent || hasRemoveListeners,
"Should always have a parent unless "
"mutation events messed us up");
if (parent) {
parent->RemoveChildAt(parent->IndexOf(node), PR_TRUE);
}
}
return NS_OK;
}
nsresult nsresult
nsINode::GetDOMBaseURI(nsAString &aURI) const nsINode::GetDOMBaseURI(nsAString &aURI) const
{ {
@ -2619,103 +2709,6 @@ nsGenericElement::HasAttributeNS(const nsAString& aNamespaceURI,
return NS_OK; return NS_OK;
} }
nsresult
nsGenericElement::JoinTextNodes(nsIContent* aFirst,
nsIContent* aSecond)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDOMText> firstText(do_QueryInterface(aFirst, &rv));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMText> secondText(do_QueryInterface(aSecond, &rv));
if (NS_SUCCEEDED(rv)) {
nsAutoString str;
rv = secondText->GetData(str);
if (NS_SUCCEEDED(rv)) {
rv = firstText->AppendData(str);
}
}
}
return rv;
}
nsresult
nsGenericElement::Normalize()
{
// We're relying on mozAutoSubtreeModified to keep the doc alive here.
nsIDocument* doc = GetOwnerDoc();
// Batch possible DOMSubtreeModified events.
mozAutoSubtreeModified subtree(doc, nsnull);
bool hasRemoveListeners = nsContentUtils::
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED);
nsresult result = NS_OK;
PRUint32 index, count = GetChildCount();
for (index = 0; (index < count) && (NS_OK == result); index++) {
nsIContent *child = GetChildAt(index);
switch (child->NodeType()) {
case nsIDOMNode::TEXT_NODE:
// ensure that if the text node is empty, it is removed
if (0 == child->TextLength()) {
if (hasRemoveListeners) {
nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
}
result = RemoveChildAt(index, PR_TRUE);
if (NS_FAILED(result)) {
return result;
}
count--;
index--;
break;
}
if (index+1 < count) {
// Get the sibling. If it's also a text node, then
// remove it from the tree and join the two text
// nodes.
nsCOMPtr<nsIContent> sibling = GetChildAt(index + 1);
if (sibling->NodeType() == nsIDOMNode::TEXT_NODE) {
if (hasRemoveListeners) {
nsContentUtils::MaybeFireNodeRemoved(sibling, this, doc);
}
result = RemoveChildAt(index+1, PR_TRUE);
if (NS_FAILED(result)) {
return result;
}
result = JoinTextNodes(child, sibling);
if (NS_FAILED(result)) {
return result;
}
count--;
index--;
}
}
break;
case nsIDOMNode::ELEMENT_NODE:
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(child);
if (element) {
result = element->Normalize();
}
break;
}
}
return result;
}
static nsXBLBinding* static nsXBLBinding*
GetFirstBindingWithContent(nsBindingManager* aBmgr, nsIContent* aBoundElem) GetFirstBindingWithContent(nsBindingManager* aBmgr, nsIContent* aBoundElem)
{ {
@ -4182,12 +4175,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericElement)
else { else {
PR_snprintf(name, sizeof(name), "nsGenericElement %s", localName.get()); PR_snprintf(name, sizeof(name), "nsGenericElement %s", localName.get());
} }
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsGenericElement), cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsGenericElement),
name); name);
} }
else { else {
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsGenericElement), NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericElement, tmp->mRefCnt.get())
"nsGenericElement");
} }
// Always need to traverse script objects, so do that before we check // Always need to traverse script objects, so do that before we check

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

@ -400,7 +400,6 @@ public:
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes); NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI); NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
NS_IMETHOD GetPrefix(nsAString& aPrefix); NS_IMETHOD GetPrefix(nsAString& aPrefix);
NS_IMETHOD Normalize();
NS_IMETHOD IsSupported(const nsAString& aFeature, NS_IMETHOD IsSupported(const nsAString& aFeature,
const nsAString& aVersion, PRBool* aReturn); const nsAString& aVersion, PRBool* aReturn);
NS_IMETHOD HasAttributes(PRBool* aHasAttributes); NS_IMETHOD HasAttributes(PRBool* aHasAttributes);
@ -479,14 +478,6 @@ public:
*/ */
nsresult LeaveLink(nsPresContext* aPresContext); nsresult LeaveLink(nsPresContext* aPresContext);
/**
* Take two text nodes and append the second to the first.
* @param aFirst the node which will contain first + second [INOUT]
* @param aSecond the node which will be appended
*/
nsresult JoinTextNodes(nsIContent* aFirst,
nsIContent* aSecond);
/** /**
* Check whether a spec feature/version is supported. * Check whether a spec feature/version is supported.
* @param aObject the object, which should support the feature, * @param aObject the object, which should support the feature,

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

@ -198,11 +198,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsNodeInfo)
PR_snprintf(name, sizeof(name), "nsNodeInfo %s", localName.get()); PR_snprintf(name, sizeof(name), "nsNodeInfo %s", localName.get());
} }
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsNodeInfo), name); cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsNodeInfo), name);
} }
else { else {
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(nsNodeInfo), NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsNodeInfo, tmp->mRefCnt.get())
"nsNodeInfo");
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager,

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

@ -42,6 +42,7 @@
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "gfxPattern.h" #include "gfxPattern.h"
#include "mozilla/RefPtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \ #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0xffb42d3c, 0x8281, 0x44c8, \ { 0xffb42d3c, 0x8281, 0x44c8, \
@ -61,6 +62,9 @@ class LayerManager;
namespace ipc { namespace ipc {
class Shmem; class Shmem;
} }
namespace gfx {
class SourceSurface;
}
} }
class nsICanvasRenderingContextInternal : public nsISupports { class nsICanvasRenderingContextInternal : public nsISupports {
@ -96,6 +100,11 @@ public:
// If this canvas context can be represented with a simple Thebes surface, // If this canvas context can be represented with a simple Thebes surface,
// return the surface. Otherwise returns an error. // return the surface. Otherwise returns an error.
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0; NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
// This gets an Azure SourceSurface for the canvas, this will be a snapshot
// of the canvas at the time it was called. This will return null for a
// non-azure canvas.
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
// If this context is opaque, the backing store of the canvas should // If this context is opaque, the backing store of the canvas should
// be created as opaque; all compositing operators should assume the // be created as opaque; all compositing operators should assume the

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

@ -55,6 +55,7 @@ CPPSRCS = \
CanvasImageCache.cpp \ CanvasImageCache.cpp \
CanvasUtils.cpp \ CanvasUtils.cpp \
nsCanvasRenderingContext2D.cpp \ nsCanvasRenderingContext2D.cpp \
nsCanvasRenderingContext2DAzure.cpp \
DocumentRendererParent.cpp \ DocumentRendererParent.cpp \
DocumentRendererChild.cpp \ DocumentRendererChild.cpp \
$(NULL) $(NULL)

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

@ -342,6 +342,9 @@ public:
const PRUnichar* aEncoderOptions, const PRUnichar* aEncoderOptions,
nsIInputStream **aStream); nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface); NS_IMETHOD GetThebesSurface(gfxASurface **surface);
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
{ return nsnull; }
NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; }; NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; };
NS_IMETHOD SetContextOptions(nsIPropertyBag *aOptions); NS_IMETHOD SetContextOptions(nsIPropertyBag *aOptions);

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

@ -373,6 +373,9 @@ public:
const PRUnichar* aEncoderOptions, const PRUnichar* aEncoderOptions,
nsIInputStream **aStream); nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface); NS_IMETHOD GetThebesSurface(gfxASurface **surface);
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
{ return nsnull; }
NS_IMETHOD SetIsOpaque(PRBool isOpaque); NS_IMETHOD SetIsOpaque(PRBool isOpaque);
NS_IMETHOD Reset(); NS_IMETHOD Reset();
already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder, already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
@ -813,7 +816,7 @@ PRUint8 (*nsCanvasRenderingContext2D::sUnpremultiplyTable)[256] = nsnull;
PRUint8 (*nsCanvasRenderingContext2D::sPremultiplyTable)[256] = nsnull; PRUint8 (*nsCanvasRenderingContext2D::sPremultiplyTable)[256] = nsnull;
nsresult nsresult
NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult) NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult)
{ {
nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2D(); nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2D();
if (!ctx) if (!ctx)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -6,6 +6,18 @@
<body> <body>
<canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas> <canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script> <script>
function IsAzureEnabled() {
var enabled = false;
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
enabled = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).AzureEnabled;
} catch (e) { }
return enabled;
}
function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) { function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) {
var pixel = ctx.getImageData(x, y, 1, 1); var pixel = ctx.getImageData(x, y, 1, 1);
var pr = pixel.data[0], var pr = pixel.data[0],
@ -34,15 +46,28 @@ g.addColorStop(1, '#0f0');
ctx.fillStyle = g; ctx.fillStyle = g;
ctx.fillRect(0, 0, 100, 50); ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0); if (IsAzureEnabled()) {
isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0); // XXX - See Bug 666097.
isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0); todo_isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0); todo_isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0); todo_isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0); todo_isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0); todo_isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0); todo_isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0); todo_isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
todo_isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
} else {
isPixel(ctx, 1,1, 0,255,0,255, "1,1", "0,255,0,255", 0);
isPixel(ctx, 50,1, 0,255,0,255, "50,1", "0,255,0,255", 0);
isPixel(ctx, 98,1, 0,255,0,255, "98,1", "0,255,0,255", 0);
isPixel(ctx, 1,25, 0,255,0,255, "1,25", "0,255,0,255", 0);
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
isPixel(ctx, 98,25, 0,255,0,255, "98,25", "0,255,0,255", 0);
isPixel(ctx, 1,48, 0,255,0,255, "1,48", "0,255,0,255", 0);
isPixel(ctx, 50,48, 0,255,0,255, "50,48", "0,255,0,255", 0);
isPixel(ctx, 98,48, 0,255,0,255, "98,48", "0,255,0,255", 0);
}
SimpleTest.finish(); SimpleTest.finish();

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

@ -17,6 +17,17 @@ function IsD2DEnabled() {
} catch(e) {} } catch(e) {}
return enabled; return enabled;
}
function IsAzureEnabled() {
var enabled = false;
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
enabled = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).AzureEnabled;
} catch (e) { }
return enabled;
} }
</script> </script>
@ -245,7 +256,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -1018,8 +1029,8 @@ function todo_isPixel(ctx, x,y, r,g,b,a, d) {
todo(r-d <= pr && pr <= r+d && todo(r-d <= pr && pr <= r+d &&
g-d <= pg && pg <= g+d && g-d <= pg && pg <= g+d &&
b-d <= pb && pb <= b+d && b-d <= pb && pb <= b+d &&
a-d <= pa && pa <= a+d, a-d <= pa && pa <= a+d,
"pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d); "pixel "+pos+" of "+ctx.canvas.id+" is "+pr+","+pg+","+pb+","+pa+" (marked todo); expected "+colour+" +/- " + d);
} }
function test_2d_composite_globalAlpha_canvaspattern() { function test_2d_composite_globalAlpha_canvaspattern() {
@ -1467,7 +1478,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -1573,7 +1584,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -1600,7 +1611,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -1646,7 +1657,7 @@ ok(ctx.globalCompositeOperation == 'xor', "ctx.globalCompositeOperation == 'xor'
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -3141,6 +3152,7 @@ var canvas = document.getElementById('c119');
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
var _thrown_outer = false; var _thrown_outer = false;
try { try {
ctx.fillStyle = '#0f0'; ctx.fillStyle = '#0f0';
@ -3843,7 +3855,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -6072,9 +6084,15 @@ g.addColorStop(0.75, '#0f0');
g.addColorStop(1, '#f00'); g.addColorStop(1, '#f00');
ctx.fillStyle = g; ctx.fillStyle = g;
ctx.fillRect(0, 0, 100, 50); ctx.fillRect(0, 0, 100, 50);
ctx.translate(-50, 0); ctx.translate(-50, 0);
ctx.fillRect(50, 0, 100, 50); ctx.fillRect(50, 0, 100, 50);
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
if (IsAzureEnabled()) {
isPixel(ctx, 25,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
}
isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0);
isPixel(ctx, 75,25, 0,255,0,255, 0); isPixel(ctx, 75,25, 0,255,0,255, 0);
@ -6379,18 +6397,30 @@ var g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
g.addColorStop(0, '#0f0'); g.addColorStop(0, '#0f0');
g.addColorStop(1, '#f00'); g.addColorStop(1, '#f00');
ctx.fillStyle = g; ctx.fillStyle = g;
ctx.fillRect(0, 0, 100, 50); ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 1,1, 0,255,0,255, 0); if (IsAzureEnabled()) {
isPixel(ctx, 50,1, 0,255,0,255, 0); // XXX - See Bug 666097.
isPixel(ctx, 98,1, 0,255,0,255, 0); todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 1,25, 0,255,0,255, 0); todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 50,25, 0,255,0,255, 0); todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 98,25, 0,255,0,255, 0); todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0); todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 50,48, 0,255,0,255, 0); todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0); todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
} else {
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
}
} }
</script> </script>
@ -6538,18 +6568,31 @@ var g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
g.addColorStop(0, '#f00'); g.addColorStop(0, '#f00');
g.addColorStop(1, '#0f0'); g.addColorStop(1, '#0f0');
ctx.fillStyle = g; ctx.fillStyle = g;
ctx.fillRect(0, 0, 100, 50); ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 50,1, 0,255,0,255, 0); if (IsAzureEnabled()) {
isPixel(ctx, 98,1, 0,255,0,255, 0); // XXX - See Bug 666097.
isPixel(ctx, 1,25, 0,255,0,255, 0); todo_isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 50,25, 0,255,0,255, 0); todo_isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 98,25, 0,255,0,255, 0); todo_isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0); todo_isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 50,48, 0,255,0,255, 0); todo_isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0); todo_isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
todo_isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
todo_isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
todo_isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
} else {
isPixel(ctx, 1, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 1, 0, 255, 0, 255, 0);
isPixel(ctx, 1, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 25, 0, 255, 0, 255, 0);
isPixel(ctx, 1, 48, 0, 255, 0, 255, 0);
isPixel(ctx, 50, 48, 0, 255, 0, 255, 0);
isPixel(ctx, 98, 48, 0, 255, 0, 255, 0);
}
} }
</script> </script>
@ -7267,10 +7310,16 @@ ctx.fillRect(0, 0, 100, 50);
ctx.translate(50, 25); ctx.translate(50, 25);
ctx.scale(10, 10); ctx.scale(10, 10);
ctx.fillRect(-5, -2.5, 10, 5); ctx.fillRect(-5, -2.5, 10, 5);
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
todo_isPixel(ctx, 75,25, 0,255,0,255, 0);
if (IsAzureEnabled()) {
isPixel(ctx, 25,25, 0,255,0,255, 0);
isPixel(ctx, 50,25, 0,255,0,255, 0);
isPixel(ctx, 75,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 25,25, 0,255,0,255, 0);
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
todo_isPixel(ctx, 75,25, 0,255,0,255, 0);
}
} }
</script> </script>
@ -7420,7 +7469,7 @@ ok(imgdata3.data.length == imgdata4.data.length, "imgdata3.data.length == imgdat
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -7536,7 +7585,7 @@ ok(isTransparentBlack, "isTransparentBlack");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -7568,7 +7617,7 @@ ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanv
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
todo(!_thrown_outer, 'should not throw exception'); todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -7600,7 +7649,7 @@ todo(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCa
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
todo(!_thrown_outer, 'should not throw exception'); todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8039,7 +8088,7 @@ ok(imgdata2.data[3] === 0, "imgdata2.data[\""+(3)+"\"] === 0");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8124,7 +8173,7 @@ ok(imgdata7.data[20*4+3] === 0, "imgdata7.data[20*4+3] === 0");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8174,7 +8223,7 @@ ok(imgdata.height == 1, "imgdata.height == 1");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8206,7 +8255,7 @@ ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanv
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
todo(!_thrown_outer, 'should not throw exception'); todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8699,7 +8748,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8745,7 +8794,7 @@ isPixel(ctx, 1,45, 0,255,0,255, 2);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8789,7 +8838,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -8833,7 +8882,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -9433,7 +9482,7 @@ ok(ctx.lineCap === 'butt', "ctx.lineCap === 'butt'");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -9807,7 +9856,7 @@ ok(ctx.lineJoin === 'bevel', "ctx.lineJoin === 'bevel'");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -10138,7 +10187,7 @@ ok(ctx.miterLimit === 1.5, "ctx.miterLimit === 1.5");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -10428,7 +10477,7 @@ ok(ctx.lineWidth === 1.5, "ctx.lineWidth === 1.5");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -11100,7 +11149,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -11582,7 +11631,12 @@ ctx.beginPath();
ctx.moveTo(0, 25); ctx.moveTo(0, 25);
ctx.arc(200, 25, 0, 0, Math.PI, true); ctx.arc(200, 25, 0, 0, Math.PI, true);
ctx.stroke(); ctx.stroke();
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
if (IsAzureEnabled()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
} }
@ -11880,7 +11934,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -12170,7 +12224,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -12213,7 +12267,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -12393,7 +12447,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -13140,22 +13194,22 @@ ok(ctx.isPointInPath(70, 30) === false, "ctx.isPointInPath(70, 30) === false");
function test_2d_path_isPointInPath_edge() { function test_2d_path_isPointInPath_edge() {
var canvas = document.getElementById('c404'); var canvas = document.getElementById('c404');
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.rect(0, 0, 20, 20); ctx.rect(0, 0, 20, 20);
ok(ctx.isPointInPath(0, 0) === true, "ctx.isPointInPath(0, 0) === true");
ok(ctx.isPointInPath(10, 0) === true, "ctx.isPointInPath(10, 0) === true"); ok(ctx.isPointInPath(0, 0) === true, "ctx.isPointInPath(0, 0) === true");
ok(ctx.isPointInPath(20, 0) === true, "ctx.isPointInPath(20, 0) === true"); ok(ctx.isPointInPath(10, 0) === true, "ctx.isPointInPath(10, 0) === true");
ok(ctx.isPointInPath(20, 10) === true, "ctx.isPointInPath(20, 10) === true"); ok(ctx.isPointInPath(20, 0) === true, "ctx.isPointInPath(20, 0) === true");
ok(ctx.isPointInPath(20, 20) === true, "ctx.isPointInPath(20, 20) === true"); ok(ctx.isPointInPath(20, 10) === true, "ctx.isPointInPath(20, 10) === true");
ok(ctx.isPointInPath(10, 20) === true, "ctx.isPointInPath(10, 20) === true"); ok(ctx.isPointInPath(20, 20) === true, "ctx.isPointInPath(20, 20) === true");
ok(ctx.isPointInPath(0, 20) === true, "ctx.isPointInPath(0, 20) === true"); ok(ctx.isPointInPath(10, 20) === true, "ctx.isPointInPath(10, 20) === true");
ok(ctx.isPointInPath(0, 10) === true, "ctx.isPointInPath(0, 10) === true"); ok(ctx.isPointInPath(0, 20) === true, "ctx.isPointInPath(0, 20) === true");
ok(ctx.isPointInPath(10, -0.01) === false, "ctx.isPointInPath(10, -0.01) === false"); ok(ctx.isPointInPath(0, 10) === true, "ctx.isPointInPath(0, 10) === true");
ok(ctx.isPointInPath(10, 20.01) === false, "ctx.isPointInPath(10, 20.01) === false"); ok(ctx.isPointInPath(10, -0.01) === false, "ctx.isPointInPath(10, -0.01) === false");
ok(ctx.isPointInPath(-0.01, 10) === false, "ctx.isPointInPath(-0.01, 10) === false"); ok(ctx.isPointInPath(10, 20.01) === false, "ctx.isPointInPath(10, 20.01) === false");
ok(ctx.isPointInPath(20.01, 10) === false, "ctx.isPointInPath(20.01, 10) === false"); ok(ctx.isPointInPath(-0.01, 10) === false, "ctx.isPointInPath(-0.01, 10) === false");
ok(ctx.isPointInPath(20.01, 10) === false, "ctx.isPointInPath(20.01, 10) === false");
} }
</script> </script>
@ -13205,7 +13259,7 @@ ok(ctx.isPointInPath(NaN, NaN) === false, "ctx.isPointInPath(NaN, NaN) === false
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -13506,7 +13560,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -13621,7 +13675,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -13727,7 +13781,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -13991,7 +14045,7 @@ isPixel(ctx, 90,45, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -14943,30 +14997,41 @@ ok(pattern.thisImplementsCanvasPattern, "pattern.thisImplementsCanvasPattern");
function test_2d_pattern_basic_zerocanvas() { function test_2d_pattern_basic_zerocanvas() {
var canvas = document.getElementById('c463'); var _thrown_outer = false;
var ctx = canvas.getContext('2d');
var canvas2 = document.createElement('canvas'); try {
canvas2.width = 0; var canvas = document.getElementById('c463');
canvas2.height = 0; var ctx = canvas.getContext('2d');
ok(canvas2.width === 0, "canvas2.width === 0");
ok(canvas2.height === 0, "canvas2.height === 0");
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = '#f00';
ctx2.fillRect(0, 0, 100, 50);
var pattern = ctx.createPattern(canvas2, 'repeat');
ctx.fillStyle = '#0f0'; var canvas2 = document.createElement('canvas');
ctx.fillRect(0, 0, 100, 50); canvas2.width = 0;
ctx.fillStyle = '#f00'; canvas2.height = 0;
ctx.fillStyle = pattern; ok(canvas2.width === 0, "canvas2.width === 0");
ctx.fillRect(0, 0, 100, 50); ok(canvas2.height === 0, "canvas2.height === 0");
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = '#f00';
ctx2.fillRect(0, 0, 100, 50);
var pattern = ctx.createPattern(canvas2, 'repeat');
isPixel(ctx, 1,1, 0,255,0,255, 0); ctx.fillStyle = '#0f0';
isPixel(ctx, 98,1, 0,255,0,255, 0); ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 1,48, 0,255,0,255, 0); ctx.fillStyle = '#f00';
isPixel(ctx, 98,48, 0,255,0,255, 0); ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 100, 50);
isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 98,1, 0,255,0,255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} catch(e) {
_thrown_outer = true;
}
if (IsAzureEnabled()) {
ok(_thrown_outer);
} else {
todo(_thrown_outer, ctx.canvas.is + ' should throw exception INVALID_STATE_ERR');
}
} }
</script> </script>
@ -15594,11 +15659,17 @@ ctx.fillRect(0, 0, 100, 50);
ctx.translate(-128, -78); ctx.translate(-128, -78);
ctx.fillRect(128, 78, 100, 50); ctx.fillRect(128, 78, 100, 50);
todo_isPixel(ctx, 1,1, 0,255,0,255, 0); if (IsAzureEnabled()) {
todo_isPixel(ctx, 98,1, 0,255,0,255, 0); isPixel(ctx, 1,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0); isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0); isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
}
} }
</script> </script>
@ -15692,12 +15763,20 @@ ctx.fillRect(0, -16, 100, 50);
ctx.fillStyle = '#0f0'; ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 16); ctx.fillRect(0, 0, 100, 16);
todo_isPixel(ctx, 1,1, 0,255,0,255, 0); if (IsAzureEnabled()) {
todo_isPixel(ctx, 98,1, 0,255,0,255, 0); isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 98,1, 0,255,0,255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
}
isPixel(ctx, 1,25, 0,255,0,255, 0); isPixel(ctx, 1,25, 0,255,0,255, 0);
isPixel(ctx, 98,25, 0,255,0,255, 0); isPixel(ctx, 98,25, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
} }
@ -15730,8 +15809,14 @@ ctx.fillRect(0, 0, 100, 16);
isPixel(ctx, 1,1, 0,255,0,255, 0); isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 98,1, 0,255,0,255, 0); isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0); if (IsAzureEnabled()) {
isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
}
} }
@ -15795,12 +15880,20 @@ ctx.fillRect(-48, 0, 100, 50);
ctx.fillStyle = '#0f0'; ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 16, 50); ctx.fillRect(0, 0, 16, 50);
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 50,1, 0,255,0,255, 0); isPixel(ctx, 50,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 50,48, 0,255,0,255, 0); isPixel(ctx, 50,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
if (IsAzureEnabled()) {
isPixel(ctx, 1,1, 0,255,0,255, 0);
isPixel(ctx, 98,1, 0,255,0,255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 1,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
}
} }
@ -15832,10 +15925,15 @@ ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 16, 50); ctx.fillRect(0, 0, 16, 50);
isPixel(ctx, 1,1, 0,255,0,255, 0); isPixel(ctx, 1,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
isPixel(ctx, 1,48, 0,255,0,255, 0); isPixel(ctx, 1,48, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
if (IsAzureEnabled()) {
isPixel(ctx, 98,1, 0,255,0,255, 0);
isPixel(ctx, 98,48, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 98,1, 0,255,0,255, 0);
todo_isPixel(ctx, 98,48, 0,255,0,255, 0);
}
} }
</script> </script>
@ -16642,10 +16740,9 @@ ctx.globalCompositeOperation = 'xor';
ctx.shadowColor = '#f00'; ctx.shadowColor = '#f00';
ctx.shadowOffsetX = 100; ctx.shadowOffsetX = 100;
ctx.fillStyle = '#0f0'; ctx.fillStyle = '#0f0';
ctx.fillRect(-100, 0, 200, 50); ctx.fillRect(-100, 0, 200, 50);
isPixel(ctx, 50,25, 0,255,0,255, 2); isPixel(ctx, 50, 25, 255, 255, 0, 255, 2);
} }
</script> </script>
@ -16669,10 +16766,9 @@ ctx.globalCompositeOperation = 'xor';
ctx.shadowColor = '#f00'; ctx.shadowColor = '#f00';
ctx.shadowBlur = 1; ctx.shadowBlur = 1;
ctx.fillStyle = '#0f0'; ctx.fillStyle = '#0f0';
ctx.fillRect(-10, -10, 120, 70); ctx.fillRect(-10, -10, 120, 70);
isPixel(ctx, 50,25, 0,255,0,255, 2); isPixel(ctx, 50, 25, 255, 255, 0, 255, 2);
} }
</script> </script>
@ -18263,7 +18359,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -18566,7 +18662,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -18825,7 +18921,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -18995,7 +19091,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19202,7 +19298,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19316,7 +19412,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19613,7 +19709,7 @@ ok(canvas.getContext('2D') === null, "canvas.getContext('2D') === null");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19639,7 +19735,7 @@ ok(canvas.getContext("") === null, "canvas.getContext(\"\") === null");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19665,7 +19761,7 @@ ok(canvas.getContext('This is not an implemented context in any real browser') =
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19691,7 +19787,7 @@ ok(canvas.getContext("2d#") === null, "canvas.getContext(\"2d#\") === null");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19717,7 +19813,7 @@ ok(canvas.getContext("2d\0") === null, "canvas.getContext(\"2d\\0\") === null");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -19743,7 +19839,7 @@ ok(canvas.getContext("2\uFF44") === null, "canvas.getContext(\"2\\uFF44\") === n
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -20763,7 +20859,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -20790,7 +20886,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -20818,7 +20914,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -20904,7 +21000,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -21012,7 +21108,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
} catch (e) { } catch (e) {
_thrown_outer = true; _thrown_outer = true;
} }
ok(!_thrown_outer, 'should not throw exception'); ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
} }
@ -21407,14 +21503,10 @@ function runTests() {
//test_2d_path_rect_zero_6(); // This test is bogus according to the spec; see bug 407107 //test_2d_path_rect_zero_6(); // This test is bogus according to the spec; see bug 407107
// These tests are bogus according to the spec: shadows should not be // The following tests are disabled due to pending changes in the spec:
// drawn if shadowBlur, shadowOffsetX, and shadowOffsetY are all zero, whic //
// they are in these tests
//test_2d_shadow_composite_3(); //test_2d_shadow_composite_3();
//test_2d_shadow_composite_4(); //test_2d_shadow_composite_4();
// Shadows should not be drawn if the operator is not source-over (the spec doesn't
// say this yet, but it should be changed). These tests assume shadows will
// be drawn with operators other than source-over:
//test_2d_shadow_composite_1(); //test_2d_shadow_composite_1();
//test_2d_shadow_composite_2(); //test_2d_shadow_composite_2();
try { try {

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

@ -48,6 +48,7 @@
#include "jsapi.h" #include "jsapi.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
#include "nsMathUtils.h" #include "nsMathUtils.h"
#include "mozilla/Preferences.h"
#include "nsFrameManager.h" #include "nsFrameManager.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
@ -722,3 +723,23 @@ nsHTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, gfxPattern::Gr
return mCurrentContext->Render(aContext, aFilter); return mCurrentContext->Render(aContext, aFilter);
} }
nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
nsresult NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult);
nsresult
NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
{
PRBool azure = PR_FALSE;
nsresult rv = Preferences::GetBool("gfx.canvas.azure.enabled", &azure);
if (azure) {
nsresult rv = NS_NewCanvasRenderingContext2DAzure(aResult);
// If Azure fails, fall back to a classic canvas.
if (NS_SUCCEEDED(rv)) {
return rv;
}
}
return NS_NewCanvasRenderingContext2DThebes(aResult);
}

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

@ -62,6 +62,8 @@ NS_INTERFACE_TABLE_HEAD(nsMathMLElement)
NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsMathMLElement) NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsMathMLElement)
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMNode) NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMNode)
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMElement) NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsIDOMElement)
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, nsILink)
NS_INTERFACE_TABLE_ENTRY(nsMathMLElement, Link)
NS_OFFSET_AND_INTERFACE_TABLE_END NS_OFFSET_AND_INTERFACE_TABLE_END
NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MathMLElement) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MathMLElement)
@ -77,6 +79,8 @@ nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
{ {
static const char kMathMLStyleSheetURI[] = "resource://gre-resources/mathml.css"; static const char kMathMLStyleSheetURI[] = "resource://gre-resources/mathml.css";
Link::ResetLinkState(false);
nsresult rv = nsMathMLElementBase::BindToTree(aDocument, aParent, nsresult rv = nsMathMLElementBase::BindToTree(aDocument, aParent,
aBindingParent, aBindingParent,
aCompileEventHandlers); aCompileEventHandlers);
@ -101,6 +105,16 @@ nsMathMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
return rv; return rv;
} }
void
nsMathMLElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
nsMathMLElementBase::UnbindFromTree(aDeep, aNullParent);
}
PRBool PRBool
nsMathMLElement::ParseAttribute(PRInt32 aNamespaceID, nsMathMLElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
@ -438,12 +452,27 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
} }
} }
nsresult
nsMathMLElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
nsresult rv = nsGenericElement::PreHandleEvent(aVisitor);
NS_ENSURE_SUCCESS(rv, rv);
return PreHandleEventForLinks(aVisitor);
}
nsresult
nsMathMLElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
{
return PostHandleEventForLinks(aVisitor);
}
NS_IMPL_ELEMENT_CLONE(nsMathMLElement) NS_IMPL_ELEMENT_CLONE(nsMathMLElement)
nsEventStates nsEventStates
nsMathMLElement::IntrinsicState() const nsMathMLElement::IntrinsicState() const
{ {
return nsMathMLElementBase::IntrinsicState() | return Link::LinkState() | nsMathMLElementBase::IntrinsicState() |
(mIncrementScriptLevel ? NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL : nsEventStates()); (mIncrementScriptLevel ? NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL : nsEventStates());
} }
@ -465,3 +494,185 @@ nsMathMLElement::SetIncrementScriptLevel(PRBool aIncrementScriptLevel,
UpdateState(true); UpdateState(true);
} }
PRBool
nsMathMLElement::IsFocusable(PRInt32 *aTabIndex, PRBool aWithMouse)
{
nsCOMPtr<nsIURI> uri;
if (IsLink(getter_AddRefs(uri))) {
if (aTabIndex) {
*aTabIndex = ((sTabFocusModel & eTabFocus_linksMask) == 0 ? -1 : 0);
}
return PR_TRUE;
}
if (aTabIndex) {
*aTabIndex = -1;
}
return PR_FALSE;
}
PRBool
nsMathMLElement::IsLink(nsIURI** aURI) const
{
// http://www.w3.org/TR/2010/REC-MathML3-20101021/chapter6.html#interf.link
// The REC says that the following elements should not be linking elements:
nsIAtom* tag = Tag();
if (tag == nsGkAtoms::mprescripts_ ||
tag == nsGkAtoms::none ||
tag == nsGkAtoms::malignmark_ ||
tag == nsGkAtoms::maligngroup_) {
*aURI = nsnull;
return PR_FALSE;
}
PRBool hasHref = PR_FALSE;
const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href,
kNameSpaceID_None);
if (href) {
// MathML href
// The REC says: "When user agents encounter MathML elements with both href
// and xlink:href attributes, the href attribute should take precedence."
hasHref = PR_TRUE;
} else {
// To be a clickable XLink for styling and interaction purposes, we require:
//
// xlink:href - must be set
// xlink:type - must be unset or set to "" or set to "simple"
// xlink:show - must be unset or set to "", "new" or "replace"
// xlink:actuate - must be unset or set to "" or "onRequest"
//
// For any other values, we're either not a *clickable* XLink, or the end
// result is poorly specified. Either way, we return PR_FALSE.
static nsIContent::AttrValuesArray sTypeVals[] =
{ &nsGkAtoms::_empty, &nsGkAtoms::simple, nsnull };
static nsIContent::AttrValuesArray sShowVals[] =
{ &nsGkAtoms::_empty, &nsGkAtoms::_new, &nsGkAtoms::replace, nsnull };
static nsIContent::AttrValuesArray sActuateVals[] =
{ &nsGkAtoms::_empty, &nsGkAtoms::onRequest, nsnull };
// Optimization: check for href first for early return
href = mAttrsAndChildren.GetAttr(nsGkAtoms::href,
kNameSpaceID_XLink);
if (href &&
FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::type,
sTypeVals, eCaseMatters) !=
nsIContent::ATTR_VALUE_NO_MATCH &&
FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
sShowVals, eCaseMatters) !=
nsIContent::ATTR_VALUE_NO_MATCH &&
FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::actuate,
sActuateVals, eCaseMatters) !=
nsIContent::ATTR_VALUE_NO_MATCH) {
hasHref = PR_TRUE;
}
}
if (hasHref) {
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
// Get absolute URI
nsAutoString hrefStr;
href->ToString(hrefStr);
nsContentUtils::NewURIWithDocumentCharset(aURI, hrefStr,
GetOwnerDoc(), baseURI);
// must promise out param is non-null if we return true
return !!*aURI;
}
*aURI = nsnull;
return PR_FALSE;
}
void
nsMathMLElement::GetLinkTarget(nsAString& aTarget)
{
const nsAttrValue* target = mAttrsAndChildren.GetAttr(nsGkAtoms::target,
kNameSpaceID_XLink);
if (target) {
target->ToString(aTarget);
}
if (aTarget.IsEmpty()) {
static nsIContent::AttrValuesArray sShowVals[] =
{ &nsGkAtoms::_new, &nsGkAtoms::replace, nsnull };
switch (FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
sShowVals, eCaseMatters)) {
case 0:
aTarget.AssignLiteral("_blank");
return;
case 1:
return;
}
nsIDocument* ownerDoc = GetOwnerDoc();
if (ownerDoc) {
ownerDoc->GetBaseTarget(aTarget);
}
}
}
nsLinkState
nsMathMLElement::GetLinkState() const
{
return Link::GetLinkState();
}
void
nsMathMLElement::RequestLinkStateUpdate()
{
UpdateLinkState(Link::LinkState());
}
already_AddRefed<nsIURI>
nsMathMLElement::GetHrefURI() const
{
nsCOMPtr<nsIURI> hrefURI;
return IsLink(getter_AddRefs(hrefURI)) ? hrefURI.forget() : nsnull;
}
nsresult
nsMathMLElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
nsresult rv = nsMathMLElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href &&
(aNameSpaceID == kNameSpaceID_None ||
aNameSpaceID == kNameSpaceID_XLink)) {
Link::ResetLinkState(!!aNotify);
}
return rv;
}
nsresult
nsMathMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
PRBool aNotify)
{
nsresult rv = nsMathMLElementBase::UnsetAttr(aNameSpaceID, aAttr, aNotify);
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
// is important here! The attribute is not unset until UnsetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aAttr == nsGkAtoms::href &&
(aNameSpaceID == kNameSpaceID_None ||
aNameSpaceID == kNameSpaceID_XLink)) {
Link::ResetLinkState(!!aNotify);
}
return rv;
}

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

@ -42,6 +42,8 @@
#include "nsMappedAttributeElement.h" #include "nsMappedAttributeElement.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsILink.h"
#include "Link.h"
class nsCSSValue; class nsCSSValue;
@ -50,12 +52,15 @@ typedef nsMappedAttributeElement nsMathMLElementBase;
/* /*
* The base class for MathML elements. * The base class for MathML elements.
*/ */
class nsMathMLElement : public nsMathMLElementBase class nsMathMLElement : public nsMathMLElementBase,
, public nsIDOMElement public nsIDOMElement,
public nsILink,
public mozilla::dom::Link
{ {
public: public:
nsMathMLElement(already_AddRefed<nsINodeInfo> aNodeInfo) nsMathMLElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsMathMLElementBase(aNodeInfo), mIncrementScriptLevel(PR_FALSE) : nsMathMLElementBase(aNodeInfo), Link(this),
mIncrementScriptLevel(PR_FALSE)
{} {}
// Implementation of nsISupports is inherited from nsMathMLElementBase // Implementation of nsISupports is inherited from nsMathMLElementBase
@ -69,6 +74,8 @@ public:
nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent, nsIContent* aBindingParent,
PRBool aCompileEventHandlers); PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual PRBool ParseAttribute(PRInt32 aNamespaceID, virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
@ -89,6 +96,8 @@ public:
static void MapMathMLAttributesInto(const nsMappedAttributes* aAttributes, static void MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
nsRuleData* aRuleData); nsRuleData* aRuleData);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
nsresult Clone(nsINodeInfo*, nsINode**) const; nsresult Clone(nsINodeInfo*, nsINode**) const;
virtual nsEventStates IntrinsicState() const; virtual nsEventStates IntrinsicState() const;
virtual PRBool IsNodeOfType(PRUint32 aFlags) const; virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
@ -100,6 +109,26 @@ public:
return mIncrementScriptLevel; return mIncrementScriptLevel;
} }
NS_IMETHOD LinkAdded() { return NS_OK; }
NS_IMETHOD LinkRemoved() { return NS_OK; }
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull,
PRBool aWithMouse = PR_FALSE);
virtual PRBool IsLink(nsIURI** aURI) const;
virtual void GetLinkTarget(nsAString& aTarget);
virtual nsLinkState GetLinkState() const;
virtual void RequestLinkStateUpdate();
virtual already_AddRefed<nsIURI> GetHrefURI() const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, PRBool aNotify)
{
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
}
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify);
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify);
virtual nsXPCClassInfo* GetClassInfo(); virtual nsXPCClassInfo* GetClassInfo();
private: private:
PRPackedBool mIncrementScriptLevel; PRPackedBool mIncrementScriptLevel;

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

@ -87,7 +87,7 @@
#ifdef MOZ_XUL #ifdef MOZ_XUL
#include "nsXULPrototypeCache.h" #include "nsXULPrototypeCache.h"
#endif #endif
#include "nsIDOMLoadListener.h" #include "nsIDOMEventListener.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
using namespace mozilla; using namespace mozilla;
@ -272,19 +272,13 @@ int nsXBLBindingRequest::gRefCnt = 0;
// nsXBLStreamListener, a helper class used for // nsXBLStreamListener, a helper class used for
// asynchronous parsing of URLs // asynchronous parsing of URLs
/* Header file */ /* Header file */
class nsXBLStreamListener : public nsIStreamListener, public nsIDOMLoadListener class nsXBLStreamListener : public nsIStreamListener, public nsIDOMEventListener
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIDOMEVENTLISTENER
NS_IMETHOD Load(nsIDOMEvent* aEvent);
NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent) { return NS_OK; }
NS_IMETHOD Unload(nsIDOMEvent* aEvent) { return NS_OK; }
NS_IMETHOD Abort(nsIDOMEvent* aEvent) { return NS_OK; }
NS_IMETHOD Error(nsIDOMEvent* aEvent) { return NS_OK; }
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
nsXBLStreamListener(nsXBLService* aXBLService, nsXBLStreamListener(nsXBLService* aXBLService,
nsIDocument* aBoundDocument, nsIDocument* aBoundDocument,
@ -307,7 +301,10 @@ private:
}; };
/* Implementation file */ /* Implementation file */
NS_IMPL_ISUPPORTS4(nsXBLStreamListener, nsIStreamListener, nsIRequestObserver, nsIDOMLoadListener, nsIDOMEventListener) NS_IMPL_ISUPPORTS3(nsXBLStreamListener,
nsIStreamListener,
nsIRequestObserver,
nsIDOMEventListener)
nsXBLStreamListener::nsXBLStreamListener(nsXBLService* aXBLService, nsXBLStreamListener::nsXBLStreamListener(nsXBLService* aXBLService,
nsIDocument* aBoundDocument, nsIDocument* aBoundDocument,
@ -401,7 +398,7 @@ nsXBLStreamListener::HasRequest(nsIURI* aURI, nsIContent* aElt)
} }
nsresult nsresult
nsXBLStreamListener::Load(nsIDOMEvent* aEvent) nsXBLStreamListener::HandleEvent(nsIDOMEvent* aEvent)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
PRUint32 i; PRUint32 i;
@ -481,7 +478,7 @@ nsXBLStreamListener::Load(nsIDOMEvent* aEvent)
} }
} }
target->RemoveEventListener(NS_LITERAL_STRING("load"), (nsIDOMLoadListener*)this, PR_FALSE); target->RemoveEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
return rv; return rv;
} }

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

@ -201,8 +201,7 @@ nsXBLWindowKeyHandler::~nsXBLWindowKeyHandler()
} }
} }
NS_IMPL_ISUPPORTS2(nsXBLWindowKeyHandler, NS_IMPL_ISUPPORTS1(nsXBLWindowKeyHandler,
nsIDOMKeyListener,
nsIDOMEventListener) nsIDOMEventListener)
static void static void
@ -393,28 +392,20 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventTy
return NS_OK; return NS_OK;
} }
nsresult nsXBLWindowKeyHandler::KeyUp(nsIDOMEvent* aEvent) NS_IMETHODIMP
nsXBLWindowKeyHandler::HandleEvent(nsIDOMEvent* aEvent)
{ {
nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent)); nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent));
NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG); NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG);
return WalkHandlers(keyEvent, nsGkAtoms::keyup);
}
nsresult nsXBLWindowKeyHandler::KeyDown(nsIDOMEvent* aEvent) nsAutoString eventType;
{ aEvent->GetType(eventType);
nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent)); nsCOMPtr<nsIAtom> eventTypeAtom = do_GetAtom(eventType);
NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG); NS_ENSURE_TRUE(eventTypeAtom, NS_ERROR_OUT_OF_MEMORY);
return WalkHandlers(keyEvent, nsGkAtoms::keydown);
}
nsresult nsXBLWindowKeyHandler::KeyPress(nsIDOMEvent* aEvent) return WalkHandlers(keyEvent, eventTypeAtom);
{
nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent));
NS_ENSURE_TRUE(keyEvent, NS_ERROR_INVALID_ARG);
return WalkHandlers(keyEvent, nsGkAtoms::keypress);
} }
// //
// EventMatched // EventMatched
// //

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

@ -41,7 +41,7 @@
#define nsXBLWindowKeyHandler_h__ #define nsXBLWindowKeyHandler_h__
#include "nsWeakPtr.h" #include "nsWeakPtr.h"
#include "nsIDOMKeyListener.h" #include "nsIDOMEventListener.h"
class nsIAtom; class nsIAtom;
class nsIDOMElement; class nsIDOMElement;
@ -52,23 +52,14 @@ class nsIXBLDocumentInfo;
class nsXBLSpecialDocInfo; class nsXBLSpecialDocInfo;
class nsXBLPrototypeHandler; class nsXBLPrototypeHandler;
class nsXBLWindowKeyHandler : public nsIDOMKeyListener class nsXBLWindowKeyHandler : public nsIDOMEventListener
{ {
public: public:
nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventTarget* aTarget); nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventTarget* aTarget);
virtual ~nsXBLWindowKeyHandler(); virtual ~nsXBLWindowKeyHandler();
// nsIDOMetc.
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
// release globals // release globals
static NS_HIDDEN_(void) ShutDown(); static NS_HIDDEN_(void) ShutDown();

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

@ -44,8 +44,6 @@
#include "nsEscape.h" #include "nsEscape.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsIPrefService.h"
#include "nsIPrefLocalizedString.h"
#include "nsIPlatformCharset.h" #include "nsIPlatformCharset.h"
#include "nsILocalFile.h" #include "nsILocalFile.h"
@ -55,6 +53,9 @@
#include "nsIURIFixup.h" #include "nsIURIFixup.h"
#include "nsDefaultURIFixup.h" #include "nsDefaultURIFixup.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
/* Implementation file */ /* Implementation file */
NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup) NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup)
@ -62,9 +63,6 @@ NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup)
nsDefaultURIFixup::nsDefaultURIFixup() nsDefaultURIFixup::nsDefaultURIFixup()
{ {
/* member initializers and constructor code */ /* member initializers and constructor code */
// Try and get the pref service
mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
} }
@ -134,13 +132,10 @@ nsDefaultURIFixup::CreateExposableURI(nsIURI *aURI, nsIURI **aReturn)
} }
// hide user:pass unless overridden by pref // hide user:pass unless overridden by pref
PRBool hideUserPass = PR_TRUE; if (Preferences::GetBool("browser.fixup.hide_user_pass", PR_TRUE))
if (mPrefBranch)
{ {
mPrefBranch->GetBoolPref("browser.fixup.hide_user_pass", &hideUserPass);
}
if (hideUserPass)
uri->SetUserPass(EmptyCString()); uri->SetUserPass(EmptyCString());
}
// return the fixed-up URI // return the fixed-up URI
*aReturn = uri; *aReturn = uri;
@ -274,10 +269,8 @@ nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, PRUint32 aFixupF
// Test whether keywords need to be fixed up // Test whether keywords need to be fixed up
PRBool fixupKeywords = PR_FALSE; PRBool fixupKeywords = PR_FALSE;
if (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) { if (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) {
if (mPrefBranch) nsresult rv = Preferences::GetBool("keyword.enabled", &fixupKeywords);
{ NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(mPrefBranch->GetBoolPref("keyword.enabled", &fixupKeywords), NS_ERROR_FAILURE);
}
if (fixupKeywords) if (fixupKeywords)
{ {
KeywordURIFixup(uriString, aURI); KeywordURIFixup(uriString, aURI);
@ -358,7 +351,7 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
nsIURI **aURI) nsIURI **aURI)
{ {
*aURI = nsnull; *aURI = nsnull;
NS_ENSURE_STATE(mPrefBranch); NS_ENSURE_STATE(Preferences::GetRootBranch());
// Strip leading "?" and leading/trailing spaces from aKeyword // Strip leading "?" and leading/trailing spaces from aKeyword
nsCAutoString keyword(aKeyword); nsCAutoString keyword(aKeyword);
@ -367,19 +360,10 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
} }
keyword.Trim(" "); keyword.Trim(" ");
nsXPIDLCString url; nsAdoptingCString url = Preferences::GetLocalizedCString("keyword.URL");
nsCOMPtr<nsIPrefLocalizedString> keywordURL; if (!url) {
mPrefBranch->GetComplexValue("keyword.URL",
NS_GET_IID(nsIPrefLocalizedString),
getter_AddRefs(keywordURL));
if (keywordURL) {
nsXPIDLString wurl;
keywordURL->GetData(getter_Copies(wurl));
CopyUTF16toUTF8(wurl, url);
} else {
// Fall back to a non-localized pref, for backwards compat // Fall back to a non-localized pref, for backwards compat
mPrefBranch->GetCharPref("keyword.URL", getter_Copies(url)); url = Preferences::GetCString("keyword.URL");
} }
// If the pref is set and non-empty, use it. // If the pref is set and non-empty, use it.
@ -441,13 +425,11 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
PRBool nsDefaultURIFixup::MakeAlternateURI(nsIURI *aURI) PRBool nsDefaultURIFixup::MakeAlternateURI(nsIURI *aURI)
{ {
if (!mPrefBranch) if (!Preferences::GetRootBranch())
{ {
return PR_FALSE; return PR_FALSE;
} }
PRBool makeAlternate = PR_TRUE; if (!Preferences::GetBool("browser.fixup.alternate.enabled", PR_TRUE))
mPrefBranch->GetBoolPref("browser.fixup.alternate.enabled", &makeAlternate);
if (!makeAlternate)
{ {
return PR_FALSE; return PR_FALSE;
} }
@ -489,17 +471,17 @@ PRBool nsDefaultURIFixup::MakeAlternateURI(nsIURI *aURI)
// are www. & .com but they could be any other value, e.g. www. & .org // are www. & .com but they could be any other value, e.g. www. & .org
nsCAutoString prefix("www."); nsCAutoString prefix("www.");
nsXPIDLCString prefPrefix; nsAdoptingCString prefPrefix =
rv = mPrefBranch->GetCharPref("browser.fixup.alternate.prefix", getter_Copies(prefPrefix)); Preferences::GetCString("browser.fixup.alternate.prefix");
if (NS_SUCCEEDED(rv)) if (prefPrefix)
{ {
prefix.Assign(prefPrefix); prefix.Assign(prefPrefix);
} }
nsCAutoString suffix(".com"); nsCAutoString suffix(".com");
nsXPIDLCString prefSuffix; nsAdoptingCString prefSuffix =
rv = mPrefBranch->GetCharPref("browser.fixup.alternate.suffix", getter_Copies(prefSuffix)); Preferences::GetCString("browser.fixup.alternate.suffix");
if (NS_SUCCEEDED(rv)) if (prefSuffix)
{ {
suffix.Assign(prefSuffix); suffix.Assign(prefSuffix);
} }

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

@ -40,7 +40,6 @@
#ifndef NSDEFAULTURIFIXUP_H #ifndef NSDEFAULTURIFIXUP_H
#define NSDEFAULTURIFIXUP_H #define NSDEFAULTURIFIXUP_H
#include "nsIPrefBranch.h"
#include "nsIURIFixup.h" #include "nsIURIFixup.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -71,7 +70,6 @@ private:
const char * GetFileSystemCharset(); const char * GetFileSystemCharset();
const char * GetCharsetForUrlBar(); const char * GetCharsetForUrlBar();
nsCOMPtr<nsIPrefBranch> mPrefBranch;
nsCString mFsCharset; nsCString mFsCharset;
}; };

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

@ -95,9 +95,6 @@
#include "nsXPCOMCID.h" #include "nsXPCOMCID.h"
#include "nsISeekableStream.h" #include "nsISeekableStream.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranch2.h"
#include "nsIWritablePropertyBag2.h" #include "nsIWritablePropertyBag2.h"
#include "nsIAppShell.h" #include "nsIAppShell.h"
#include "nsWidgetsCID.h" #include "nsWidgetsCID.h"
@ -111,6 +108,7 @@
#include "nsJSON.h" #include "nsJSON.h"
#include "IHistory.h" #include "IHistory.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/Preferences.h"
// we want to explore making the document own the load group // we want to explore making the document own the load group
// so we can associate the document URI with the load group. // so we can associate the document URI with the load group.
@ -307,21 +305,14 @@ FavorPerformanceHint(PRBool perfOverStarvation, PRUint32 starvationDelay)
static PRBool static PRBool
PingsEnabled(PRInt32 *maxPerLink, PRBool *requireSameHost) PingsEnabled(PRInt32 *maxPerLink, PRBool *requireSameHost)
{ {
PRBool allow = PR_FALSE; PRBool allow = Preferences::GetBool(PREF_PINGS_ENABLED, PR_FALSE);
*maxPerLink = 1; *maxPerLink = 1;
*requireSameHost = PR_TRUE; *requireSameHost = PR_TRUE;
nsCOMPtr<nsIPrefBranch> prefs = if (allow) {
do_GetService(NS_PREFSERVICE_CONTRACTID); Preferences::GetInt(PREF_PINGS_MAX_PER_LINK, maxPerLink);
if (prefs) { Preferences::GetBool(PREF_PINGS_REQUIRE_SAME_HOST, requireSameHost);
PRBool val;
if (NS_SUCCEEDED(prefs->GetBoolPref(PREF_PINGS_ENABLED, &val)))
allow = val;
if (allow) {
prefs->GetIntPref(PREF_PINGS_MAX_PER_LINK, maxPerLink);
prefs->GetBoolPref(PREF_PINGS_REQUIRE_SAME_HOST, requireSameHost);
}
} }
return allow; return allow;
@ -739,6 +730,7 @@ nsDocShell::nsDocShell():
mPreviousTransIndex(-1), mPreviousTransIndex(-1),
mLoadType(0), mLoadType(0),
mLoadedTransIndex(-1), mLoadedTransIndex(-1),
mCreated(PR_FALSE),
mAllowSubframes(PR_TRUE), mAllowSubframes(PR_TRUE),
mAllowPlugins(PR_TRUE), mAllowPlugins(PR_TRUE),
mAllowJavascript(PR_TRUE), mAllowJavascript(PR_TRUE),
@ -1600,9 +1592,7 @@ nsDocShell::MaybeInitTiming()
return NS_OK; return NS_OK;
} }
PRBool enabled; if (Preferences::GetBool("dom.enable_performance", PR_FALSE)) {
nsresult rv = mPrefs->GetBoolPref("dom.enable_performance", &enabled);
if (NS_SUCCEEDED(rv) && enabled) {
mTiming = new nsDOMNavigationTiming(); mTiming = new nsDOMNavigationTiming();
mTiming->NotifyNavigationStart(); mTiming->NotifyNavigationStart();
} }
@ -2201,11 +2191,8 @@ nsDocShell::SetUseErrorPages(PRBool aUseErrorPages)
{ {
// If mUseErrorPages is set explicitly, stop observing the pref. // If mUseErrorPages is set explicitly, stop observing the pref.
if (mObserveErrorPages) { if (mObserveErrorPages) {
nsCOMPtr<nsIPrefBranch2> prefs(do_QueryInterface(mPrefs)); Preferences::RemoveObserver(this, "browser.xul.error_pages.enabled");
if (prefs) { mObserveErrorPages = PR_FALSE;
prefs->RemoveObserver("browser.xul.error_pages.enabled", this);
mObserveErrorPages = PR_FALSE;
}
} }
mUseErrorPages = aUseErrorPages; mUseErrorPages = aUseErrorPages;
return NS_OK; return NS_OK;
@ -3919,17 +3906,15 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
if (isStsHost) if (isStsHost)
cssClass.AssignLiteral("badStsCert"); cssClass.AssignLiteral("badStsCert");
PRBool expert = PR_FALSE; if (Preferences::GetBool(
mPrefs->GetBoolPref("browser.xul.error_pages.expert_bad_cert", "browser.xul.error_pages.expert_bad_cert", PR_FALSE)) {
&expert);
if (expert) {
cssClass.AssignLiteral("expertBadCert"); cssClass.AssignLiteral("expertBadCert");
} }
// See if an alternate cert error page is registered // See if an alternate cert error page is registered
nsXPIDLCString alternateErrorPage; nsAdoptingCString alternateErrorPage =
mPrefs->GetCharPref("security.alternate_certificate_error_page", Preferences::GetCString(
getter_Copies(alternateErrorPage)); "security.alternate_certificate_error_page");
if (alternateErrorPage) if (alternateErrorPage)
errorPage.Assign(alternateErrorPage); errorPage.Assign(alternateErrorPage);
} else { } else {
@ -3944,9 +3929,8 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
// Malware and phishing detectors may want to use an alternate error // Malware and phishing detectors may want to use an alternate error
// page, but if the pref's not set, we'll fall back on the standard page // page, but if the pref's not set, we'll fall back on the standard page
nsXPIDLCString alternateErrorPage; nsAdoptingCString alternateErrorPage =
mPrefs->GetCharPref("urlclassifier.alternate_error_page", Preferences::GetCString("urlclassifier.alternate_error_page");
getter_Copies(alternateErrorPage));
if (alternateErrorPage) if (alternateErrorPage)
errorPage.Assign(alternateErrorPage); errorPage.Assign(alternateErrorPage);
@ -4492,7 +4476,7 @@ nsDocShell::InitWindow(nativeWindow parentNativeWindow,
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::Create() nsDocShell::Create()
{ {
if (mPrefs) { if (mCreated) {
// We've already been created // We've already been created
return NS_OK; return NS_OK;
} }
@ -4500,34 +4484,24 @@ nsDocShell::Create()
NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome, NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,
"Unexpected item type in docshell"); "Unexpected item type in docshell");
nsresult rv = NS_ERROR_FAILURE; NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
mPrefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); mCreated = PR_TRUE;
NS_ENSURE_SUCCESS(rv, rv);
PRBool tmpbool; mAllowSubframes =
Preferences::GetBool("browser.frames.enabled", mAllowSubframes);
rv = mPrefs->GetBoolPref("browser.frames.enabled", &tmpbool);
if (NS_SUCCEEDED(rv))
mAllowSubframes = tmpbool;
if (gValidateOrigin == (PRBool)0xffffffff) { if (gValidateOrigin == (PRBool)0xffffffff) {
// Check pref to see if we should prevent frameset spoofing // Check pref to see if we should prevent frameset spoofing
rv = mPrefs->GetBoolPref("browser.frame.validate_origin", &tmpbool); gValidateOrigin =
if (NS_SUCCEEDED(rv)) { Preferences::GetBool("browser.frame.validate_origin", PR_TRUE);
gValidateOrigin = tmpbool;
} else {
gValidateOrigin = PR_TRUE;
}
} }
// Should we use XUL error pages instead of alerts if possible? // Should we use XUL error pages instead of alerts if possible?
rv = mPrefs->GetBoolPref("browser.xul.error_pages.enabled", &tmpbool); mUseErrorPages =
if (NS_SUCCEEDED(rv)) Preferences::GetBool("browser.xul.error_pages.enabled", mUseErrorPages);
mUseErrorPages = tmpbool;
nsCOMPtr<nsIPrefBranch2> prefs(do_QueryInterface(mPrefs, &rv)); if (mObserveErrorPages) {
if (NS_SUCCEEDED(rv) && mObserveErrorPages) { Preferences::AddStrongObserver(this, "browser.xul.error_pages.enabled");
prefs->AddObserver("browser.xul.error_pages.enabled", this, PR_FALSE);
} }
nsCOMPtr<nsIObserverService> serv = do_GetService(NS_OBSERVERSERVICE_CONTRACTID); nsCOMPtr<nsIObserverService> serv = do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
@ -4560,11 +4534,8 @@ nsDocShell::Destroy()
// Remove our pref observers // Remove our pref observers
if (mObserveErrorPages) { if (mObserveErrorPages) {
nsCOMPtr<nsIPrefBranch2> prefs(do_QueryInterface(mPrefs)); Preferences::RemoveObserver(this, "browser.xul.error_pages.enabled");
if (prefs) { mObserveErrorPages = PR_FALSE;
prefs->RemoveObserver("browser.xul.error_pages.enabled", this);
mObserveErrorPages = PR_FALSE;
}
} }
// Make sure to blow away our mLoadingURI just in case. No loads // Make sure to blow away our mLoadingURI just in case. No loads
@ -5971,9 +5942,7 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest,
if ((aStateFlags & STATE_RESTORING) == 0) { if ((aStateFlags & STATE_RESTORING) == 0) {
// Show the progress cursor if the pref is set // Show the progress cursor if the pref is set
PRBool tmpBool = PR_FALSE; if (Preferences::GetBool("ui.use_activity_cursor", PR_FALSE)) {
if (NS_SUCCEEDED(mPrefs->GetBoolPref("ui.use_activity_cursor", &tmpBool))
&& tmpBool) {
nsCOMPtr<nsIWidget> mainWidget; nsCOMPtr<nsIWidget> mainWidget;
GetMainWidget(getter_AddRefs(mainWidget)); GetMainWidget(getter_AddRefs(mainWidget));
if (mainWidget) { if (mainWidget) {
@ -5991,9 +5960,7 @@ nsDocShell::OnStateChange(nsIWebProgress * aProgress, nsIRequest * aRequest,
mBusyFlags = BUSY_FLAGS_NONE; mBusyFlags = BUSY_FLAGS_NONE;
// Hide the progress cursor if the pref is set // Hide the progress cursor if the pref is set
PRBool tmpBool = PR_FALSE; if (Preferences::GetBool("ui.use_activity_cursor", PR_FALSE)) {
if (NS_SUCCEEDED(mPrefs->GetBoolPref("ui.use_activity_cursor", &tmpBool))
&& tmpBool) {
nsCOMPtr<nsIWidget> mainWidget; nsCOMPtr<nsIWidget> mainWidget;
GetMainWidget(getter_AddRefs(mainWidget)); GetMainWidget(getter_AddRefs(mainWidget));
if (mainWidget) { if (mainWidget) {
@ -6240,12 +6207,8 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
// First try keyword fixup // First try keyword fixup
// //
if (aStatus == NS_ERROR_UNKNOWN_HOST && mAllowKeywordFixup) { if (aStatus == NS_ERROR_UNKNOWN_HOST && mAllowKeywordFixup) {
PRBool keywordsEnabled = PR_FALSE; PRBool keywordsEnabled =
Preferences::GetBool("keyword.enabled", PR_FALSE);
if (mPrefs &&
NS_FAILED(mPrefs->GetBoolPref("keyword.enabled",
&keywordsEnabled)))
keywordsEnabled = PR_FALSE;
nsCAutoString host; nsCAutoString host;
url->GetHost(host); url->GetHost(host);
@ -6700,9 +6663,9 @@ nsDocShell::CanSavePresentation(PRUint32 aLoadType,
// Don't cache the content viewer if we're in a subframe and the subframe // Don't cache the content viewer if we're in a subframe and the subframe
// pref is disabled. // pref is disabled.
PRBool cacheFrames = PR_FALSE; PRBool cacheFrames =
mPrefs->GetBoolPref("browser.sessionhistory.cache_subframes", Preferences::GetBool("browser.sessionhistory.cache_subframes",
&cacheFrames); PR_FALSE);
if (!cacheFrames) { if (!cacheFrames) {
nsCOMPtr<nsIDocShellTreeItem> root; nsCOMPtr<nsIDocShellTreeItem> root;
GetSameTypeParent(getter_AddRefs(root)); GetSameTypeParent(getter_AddRefs(root));
@ -9212,22 +9175,16 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
case LOAD_NORMAL: case LOAD_NORMAL:
case LOAD_LINK: case LOAD_LINK:
// Set cache checking flags // Set cache checking flags
PRInt32 prefSetting; switch (Preferences::GetInt("browser.cache.check_doc_frequency", -1)) {
if (NS_SUCCEEDED case 0:
(mPrefs-> loadFlags |= nsIRequest::VALIDATE_ONCE_PER_SESSION;
GetIntPref("browser.cache.check_doc_frequency", break;
&prefSetting))) { case 1:
switch (prefSetting) { loadFlags |= nsIRequest::VALIDATE_ALWAYS;
case 0: break;
loadFlags |= nsIRequest::VALIDATE_ONCE_PER_SESSION; case 2:
break; loadFlags |= nsIRequest::VALIDATE_NEVER;
case 1: break;
loadFlags |= nsIRequest::VALIDATE_ALWAYS;
break;
case 2:
loadFlags |= nsIRequest::VALIDATE_NEVER;
break;
}
} }
break; break;
} }
@ -9700,11 +9657,8 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
// Check that the state object isn't too long. // Check that the state object isn't too long.
// Default max length: 640k bytes. // Default max length: 640k bytes.
PRInt32 maxStateObjSize = 0xA0000; PRInt32 maxStateObjSize =
if (mPrefs) { Preferences::GetInt("browser.history.maxStateObjectSize", 0xA0000);
mPrefs->GetIntPref("browser.history.maxStateObjectSize",
&maxStateObjSize);
}
if (maxStateObjSize < 0) { if (maxStateObjSize < 0) {
maxStateObjSize = 0; maxStateObjSize = 0;
} }
@ -11206,11 +11160,8 @@ nsDocShell::Observe(nsISupports *aSubject, const char *aTopic,
!nsCRT::strcmp(aData, !nsCRT::strcmp(aData,
NS_LITERAL_STRING("browser.xul.error_pages.enabled").get())) { NS_LITERAL_STRING("browser.xul.error_pages.enabled").get())) {
nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject, &rv));
NS_ENSURE_SUCCESS(rv, rv);
PRBool tmpbool; PRBool tmpbool;
rv = prefs->GetBoolPref("browser.xul.error_pages.enabled", &tmpbool); rv = Preferences::GetBool("browser.xul.error_pages.enabled", &tmpbool);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
mUseErrorPages = tmpbool; mUseErrorPages = tmpbool;

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

@ -44,7 +44,6 @@
#include "nsIDOMNode.h" #include "nsIDOMNode.h"
#include "nsIDOMNodeList.h" #include "nsIDOMNodeList.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIPrefBranch.h"
#include "nsInterfaceHashtable.h" #include "nsInterfaceHashtable.h"
#include "nsIScriptContext.h" #include "nsIScriptContext.h"
#include "nsITimer.h" #include "nsITimer.h"
@ -718,7 +717,6 @@ protected:
nsCOMPtr<nsIContentViewer> mContentViewer; nsCOMPtr<nsIContentViewer> mContentViewer;
nsCOMPtr<nsIDocumentCharsetInfo> mDocumentCharsetInfo; nsCOMPtr<nsIDocumentCharsetInfo> mDocumentCharsetInfo;
nsCOMPtr<nsIWidget> mParentWidget; nsCOMPtr<nsIWidget> mParentWidget;
nsCOMPtr<nsIPrefBranch> mPrefs;
// mCurrentURI should be marked immutable on set if possible. // mCurrentURI should be marked immutable on set if possible.
nsCOMPtr<nsIURI> mCurrentURI; nsCOMPtr<nsIURI> mCurrentURI;
@ -791,6 +789,7 @@ protected:
PRInt32 mPreviousTransIndex; PRInt32 mPreviousTransIndex;
PRInt32 mLoadedTransIndex; PRInt32 mLoadedTransIndex;
PRPackedBool mCreated;
PRPackedBool mAllowSubframes; PRPackedBool mAllowSubframes;
PRPackedBool mAllowPlugins; PRPackedBool mAllowPlugins;
PRPackedBool mAllowJavascript; PRPackedBool mAllowJavascript;

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

@ -94,6 +94,7 @@ Initialize()
static void static void
Shutdown() Shutdown()
{ {
nsSHistory::Shutdown();
nsSHEntry::Shutdown(); nsSHEntry::Shutdown();
gInitialized = PR_FALSE; gInitialized = PR_FALSE;
} }

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

@ -43,6 +43,7 @@
// Helper Classes // Helper Classes
#include "nsXPIDLString.h" #include "nsXPIDLString.h"
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "mozilla/Preferences.h"
// Interfaces Needed // Interfaces Needed
#include "nsILayoutHistoryState.h" #include "nsILayoutHistoryState.h"
@ -53,7 +54,6 @@
#include "nsIDocShellTreeNode.h" #include "nsIDocShellTreeNode.h"
#include "nsIDocShellLoadInfo.h" #include "nsIDocShellLoadInfo.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIPrefService.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsICacheService.h" #include "nsICacheService.h"
@ -68,10 +68,19 @@
#include "nspr.h" #include "nspr.h"
#include <math.h> // for log() #include <math.h> // for log()
using namespace mozilla;
#define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries" #define PREF_SHISTORY_SIZE "browser.sessionhistory.max_entries"
#define PREF_SHISTORY_MAX_TOTAL_VIEWERS "browser.sessionhistory.max_total_viewers" #define PREF_SHISTORY_MAX_TOTAL_VIEWERS "browser.sessionhistory.max_total_viewers"
#define PREF_SHISTORY_OPTIMIZE_EVICTION "browser.sessionhistory.optimize_eviction" #define PREF_SHISTORY_OPTIMIZE_EVICTION "browser.sessionhistory.optimize_eviction"
static const char* kObservedPrefs[] = {
PREF_SHISTORY_SIZE,
PREF_SHISTORY_MAX_TOTAL_VIEWERS,
PREF_SHISTORY_OPTIMIZE_EVICTION,
nsnull
};
static PRInt32 gHistoryMaxSize = 50; static PRInt32 gHistoryMaxSize = 50;
// Max viewers allowed per SHistory objects // Max viewers allowed per SHistory objects
static const PRInt32 gHistoryMaxViewers = 3; static const PRInt32 gHistoryMaxViewers = 3;
@ -115,6 +124,8 @@ protected:
~nsSHistoryObserver() {} ~nsSHistoryObserver() {}
}; };
static nsSHistoryObserver* gObserver = nsnull;
NS_IMPL_ISUPPORTS1(nsSHistoryObserver, nsIObserver) NS_IMPL_ISUPPORTS1(nsSHistoryObserver, nsIObserver)
NS_IMETHODIMP NS_IMETHODIMP
@ -122,11 +133,8 @@ nsSHistoryObserver::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData) const PRUnichar *aData)
{ {
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
nsCOMPtr<nsIPrefBranch> prefs = do_QueryInterface(aSubject); nsSHistory::UpdatePrefs();
if (prefs) { nsSHistory::EvictGlobalContentViewer();
nsSHistory::UpdatePrefs(prefs);
nsSHistory::EvictGlobalContentViewer();
}
} else if (!strcmp(aTopic, NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID) || } else if (!strcmp(aTopic, NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID) ||
!strcmp(aTopic, "memory-pressure")) { !strcmp(aTopic, "memory-pressure")) {
nsSHistory::EvictAllContentViewersGlobally(); nsSHistory::EvictAllContentViewersGlobally();
@ -227,13 +235,12 @@ nsSHistory::CalcMaxTotalViewers()
// static // static
void void
nsSHistory::UpdatePrefs(nsIPrefBranch *aPrefBranch) nsSHistory::UpdatePrefs()
{ {
aPrefBranch->GetIntPref(PREF_SHISTORY_SIZE, &gHistoryMaxSize); Preferences::GetInt(PREF_SHISTORY_SIZE, &gHistoryMaxSize);
aPrefBranch->GetIntPref(PREF_SHISTORY_MAX_TOTAL_VIEWERS, Preferences::GetInt(PREF_SHISTORY_MAX_TOTAL_VIEWERS,
&sHistoryMaxTotalViewers); &sHistoryMaxTotalViewers);
aPrefBranch->GetBoolPref(PREF_SHISTORY_OPTIMIZE_EVICTION, Preferences::GetBool(PREF_SHISTORY_OPTIMIZE_EVICTION, &gOptimizeEviction);
&gOptimizeEviction);
// If the pref is negative, that means we calculate how many viewers // If the pref is negative, that means we calculate how many viewers
// we think we should cache, based on total memory // we think we should cache, based on total memory
if (sHistoryMaxTotalViewers < 0) { if (sHistoryMaxTotalViewers < 0) {
@ -245,52 +252,33 @@ nsSHistory::UpdatePrefs(nsIPrefBranch *aPrefBranch)
nsresult nsresult
nsSHistory::Startup() nsSHistory::Startup()
{ {
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); UpdatePrefs();
if (prefs) {
nsCOMPtr<nsIPrefBranch> sesHBranch;
prefs->GetBranch(nsnull, getter_AddRefs(sesHBranch));
if (sesHBranch) {
UpdatePrefs(sesHBranch);
}
// The goal of this is to unbreak users who have inadvertently set their // The goal of this is to unbreak users who have inadvertently set their
// session history size to less than the default value. // session history size to less than the default value.
PRInt32 defaultHistoryMaxSize = 50; PRInt32 defaultHistoryMaxSize =
nsCOMPtr<nsIPrefBranch> defaultBranch; Preferences::GetDefaultInt(PREF_SHISTORY_SIZE, 50);
prefs->GetDefaultBranch(nsnull, getter_AddRefs(defaultBranch)); if (gHistoryMaxSize < defaultHistoryMaxSize) {
if (defaultBranch) { gHistoryMaxSize = defaultHistoryMaxSize;
defaultBranch->GetIntPref(PREF_SHISTORY_SIZE, &defaultHistoryMaxSize); }
}
// Allow the user to override the max total number of cached viewers,
// but keep the per SHistory cached viewer limit constant
if (!gObserver) {
gObserver = new nsSHistoryObserver();
NS_ADDREF(gObserver);
Preferences::AddStrongObservers(gObserver, kObservedPrefs);
if (gHistoryMaxSize < defaultHistoryMaxSize) { nsCOMPtr<nsIObserverService> obsSvc =
gHistoryMaxSize = defaultHistoryMaxSize; mozilla::services::GetObserverService();
} if (obsSvc) {
// Observe empty-cache notifications so tahat clearing the disk/memory
// Allow the user to override the max total number of cached viewers, // cache will also evict all content viewers.
// but keep the per SHistory cached viewer limit constant obsSvc->AddObserver(gObserver,
nsCOMPtr<nsIPrefBranch2> branch = do_QueryInterface(sesHBranch); NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID, PR_FALSE);
if (branch) {
nsSHistoryObserver* obs = new nsSHistoryObserver();
if (!obs) {
return NS_ERROR_OUT_OF_MEMORY;
}
branch->AddObserver(PREF_SHISTORY_SIZE, obs, PR_FALSE);
branch->AddObserver(PREF_SHISTORY_MAX_TOTAL_VIEWERS,
obs, PR_FALSE);
branch->AddObserver(PREF_SHISTORY_OPTIMIZE_EVICTION,
obs, PR_FALSE);
nsCOMPtr<nsIObserverService> obsSvc = // Same for memory-pressure notifications
mozilla::services::GetObserverService(); obsSvc->AddObserver(gObserver, "memory-pressure", PR_FALSE);
if (obsSvc) {
// Observe empty-cache notifications so tahat clearing the disk/memory
// cache will also evict all content viewers.
obsSvc->AddObserver(obs,
NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID, PR_FALSE);
// Same for memory-pressure notifications
obsSvc->AddObserver(obs, "memory-pressure", PR_FALSE);
}
} }
} }
@ -299,6 +287,22 @@ nsSHistory::Startup()
return NS_OK; return NS_OK;
} }
// static
void
nsSHistory::Shutdown()
{
if (gObserver) {
Preferences::RemoveObservers(gObserver, kObservedPrefs);
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->RemoveObserver(gObserver, NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID);
obsSvc->RemoveObserver(gObserver, "memory-pressure");
}
NS_RELEASE(gObserver);
}
}
/* Add an entry to the History list at mIndex and /* Add an entry to the History list at mIndex and
* increment the index to point to the new entry * increment the index to point to the new entry
*/ */

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

@ -53,7 +53,6 @@
#include "nsISHistoryListener.h" #include "nsISHistoryListener.h"
#include "nsIHistoryEntry.h" #include "nsIHistoryEntry.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsIPrefBranch2.h"
// Needed to maintain global list of all SHistory objects // Needed to maintain global list of all SHistory objects
#include "prclist.h" #include "prclist.h"
@ -76,7 +75,8 @@ public:
// One time initialization method called upon docshell module construction // One time initialization method called upon docshell module construction
static nsresult Startup(); static nsresult Startup();
static void UpdatePrefs(nsIPrefBranch *aPrefBranch); static void Shutdown();
static void UpdatePrefs();
// Max number of total cached content viewers. If the pref // Max number of total cached content viewers. If the pref
// browser.sessionhistory.max_total_viewers is negative, then // browser.sessionhistory.max_total_viewers is negative, then

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

@ -142,13 +142,12 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
} }
} }
} }
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), cb.DescribeRefCountedNode(tmp->mRefCnt.get(),
sizeof(nsJSScriptTimeoutHandler), foo.get()); sizeof(nsJSScriptTimeoutHandler), foo.get());
} }
else { else {
cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsJSScriptTimeoutHandler,
sizeof(nsJSScriptTimeoutHandler), tmp->mRefCnt.get())
"nsJSScriptTimeoutHandler");
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)

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

@ -168,11 +168,6 @@ nsHTMLEditor::~nsHTMLEditor()
// free any default style propItems // free any default style propItems
RemoveAllDefaultProperties(); RemoveAllDefaultProperties();
while (mStyleSheetURLs.Length())
{
RemoveOverrideStyleSheet(mStyleSheetURLs[0]);
}
if (mLinkHandler && mDocWeak) if (mLinkHandler && mDocWeak)
{ {
nsCOMPtr<nsIPresShell> ps = GetPresShell(); nsCOMPtr<nsIPresShell> ps = GetPresShell();
@ -359,6 +354,11 @@ nsHTMLEditor::PreDestroy(PRBool aDestroyingFrames)
document->RemoveMutationObserver(this); document->RemoveMutationObserver(this);
} }
while (mStyleSheetURLs.Length())
{
RemoveOverrideStyleSheet(mStyleSheetURLs[0]);
}
return nsPlaintextEditor::PreDestroy(aDestroyingFrames); return nsPlaintextEditor::PreDestroy(aDestroyingFrames);
} }

668
gfx/2d/2D.h Normal file
Просмотреть файл

@ -0,0 +1,668 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _MOZILLA_GFX_2D_H
#define _MOZILLA_GFX_2D_H
#include "Point.h"
#include "Rect.h"
#include "Matrix.h"
// This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
// outparams using the &-operator. But it will have to do as there's no easy
// solution.
#include "mozilla/RefPtr.h"
struct _cairo_surface;
typedef _cairo_surface cairo_surface_t;
struct ID3D10Device1;
struct ID3D10Texture2D;
namespace mozilla {
namespace gfx {
class SourceSurface;
class DataSourceSurface;
class DrawTarget;
struct NativeSurface {
NativeSurfaceType mType;
SurfaceFormat mFormat;
void *mSurface;
};
struct NativeFont {
NativeFontType mType;
void *mFont;
};
/*
* This structure is used to send draw options that are universal to all drawing
* operations. It consists of the following:
*
* mAlpha - Alpha value by which the mask generated by this operation is
* multiplied.
* mCompositionOp - The operator that indicates how the source and destination
* patterns are blended.
* mAntiAliasMode - The AntiAlias mode used for this drawing operation.
* mSnapping - Whether this operation is snapped to pixel boundaries.
*/
struct DrawOptions {
DrawOptions(Float aAlpha = 1.0f,
CompositionOp aCompositionOp = OP_OVER,
AntialiasMode aAntialiasMode = AA_GRAY,
Snapping aSnapping = SNAP_NONE)
: mAlpha(aAlpha)
, mCompositionOp(aCompositionOp)
, mAntialiasMode(aAntialiasMode)
, mSnapping(aSnapping)
{}
Float mAlpha;
CompositionOp mCompositionOp : 8;
AntialiasMode mAntialiasMode : 2;
Snapping mSnapping : 1;
};
/*
* This structure is used to send stroke options that are used in stroking
* operations. It consists of the following:
*
* mLineWidth - Width of the stroke in userspace.
* mLineJoin - Join style used for joining lines.
* mLineCap - Cap style used for capping lines.
* mMiterLimit - Miter limit in units of linewidth
*/
struct StrokeOptions {
StrokeOptions(Float aLineWidth = 1.0f,
JoinStyle aLineJoin = JOIN_MITER_OR_BEVEL,
CapStyle aLineCap = CAP_BUTT,
Float aMiterLimit = 10.0f)
: mLineWidth(aLineWidth)
, mMiterLimit(aMiterLimit)
, mLineJoin(aLineJoin)
, mLineCap(aLineCap)
{}
Float mLineWidth;
Float mMiterLimit;
JoinStyle mLineJoin : 4;
CapStyle mLineCap : 3;
};
/*
* This structure supplies additional options for calls to DrawSurface.
*
* mFilter - Filter used when resampling source surface region to the
* destination region.
*/
struct DrawSurfaceOptions {
DrawSurfaceOptions(Filter aFilter = FILTER_LINEAR)
: mFilter(aFilter)
{ }
Filter mFilter : 3;
};
/*
* This class is used to store gradient stops, it can only be used with a
* matching DrawTarget. Not adhering to this condition will make a draw call
* fail.
*/
class GradientStops : public RefCounted<GradientStops>
{
public:
virtual ~GradientStops() {}
virtual BackendType GetBackendType() const = 0;
protected:
GradientStops() {}
};
/*
* This is the base class for 'patterns'. Patterns describe the pixels used as
* the source for a masked composition operation that is done by the different
* drawing commands. These objects are not backend specific, however for
* example the gradient stops on a gradient pattern can be backend specific.
*/
class Pattern
{
public:
virtual ~Pattern() {}
virtual PatternType GetType() const = 0;
protected:
Pattern() {}
};
class ColorPattern : public Pattern
{
public:
ColorPattern(const Color &aColor)
: mColor(aColor)
{}
virtual PatternType GetType() const { return PATTERN_COLOR; }
Color mColor;
};
/*
* This class is used for Linear Gradient Patterns, the gradient stops are
* stored in a separate object and are backend dependent. This class itself
* may be used on the stack.
*/
class LinearGradientPattern : public Pattern
{
public:
/*
* aBegin Start of the linear gradient
* aEnd End of the linear gradient
* aStops GradientStops object for this gradient, this should match the
* backend type of the draw target this pattern will be used with.
*/
LinearGradientPattern(const Point &aBegin,
const Point &aEnd,
GradientStops *aStops)
: mBegin(aBegin)
, mEnd(aEnd)
, mStops(aStops)
{
}
virtual PatternType GetType() const { return PATTERN_LINEAR_GRADIENT; }
Point mBegin;
Point mEnd;
RefPtr<GradientStops> mStops;
};
/*
* This class is used for Radial Gradient Patterns, the gradient stops are
* stored in a separate object and are backend dependent. This class itself
* may be used on the stack.
*/
class RadialGradientPattern : public Pattern
{
public:
/*
* aBegin Start of the linear gradient
* aEnd End of the linear gradient
* aStops GradientStops object for this gradient, this should match the
* backend type of the draw target this pattern will be used with.
*/
RadialGradientPattern(const Point &aCenter,
const Point &aOrigin,
Float aRadius,
GradientStops *aStops)
: mCenter(aCenter)
, mOrigin(aOrigin)
, mRadius(aRadius)
, mStops(aStops)
{
}
virtual PatternType GetType() const { return PATTERN_RADIAL_GRADIENT; }
Point mCenter;
Point mOrigin;
Float mRadius;
RefPtr<GradientStops> mStops;
};
/*
* This class is used for Surface Patterns, they wrap a surface and a
* repetition mode for the surface. This may be used on the stack.
*/
class SurfacePattern : public Pattern
{
public:
SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode)
: mSurface(aSourceSurface)
, mExtendMode(aExtendMode)
{}
virtual PatternType GetType() const { return PATTERN_SURFACE; }
RefPtr<SourceSurface> mSurface;
ExtendMode mExtendMode;
Filter mFilter;
};
/*
* This is the base class for source surfaces. These objects are surfaces
* which may be used as a source in a SurfacePattern of a DrawSurface call.
* They cannot be drawn to directly.
*/
class SourceSurface : public RefCounted<SourceSurface>
{
public:
virtual ~SourceSurface() {}
virtual SurfaceType GetType() const = 0;
virtual IntSize GetSize() const = 0;
virtual SurfaceFormat GetFormat() const = 0;
/*
* This function will get a DataSourceSurface for this surface, a
* DataSourceSurface's data can be accessed directly.
*/
virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
};
class DataSourceSurface : public SourceSurface
{
public:
/* Get the raw bitmap data of the surface */
virtual unsigned char *GetData() = 0;
/*
* Stride of the surface, distance in bytes between the start of the image
* data belonging to row y and row y+1. This may be negative.
*/
virtual int32_t Stride() = 0;
virtual TemporaryRef<DataSourceSurface> GetDataSurface() { RefPtr<DataSourceSurface> temp = this; return temp.forget(); }
};
/* This is an abstract object that accepts path segments. */
class PathSink : public RefCounted<PathSink>
{
public:
virtual ~PathSink() {}
/* Move the current point in the path, any figure currently being drawn will
* be considered closed during fill operations, however when stroking the
* closing line segment will not be drawn.
*/
virtual void MoveTo(const Point &aPoint) = 0;
/* Add a linesegment to the current figure */
virtual void LineTo(const Point &aPoint) = 0;
/* Add a cubic bezier curve to the current figure */
virtual void BezierTo(const Point &aCP1,
const Point &aCP2,
const Point &aCP3) = 0;
/* Add a quadratic bezier curve to the current figure */
virtual void QuadraticBezierTo(const Point &aCP1,
const Point &aCP2) = 0;
/* Close the current figure, this will essentially generate a line segment
* from the current point to the starting point for the current figure
*/
virtual void Close() = 0;
/* Add an arc to the current figure */
virtual void Arc(const Point &aOrigin, float aRadius, float aStartAngle,
float aEndAngle, bool aAntiClockwise = false) = 0;
/* Point the current subpath is at - or where the next subpath will start
* if there is no active subpath.
*/
virtual Point CurrentPoint() const = 0;
};
class PathBuilder;
/* The path class is used to create (sets of) figures of any shape that can be
* filled or stroked to a DrawTarget
*/
class Path : public RefCounted<Path>
{
public:
virtual ~Path() {}
virtual BackendType GetBackendType() const = 0;
/* This returns a PathBuilder object that contains a copy of the contents of
* this path and is still writable.
*/
virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const = 0;
virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
FillRule aFillRule = FILL_WINDING) const = 0;
/* This function checks if a point lies within a path. It allows passing a
* transform that will transform the path to the coordinate space in which
* aPoint is given.
*/
virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const = 0;
/* This gets the fillrule this path's builder was created with. This is not
* mutable.
*/
virtual FillRule GetFillRule() const = 0;
};
/* The PathBuilder class allows path creation. Once finish is called on the
* pathbuilder it may no longer be written to.
*/
class PathBuilder : public PathSink
{
public:
/* Finish writing to the path and return a Path object that can be used for
* drawing. Future use of the builder results in a crash!
*/
virtual TemporaryRef<Path> Finish() = 0;
};
struct Glyph
{
uint32_t mIndex;
Point mPosition;
};
/* This class functions as a glyph buffer that can be drawn to a DrawTarget.
* XXX - This should probably contain the guts of gfxTextRun in the future as
* roc suggested. But for now it's a simple container for a glyph vector.
*/
struct GlyphBuffer
{
// A pointer to a buffer of glyphs. Managed by the caller.
const Glyph *mGlyphs;
// Number of glyphs mGlyphs points to.
uint32_t mNumGlyphs;
};
/* This class is an abstraction of a backend/platform specific font object
* at a particular size. It is passed into text drawing calls to describe
* the font used for the drawing call.
*/
class ScaledFont : public RefCounted<ScaledFont>
{
public:
virtual ~ScaledFont() {}
virtual FontType GetType() const = 0;
/* This allows getting a path that describes the outline of a set of glyphs.
* A target is passed in so that the guarantee is made the returned path
* can be used with any DrawTarget that has the same backend as the one
* passed in.
*/
virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) = 0;
protected:
ScaledFont() {}
};
/* This is the main class used for all the drawing. It is created through the
* factory and accepts drawing commands. The results of drawing to a target
* may be used either through a Snapshot or by flushing the target and directly
* accessing the backing store a DrawTarget was created with.
*/
class DrawTarget : public RefCounted<DrawTarget>
{
public:
DrawTarget() : mTransformDirty(false) {}
virtual ~DrawTarget() {}
virtual BackendType GetType() const = 0;
virtual TemporaryRef<SourceSurface> Snapshot() = 0;
virtual IntSize GetSize() = 0;
/* Ensure that the DrawTarget backend has flushed all drawing operations to
* this draw target. This must be called before using the backing surface of
* this draw target outside of GFX 2D code.
*/
virtual void Flush() = 0;
/*
* Draw a surface to the draw target. Possibly doing partial drawing or
* applying scaling. No sampling happens outside the source.
*
* aSurface Source surface to draw
* aDest Destination rectangle that this drawing operation should draw to
* aSource Source rectangle in aSurface coordinates, this area of aSurface
* will be stretched to the size of aDest.
* aOptions General draw options that are applied to the operation
* aSurfOptions DrawSurface options that are applied
*/
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Blend a surface to the draw target with a shadow. The shadow is drawn as a
* gaussian blur using a specified sigma.
* NOTE: This function works in device space!
*
* aSurface Source surface to draw.
* aDest Destination point that this drawing operation should draw to.
* aColor Color of the drawn shadow
* aOffset Offset of the shadow
* aSigma Sigma used for the guassian filter kernel
*/
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma) = 0;
/*
* Clear a rectangle on the draw target to transparent black. This will
* respect the clipping region and transform.
*
* aRect Rectangle to clear
*/
virtual void ClearRect(const Rect &aRect) = 0;
/*
* This is essentially a 'memcpy' between two surfaces. It moves a pixel
* aligned area from the source surface unscaled directly onto the
* drawtarget. This ignores both transform and clip.
*
* aSurface Surface to copy from
* aSourceRect Source rectangle to be copied
* aDest Destination point to copy the surface to
*/
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination) = 0;
/*
* Fill a rectangle on the DrawTarget with a certain source pattern.
*
* aRect Rectangle that forms the mask of this filling operation
* aPattern Pattern that forms the source of this filling operation
* aOptions Options that are applied to this operation
*/
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Stroke a rectangle on the DrawTarget with a certain source pattern.
*
* aRect Rectangle that forms the mask of this stroking operation
* aPattern Pattern that forms the source of this stroking operation
* aOptions Options that are applied to this operation
*/
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Stroke a line on the DrawTarget with a certain source pattern.
*
* aStart Starting point of the line
* aEnd End point of the line
* aPattern Pattern that forms the source of this stroking operation
* aOptions Options that are applied to this operation
*/
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Stroke a path on the draw target with a certain source pattern.
*
* aPath Path that is to be stroked
* aPattern Pattern that should be used for the stroke
* aStrokeOptions Stroke options used for this operation
* aOptions Draw options used for this operation
*/
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Fill a path on the draw target with a certain source pattern.
*
* aPath Path that is to be filled
* aPattern Pattern that should be used for the fill
* aOptions Draw options used for this operation
*/
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Fill a series of clyphs on the draw target with a certain source pattern.
*/
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions()) = 0;
/*
* Push a clip to the DrawTarget.
*
* aPath The path to clip to
*/
virtual void PushClip(const Path *aPath) = 0;
/* Pop a clip from the DrawTarget. A pop without a corresponding push will
* be ignored.
*/
virtual void PopClip() = 0;
/*
* Create a SourceSurface optimized for use with this DrawTarget for
* existing bitmap data in memory.
*/
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const = 0;
/*
* Create a SourceSurface optimized for use with this DrawTarget from
* an arbitrary other SourceSurface. This may return aSourceSurface or some
* other existing surface.
*/
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const = 0;
/*
* Create a SourceSurface for a type of NativeSurface. This may fail if the
* draw target does not know how to deal with the type of NativeSurface passed
* in.
*/
virtual TemporaryRef<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const = 0;
/*
* Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
*/
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
/*
* Create a path builder with the specified fillmode.
*/
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const = 0;
/*
* Create a GradientStops object that holds information about a set of
* gradient stops, this object is required for linear or radial gradient
* patterns to represent the color stops in the gradient.
*
* aStops An array of gradient stops
* aNumStops Number of stops in the array aStops
*/
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const = 0;
const Matrix &GetTransform() const { return mTransform; }
/*
* Set a transform on the surface, this transform is applied at drawing time
* to both the mask and source of the operation.
*/
virtual void SetTransform(const Matrix &aTransform)
{ mTransform = aTransform; mTransformDirty = true; }
SurfaceFormat GetFormat() { return mFormat; }
/* Tries to get a native surface for a DrawTarget, this may fail if the
* draw target cannot convert to this surface type.
*/
virtual void *GetNativeSurface(NativeSurfaceType aType) = 0;
protected:
Matrix mTransform;
bool mTransformDirty : 1;
SurfaceFormat mFormat;
};
class Factory
{
public:
#ifdef USE_CAIRO
static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface);
#endif
static TemporaryRef<DrawTarget> CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
static TemporaryRef<ScaledFont> CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
#ifdef WIN32
static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
static void SetDirect3D10Device(ID3D10Device1 *aDevice);
static ID3D10Device1 *GetDirect3D10Device();
private:
static ID3D10Device1 *mD3D10Device;
#endif
};
}
}
#endif // _MOZILLA_GFX_2D_H

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

@ -35,12 +35,13 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_BASEMARGIN_H_ #ifndef MOZILLA_GFX_BASEMARGIN_H_
#define MOZILLA_BASEMARGIN_H_ #define MOZILLA_GFX_BASEMARGIN_H_
#include "gfxCore.h" #include "Types.h"
namespace mozilla { namespace mozilla {
namespace gfx {
/** /**
* Do not use this class directly. Subclass it, pass that subclass as the * Do not use this class directly. Subclass it, pass that subclass as the
@ -68,12 +69,10 @@ struct BaseMargin {
T TopBottom() const { return top + bottom; } T TopBottom() const { return top + bottom; }
T& Side(SideT aSide) { T& Side(SideT aSide) {
NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
// This is ugly! // This is ugly!
return *(&top + aSide); return *(&top + aSide);
} }
T Side(SideT aSide) const { T Side(SideT aSide) const {
NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
// This is ugly! // This is ugly!
return *(&top + aSide); return *(&top + aSide);
} }
@ -104,6 +103,7 @@ struct BaseMargin {
} }
}; };
}
} }
#endif /* MOZILLA_BASEMARGIN_H_ */ #endif /* MOZILLA_GFX_BASEMARGIN_H_ */

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

@ -35,10 +35,11 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_BASEPOINT_H_ #ifndef MOZILLA_GFX_BASEPOINT_H_
#define MOZILLA_BASEPOINT_H_ #define MOZILLA_GFX_BASEPOINT_H_
namespace mozilla { namespace mozilla {
namespace gfx {
/** /**
* Do not use this class directly. Subclass it, pass that subclass as the * Do not use this class directly. Subclass it, pass that subclass as the
@ -95,6 +96,7 @@ struct BasePoint {
} }
}; };
}
} }
#endif /* MOZILLA_BASEPOINT_H_ */ #endif /* MOZILLA_GFX_BASEPOINT_H_ */

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

@ -35,12 +35,27 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_BASERECT_H_ #ifndef MOZILLA_GFX_BASERECT_H_
#define MOZILLA_BASERECT_H_ #define MOZILLA_GFX_BASERECT_H_
#include "nsAlgorithm.h" #include <cmath>
namespace mozilla { namespace mozilla {
namespace gfx {
// XXX - <algorithm> conflicts with exceptions on 10.6. Define our own gfx_min/gfx_max
// functions here. Avoid min/max to avoid conflicts with existing #defines on windows.
template<typename T>
T gfx_min(T aVal1, T aVal2)
{
return (aVal1 < aVal2) ? aVal1 : aVal2;
}
template<typename T>
T gfx_max(T aVal1, T aVal2)
{
return (aVal1 > aVal2) ? aVal1 : aVal2;
}
/** /**
* Rectangles have two interpretations: a set of (zero-size) points, * Rectangles have two interpretations: a set of (zero-size) points,
@ -113,15 +128,15 @@ struct BaseRect {
} }
// Returns the rectangle containing the intersection of the points // Returns the rectangle containing the intersection of the points
// (including edges) of *this and aRect. If there are no points in that // (including edges) of *this and aRect. If there are no points in that
// intersection, returns an empty rectangle with x/y set to the max of the x/y // intersection, returns an empty rectangle with x/y set to the gfx_max of the x/y
// of *this and aRect. // of *this and aRect.
Sub Intersect(const Sub& aRect) const Sub Intersect(const Sub& aRect) const
{ {
Sub result; Sub result;
result.x = NS_MAX(x, aRect.x); result.x = gfx_max(x, aRect.x);
result.y = NS_MAX(y, aRect.y); result.y = gfx_max(y, aRect.y);
result.width = NS_MIN(XMost(), aRect.XMost()) - result.x; result.width = gfx_min(XMost(), aRect.XMost()) - result.x;
result.height = NS_MIN(YMost(), aRect.YMost()) - result.y; result.height = gfx_min(YMost(), aRect.YMost()) - result.y;
if (result.width < 0 || result.height < 0) { if (result.width < 0 || result.height < 0) {
result.SizeTo(0, 0); result.SizeTo(0, 0);
} }
@ -129,7 +144,7 @@ struct BaseRect {
} }
// Sets *this to be the rectangle containing the intersection of the points // Sets *this to be the rectangle containing the intersection of the points
// (including edges) of *this and aRect. If there are no points in that // (including edges) of *this and aRect. If there are no points in that
// intersection, sets *this to be an empty rectangle with x/y set to the max // intersection, sets *this to be an empty rectangle with x/y set to the gfx_max
// of the x/y of *this and aRect. // of the x/y of *this and aRect.
// //
// 'this' can be the same object as either aRect1 or aRect2 // 'this' can be the same object as either aRect1 or aRect2
@ -159,10 +174,10 @@ struct BaseRect {
Sub UnionEdges(const Sub& aRect) const Sub UnionEdges(const Sub& aRect) const
{ {
Sub result; Sub result;
result.x = NS_MIN(x, aRect.x); result.x = gfx_min(x, aRect.x);
result.y = NS_MIN(y, aRect.y); result.y = gfx_min(y, aRect.y);
result.width = NS_MAX(XMost(), aRect.XMost()) - result.x; result.width = gfx_max(XMost(), aRect.XMost()) - result.x;
result.height = NS_MAX(YMost(), aRect.YMost()) - result.y; result.height = gfx_max(YMost(), aRect.YMost()) - result.y;
return result; return result;
} }
// Computes the smallest rectangle that contains both the area of both // Computes the smallest rectangle that contains both the area of both
@ -223,15 +238,15 @@ struct BaseRect {
{ {
x += aDx; x += aDx;
y += aDy; y += aDy;
width = NS_MAX(T(0), width - 2 * aDx); width = gfx_max(T(0), width - 2 * aDx);
height = NS_MAX(T(0), height - 2 * aDy); height = gfx_max(T(0), height - 2 * aDy);
} }
void Deflate(const Margin& aMargin) void Deflate(const Margin& aMargin)
{ {
x += aMargin.left; x += aMargin.left;
y += aMargin.top; y += aMargin.top;
width = NS_MAX(T(0), width - aMargin.LeftRight()); width = gfx_max(T(0), width - aMargin.LeftRight());
height = NS_MAX(T(0), height - aMargin.TopBottom()); height = gfx_max(T(0), height - aMargin.TopBottom());
} }
void Deflate(const SizeT& aSize) { Deflate(aSize.width, aSize.height); } void Deflate(const SizeT& aSize) { Deflate(aSize.width, aSize.height); }
@ -303,10 +318,10 @@ struct BaseRect {
// Note: this can turn an empty rectangle into a non-empty rectangle // Note: this can turn an empty rectangle into a non-empty rectangle
void ScaleRoundOut(double aXScale, double aYScale) void ScaleRoundOut(double aXScale, double aYScale)
{ {
T right = static_cast<T>(NS_ceil(double(XMost()) * aXScale)); T right = static_cast<T>(ceil(double(XMost()) * aXScale));
T bottom = static_cast<T>(NS_ceil(double(YMost()) * aYScale)); T bottom = static_cast<T>(ceil(double(YMost()) * aYScale));
x = static_cast<T>(NS_floor(double(x) * aXScale)); x = static_cast<T>(floor(double(x) * aXScale));
y = static_cast<T>(NS_floor(double(y) * aYScale)); y = static_cast<T>(floor(double(y) * aYScale));
width = right - x; width = right - x;
height = bottom - y; height = bottom - y;
} }
@ -318,12 +333,12 @@ struct BaseRect {
// unrounded result. // unrounded result.
void ScaleRoundIn(double aXScale, double aYScale) void ScaleRoundIn(double aXScale, double aYScale)
{ {
T right = static_cast<T>(NS_floor(double(XMost()) * aXScale)); T right = static_cast<T>(floor(double(XMost()) * aXScale));
T bottom = static_cast<T>(NS_floor(double(YMost()) * aYScale)); T bottom = static_cast<T>(floor(double(YMost()) * aYScale));
x = static_cast<T>(NS_ceil(double(x) * aXScale)); x = static_cast<T>(ceil(double(x) * aXScale));
y = static_cast<T>(NS_ceil(double(y) * aYScale)); y = static_cast<T>(ceil(double(y) * aYScale));
width = NS_MAX<T>(0, right - x); width = gfx_max<T>(0, right - x);
height = NS_MAX<T>(0, bottom - y); height = gfx_max<T>(0, bottom - y);
} }
// Scale 'this' by 1/aScale, converting coordinates to integers so that the result is // Scale 'this' by 1/aScale, converting coordinates to integers so that the result is
// the smallest integer-coordinate rectangle containing the unrounded result. // the smallest integer-coordinate rectangle containing the unrounded result.
@ -350,6 +365,7 @@ private:
bool operator!=(const Sub& aRect) const { return false; } bool operator!=(const Sub& aRect) const { return false; }
}; };
}
} }
#endif /* MOZILLA_BASERECT_H_ */ #endif /* MOZILLA_GFX_BASERECT_H_ */

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

@ -35,10 +35,11 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_BASESIZE_H_ #ifndef MOZILLA_GFX_BASESIZE_H_
#define MOZILLA_BASESIZE_H_ #define MOZILLA_GFX_BASESIZE_H_
namespace mozilla { namespace mozilla {
namespace gfx {
/** /**
* Do not use this class directly. Subclass it, pass that subclass as the * Do not use this class directly. Subclass it, pass that subclass as the
@ -96,6 +97,7 @@ struct BaseSize {
} }
}; };
}
} }
#endif /* MOZILLA_BASESIZE_H_ */ #endif /* MOZILLA_GFX_BASESIZE_H_ */

184
gfx/2d/DrawTargetCG.cpp Normal file
Просмотреть файл

@ -0,0 +1,184 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "DrawTargetCG.h"
#include "SourceSurfaceCG.h"
#include "Rect.h"
//CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode);
namespace mozilla {
namespace gfx {
static CGRect RectToCGRect(Rect r)
{
return CGRectMake(r.x, r.y, r.width, r.height);
}
CGBlendMode ToBlendMode(CompositionOp op)
{
CGBlendMode mode;
switch (op) {
case OP_OVER:
mode = kCGBlendModeNormal;
break;
case OP_SOURCE:
mode = kCGBlendModeCopy;
break;
case OP_CLEAR:
mode = kCGBlendModeClear;
break;
case OP_ADD:
mode = kCGBlendModePlusLighter;
break;
case OP_ATOP:
mode = kCGBlendModeSourceAtop;
break;
default:
mode = kCGBlendModeNormal;
}
return mode;
}
DrawTargetCG::DrawTargetCG()
{
}
DrawTargetCG::~DrawTargetCG()
{
}
TemporaryRef<SourceSurface>
DrawTargetCG::Snapshot()
{
return NULL;
}
TemporaryRef<SourceSurface>
DrawTargetCG::CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const
{
RefPtr<SourceSurfaceCG> newSurf = new SourceSurfaceCG();
if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
return NULL;
}
return newSurf;
}
TemporaryRef<SourceSurface>
DrawTargetCG::OptimizeSourceSurface(SourceSurface *aSurface) const
{
return NULL;
}
void
DrawTargetCG::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawOptions &aOptions,
const DrawSurfaceOptions &aSurfOptions)
{
CGImageRef image;
CGImageRef subimage = NULL;
if (aSurface->GetType() == COREGRAPHICS_IMAGE) {
image = static_cast<SourceSurfaceCG*>(aSurface)->GetImage();
/* we have two options here:
* - create a subimage -- this is slower
* - fancy things with clip and different dest rects */
{
subimage = CGImageCreateWithImageInRect(image, RectToCGRect(aSource));
image = subimage;
}
CGContextDrawImage(mCg, RectToCGRect(aDest), image);
CGImageRelease(subimage);
}
}
void
DrawTargetCG::FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions)
{
//XXX: it would be nice to hang a CGColor off of the pattern here
if (aPattern.GetType() == COLOR) {
Color color = static_cast<const ColorPattern*>(&aPattern)->mColor;
//XXX: the m prefixes are painful here
CGContextSetRGBFillColor(mCg, color.mR, color.mG, color.mB, color.mA);
}
CGContextSetBlendMode(mCg, ToBlendMode(aOptions.mCompositionOp));
CGContextFillRect(mCg, RectToCGRect(aRect));
}
bool
DrawTargetCG::Init(const IntSize &aSize)
{
CGColorSpaceRef cgColorspace;
cgColorspace = CGColorSpaceCreateDeviceRGB();
mSize = aSize;
int bitsPerComponent = 8;
int stride = mSize.width;
CGBitmapInfo bitinfo;
bitinfo = kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst;
// XXX: mWidth is ugly
mCg = CGBitmapContextCreate (NULL,
mSize.width,
mSize.height,
bitsPerComponent,
stride,
cgColorspace,
bitinfo);
CGColorSpaceRelease (cgColorspace);
return true;
}
}
}

85
gfx/2d/DrawTargetCG.h Normal file
Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jeff Muizelaar <jmuizelaar@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma once
#include <ApplicationServices/ApplicationServices.h>
#include "2D.h"
#include "Rect.h"
namespace mozilla {
namespace gfx {
class DrawTargetCG : public DrawTarget
{
public:
DrawTargetCG();
virtual ~DrawTargetCG();
virtual BackendType GetType() const { return COREGRAPHICS; }
virtual TemporaryRef<SourceSurface> Snapshot();
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawOptions &aOptions = DrawOptions(),
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions());
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
bool Init(const IntSize &aSize);
bool Init(CGContextRef cgContext, const IntSize &aSize);
/* This is for creating good compatible surfaces */
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const;
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
private:
bool InitCGRenderTarget();
IntSize mSize;
CGContextRef mCg;
};
}
}

221
gfx/2d/DrawTargetCairo.cpp Normal file
Просмотреть файл

@ -0,0 +1,221 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "DrawTargetCairo.h"
#include "SourceSurfaceCairo.h"
#include "cairo/cairo.h"
namespace mozilla {
namespace gfx {
cairo_operator_t
GfxOpToCairoOp(CompositionOp op)
{
switch (op)
{
case OP_OVER:
return CAIRO_OPERATOR_OVER;
case OP_SOURCE:
return CAIRO_OPERATOR_SOURCE;
case OP_ADD:
return CAIRO_OPERATOR_ADD;
case OP_ATOP:
return CAIRO_OPERATOR_ATOP;
case OP_COUNT:
break;
}
return CAIRO_OPERATOR_OVER;
}
cairo_filter_t
GfxFilterToCairoFilter(Filter filter)
{
switch (filter)
{
case FILTER_LINEAR:
return CAIRO_FILTER_BILINEAR;
case FILTER_POINT:
return CAIRO_FILTER_NEAREST;
}
return CAIRO_FILTER_BILINEAR;
}
cairo_format_t
GfxFormatToCairoFormat(SurfaceFormat format)
{
switch (format)
{
case FORMAT_B8G8R8A8:
return CAIRO_FORMAT_ARGB32;
case FORMAT_B8G8R8X8:
return CAIRO_FORMAT_RGB24;
case FORMAT_A8:
return CAIRO_FORMAT_A8;
}
return CAIRO_FORMAT_ARGB32;
}
void
GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
{
cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
}
DrawTargetCairo::DrawTargetCairo()
: mContext(NULL)
{
}
DrawTargetCairo::~DrawTargetCairo()
{
cairo_destroy(mContext);
}
TemporaryRef<SourceSurface>
DrawTargetCairo::Snapshot()
{
return NULL;
}
void
DrawTargetCairo::Flush()
{
cairo_surface_t* surf = cairo_get_target(mContext);
cairo_surface_flush(surf);
}
void
DrawTargetCairo::DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions,
const DrawOptions &aOptions)
{
float sx = aSource.Width() / aDest.Width();
float sy = aSource.Height() / aDest.Height();
cairo_matrix_t src_mat;
cairo_matrix_init_scale(&src_mat, sx, sy);
cairo_matrix_translate(&src_mat, -aSource.X(), -aSource.Y());
cairo_surface_t* surf = NULL;
if (aSurface->GetType() == SURFACE_CAIRO) {
surf = static_cast<SourceSurfaceCairo*>(aSurface)->GetSurface();
}
cairo_pattern_t* pat = cairo_pattern_create_for_surface(surf);
cairo_pattern_set_matrix(pat, &src_mat);
cairo_pattern_set_filter(pat, GfxFilterToCairoFilter(aSurfOptions.mFilter));
cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
cairo_rectangle(mContext, aDest.X(), aDest.Y(),
aDest.Width(), aDest.Height());
cairo_fill(mContext);
cairo_pattern_destroy(pat);
}
void
DrawTargetCairo::FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions)
{
cairo_new_path(mContext);
cairo_rectangle(mContext, aRect.x, aRect.y, aRect.Width(), aRect.Height());
cairo_set_operator(mContext, GfxOpToCairoOp(aOptions.mCompositionOp));
if (aPattern.GetType() == PATTERN_COLOR) {
Color color = static_cast<const ColorPattern&>(aPattern).mColor;
cairo_set_source_rgba(mContext, color.r, color.g,
color.b, color.a);
}
cairo_fill(mContext);
}
TemporaryRef<SourceSurface>
DrawTargetCairo::CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const
{
cairo_surface_t* surf = cairo_image_surface_create_for_data(aData,
GfxFormatToCairoFormat(aFormat),
aSize.width,
aSize.height,
aStride);
RefPtr<SourceSurfaceCairo> source_surf = new SourceSurfaceCairo();
source_surf->InitFromSurface(surf, aSize, aFormat);
cairo_surface_destroy(surf);
return source_surf;
}
TemporaryRef<SourceSurface>
DrawTargetCairo::OptimizeSourceSurface(SourceSurface *aSurface) const
{
return NULL;
}
TemporaryRef<SourceSurface>
DrawTargetCairo::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
{
return NULL;
}
bool
DrawTargetCairo::Init(cairo_surface_t* aSurface)
{
mContext = cairo_create(aSurface);
return true;
}
void
DrawTargetCairo::SetTransform(const Matrix& aTransform)
{
cairo_matrix_t mat;
GfxMatrixToCairoMatrix(aTransform, mat);
cairo_set_matrix(mContext, &mat);
mTransform = aTransform;
}
}
}

143
gfx/2d/DrawTargetCairo.h Normal file
Просмотреть файл

@ -0,0 +1,143 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
#define _MOZILLA_GFX_DRAWTARGET_CAIRO_H_
#include "2D.h"
#include "cairo/cairo.h"
namespace mozilla {
namespace gfx {
class DrawTargetCairo : public DrawTarget
{
public:
DrawTargetCairo();
virtual ~DrawTargetCairo();
virtual BackendType GetType() const { return BACKEND_CAIRO; }
virtual TemporaryRef<SourceSurface> Snapshot();
virtual IntSize GetSize() { return IntSize(); }
virtual void Flush();
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma)
{ }
virtual void ClearRect(const Rect &aRect)
{ }
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination)
{ }
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions())
{ return; }
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions())
{ return; }
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions())
{ return; }
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions())
{ return; }
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions)
{ return; }
virtual void PushClip(const Path *aPath) { }
virtual void PopClip() { }
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const { return NULL; }
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const;
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
virtual TemporaryRef<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{ return NULL; }
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const
{ return NULL; }
virtual void *GetNativeSurface(NativeSurfaceType aType)
{ return NULL; }
virtual void SetTransform(const Matrix& aTransform);
bool Init(cairo_surface_t* aSurface);
private:
cairo_t* mContext;
};
}
}
#endif // _MOZILLA_GFX_DRAWTARGET_CAIRO_H_

1679
gfx/2d/DrawTargetD2D.cpp Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

204
gfx/2d/DrawTargetD2D.h Normal file
Просмотреть файл

@ -0,0 +1,204 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_DRAWTARGETD2D_H_
#define MOZILLA_GFX_DRAWTARGETD2D_H_
#include "2D.h"
#include "PathD2D.h"
#include <d3d10_1.h>
#include "HelpersD2D.h"
#include <vector>
#include <sstream>
namespace mozilla {
namespace gfx {
class SourceSurfaceD2DTarget;
struct PrivateD3D10DataD2D
{
RefPtr<ID3D10Effect> mEffect;
RefPtr<ID3D10InputLayout> mInputLayout;
RefPtr<ID3D10Buffer> mVB;
RefPtr<ID3D10BlendState> mBlendStates[OP_COUNT];
};
class DrawTargetD2D : public DrawTarget
{
public:
DrawTargetD2D();
virtual ~DrawTargetD2D();
virtual BackendType GetType() const { return BACKEND_DIRECT2D; }
virtual TemporaryRef<SourceSurface> Snapshot();
virtual IntSize GetSize() { return mSize; }
virtual void Flush();
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma);
virtual void ClearRect(const Rect &aRect);
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination);
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions());
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions());
virtual void PushClip(const Path *aPath);
virtual void PopClip();
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const;
virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const;
virtual TemporaryRef<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const;
virtual TemporaryRef<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const;
virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FILL_WINDING) const;
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops) const;
virtual void *GetNativeSurface(NativeSurfaceType aType);
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
bool InitD3D10Data();
static ID2D1Factory *factory();
operator std::string() const {
std::stringstream stream;
stream << "DrawTargetD2D(" << this << ")";
return stream.str();
}
private:
friend class AutoSaveRestoreClippedOut;
friend class SourceSurfaceD2DTarget;
bool InitD2DRenderTarget();
void PrepareForDrawing(ID2D1RenderTarget *aRT);
// This function will mark the surface as changing, and make sure any
// copy-on-write snapshots are notified.
void MarkChanged();
ID3D10BlendState *GetBlendStateForOperator(CompositionOp aOperator);
ID2D1RenderTarget *GetRTForOperator(CompositionOp aOperator);
void FinalizeRTForOperator(CompositionOp aOperator, const Rect &aBounds);
void EnsureViews();
void PopAllClips();
TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture);
TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions);
IntSize mSize;
RefPtr<ID3D10Device1> mDevice;
RefPtr<ID3D10Texture2D> mTexture;
mutable RefPtr<ID2D1RenderTarget> mRT;
// Temporary texture and render target used for supporting alternative operators.
RefPtr<ID3D10Texture2D> mTempTexture;
RefPtr<ID3D10RenderTargetView> mRTView;
RefPtr<ID3D10ShaderResourceView> mSRView;
RefPtr<ID2D1RenderTarget> mTempRT;
RefPtr<ID3D10RenderTargetView> mTempRTView;
// List of pushed clips.
struct PushedClip
{
RefPtr<ID2D1Layer> mLayer;
D2D1_RECT_F mBounds;
D2D1_MATRIX_3X2_F mTransform;
RefPtr<PathD2D> mPath;
};
std::vector<PushedClip> mPushedClips;
// List of Snapshots of this surface, these need to be told when this
// surface is modified. Possibly vector is not the best choice here.
std::vector<SourceSurfaceD2DTarget*> mSnapshots;
// A list of targets we need to flush when we're modified.
std::vector<RefPtr<DrawTargetD2D>> mDependentTargets;
// True of the current clip stack is pushed to the main RT.
bool mClipsArePushed;
PrivateD3D10DataD2D *mPrivateData;
static ID2D1Factory *mFactory;
};
}
}
#endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */

152
gfx/2d/Factory.cpp Normal file
Просмотреть файл

@ -0,0 +1,152 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "2D.h"
#ifdef USE_CAIRO
#include "DrawTargetCairo.h"
#endif
#ifdef WIN32
#include "DrawTargetD2D.h"
#include "ScaledFontDWrite.h"
#include <d3d10_1.h>
#endif
#include "Logging.h"
#ifdef PR_LOGGING
PRLogModuleInfo *sGFX2DLog = PR_NewLogModule("gfx2d");
#endif
namespace mozilla {
namespace gfx {
// XXX - Need to define an API to set this.
int sGfxLogLevel = LOG_DEBUG;
#ifdef WIN32
ID3D10Device1 *Factory::mD3D10Device;
#endif
TemporaryRef<DrawTarget>
Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
{
switch (aBackend) {
#ifdef WIN32
case BACKEND_DIRECT2D:
{
RefPtr<DrawTargetD2D> newTarget;
newTarget = new DrawTargetD2D();
if (newTarget->Init(aSize, aFormat)) {
return newTarget;
}
break;
}
#endif
default:
gfxDebug() << "Invalid draw target type specified.";
return NULL;
}
gfxDebug() << "Failed to create DrawTarget, Type: " << aBackend << " Size: " << aSize;
// Failed
return NULL;
}
TemporaryRef<ScaledFont>
Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize)
{
switch (aNativeFont.mType) {
#ifdef WIN32
case NATIVE_FONT_DWRITE_FONT_FACE:
{
return new ScaledFontDWrite(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aSize);
}
#endif
default:
gfxWarning() << "Invalid native font type specified.";
return NULL;
}
}
#ifdef WIN32
TemporaryRef<DrawTarget>
Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
{
RefPtr<DrawTargetD2D> newTarget;
newTarget = new DrawTargetD2D();
if (newTarget->Init(aTexture, aFormat)) {
return newTarget;
}
gfxWarning() << "Failed to create draw target for D3D10 texture.";
// Failed
return NULL;
}
void
Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
{
mD3D10Device = aDevice;
}
ID3D10Device1*
Factory::GetDirect3D10Device()
{
return mD3D10Device;
}
#endif // XP_WIN
#ifdef USE_CAIRO
TemporaryRef<DrawTarget>
Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface)
{
RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
if (newTarget->Init(aSurface)) {
return newTarget;
}
return NULL;
}
#endif
}
}

66
gfx/2d/GradientStopsD2D.h Normal file
Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_GRADIENTSTOPSD2D_H_
#define MOZILLA_GFX_GRADIENTSTOPSD2D_H_
#include "2D.h"
#include <D2D1.h>
namespace mozilla {
namespace gfx {
class GradientStopsD2D : public GradientStops
{
public:
GradientStopsD2D(ID2D1GradientStopCollection *aStopCollection)
: mStopCollection(aStopCollection)
{}
virtual BackendType GetBackendType() const { return BACKEND_DIRECT2D; }
private:
friend class DrawTargetD2D;
mutable RefPtr<ID2D1GradientStopCollection> mStopCollection;
};
}
}
#endif /* MOZILLA_GFX_GRADIENTSTOPSD2D_H_ */

175
gfx/2d/HelpersD2D.h Normal file
Просмотреть файл

@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_HELPERSD2D_H_
#define MOZILLA_GFX_HELPERSD2D_H_
#include <D2D1.h>
#include "2D.h"
namespace mozilla {
namespace gfx {
static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
{
return D2D1::Point2F(aPoint.x, aPoint.y);
}
static inline D2D1_SIZE_U D2DIntSize(const IntSize &aSize)
{
return D2D1::SizeU(aSize.width, aSize.height);
}
static inline D2D1_RECT_F D2DRect(const Rect &aRect)
{
return D2D1::RectF(aRect.x, aRect.y, aRect.XMost(), aRect.YMost());
}
static inline D2D1_BITMAP_INTERPOLATION_MODE D2DFilter(const Filter &aFilter)
{
switch (aFilter) {
case FILTER_POINT:
return D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
}
return D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
}
static inline D2D1_ANTIALIAS_MODE D2DAAMode(const AntialiasMode &aMode)
{
switch (aMode) {
case AA_NONE:
D2D1_ANTIALIAS_MODE_ALIASED;
}
return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
}
static inline D2D1_MATRIX_3X2_F D2DMatrix(const Matrix &aTransform)
{
return D2D1::Matrix3x2F(aTransform._11, aTransform._12,
aTransform._21, aTransform._22,
aTransform._31, aTransform._32);
}
static inline D2D1_COLOR_F D2DColor(const Color &aColor)
{
return D2D1::ColorF(aColor.r, aColor.g, aColor.b, aColor.a);
}
static inline IntSize ToIntSize(const D2D1_SIZE_U &aSize)
{
return IntSize(aSize.width, aSize.height);
}
static inline SurfaceFormat ToPixelFormat(const D2D1_PIXEL_FORMAT &aFormat)
{
switch(aFormat.format) {
case DXGI_FORMAT_A8_UNORM:
return FORMAT_A8;
case DXGI_FORMAT_B8G8R8A8_UNORM:
if (aFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) {
return FORMAT_B8G8R8X8;
} else {
return FORMAT_B8G8R8A8;
}
}
return FORMAT_B8G8R8A8;
}
static inline Rect ToRect(const D2D1_RECT_F &aRect)
{
return Rect(aRect.left, aRect.top, aRect.right - aRect.left, aRect.bottom - aRect.top);
}
static inline DXGI_FORMAT DXGIFormat(SurfaceFormat aFormat)
{
switch (aFormat) {
case FORMAT_B8G8R8A8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case FORMAT_B8G8R8X8:
return DXGI_FORMAT_B8G8R8A8_UNORM;
case FORMAT_A8:
return DXGI_FORMAT_A8_UNORM;
}
return DXGI_FORMAT_UNKNOWN;
}
static inline D2D1_ALPHA_MODE AlphaMode(SurfaceFormat aFormat)
{
switch (aFormat) {
case FORMAT_B8G8R8X8:
return D2D1_ALPHA_MODE_IGNORE;
}
return D2D1_ALPHA_MODE_PREMULTIPLIED;
}
static inline int BytesPerPixel(SurfaceFormat aFormat)
{
switch (aFormat) {
case FORMAT_A8:
return 1;
default:
return 4;
}
}
/**
* This structure is used to pass rectangles to our shader constant. We can use
* this for passing rectangular areas to SetVertexShaderConstant. In the format
* of a 4 component float(x,y,width,height). Our vertex shader can then use
* this to construct rectangular positions from the 0,0-1,1 quad that we source
* it with.
*/
struct ShaderConstantRectD3D10
{
float mX, mY, mWidth, mHeight;
ShaderConstantRectD3D10(float aX, float aY, float aWidth, float aHeight)
: mX(aX), mY(aY), mWidth(aWidth), mHeight(aHeight)
{ }
// For easy passing to SetVertexShaderConstantF.
operator float* () { return &mX; }
};
}
}
#endif /* MOZILLA_GFX_HELPERSD2D_H_ */

144
gfx/2d/Logging.h Normal file
Просмотреть файл

@ -0,0 +1,144 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_LOGGING_H_
#define MOZILLA_GFX_LOGGING_H_
#include <string>
#include <sstream>
#include "Point.h"
#ifdef WIN32
#include <windows.h>
#endif
#ifdef PR_LOGGING
#include <prlog.h>
extern PRLogModuleInfo *sGFX2DLog;
#endif
namespace mozilla {
namespace gfx {
const int LOG_DEBUG = 1;
const int LOG_WARNING = 2;
#ifdef PR_LOGGING
inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) {
switch (aLevel) {
case LOG_DEBUG:
return PR_LOG_DEBUG;
case LOG_WARNING:
return PR_LOG_WARNING;
}
return PR_LOG_DEBUG;
}
#endif
extern int sGfxLogLevel;
static void OutputMessage(const std::string &aString, int aLevel) {
#if defined(WIN32) && !defined(PR_LOGGING)
if (aLevel >= sGfxLogLevel) {
::OutputDebugStringA(aString.c_str());
}
#elif defined(PR_LOGGING)
if (PR_LOG_TEST(sGFX2DLog, PRLogLevelForLevel(aLevel))) {
PR_LogPrint(aString.c_str());
}
#else
if (aLevel >= sGfxLogLevel) {
printf(aString.c_str());
}
#endif
}
class NoLog
{
public:
NoLog() {}
~NoLog() {}
template<typename T>
NoLog &operator <<(const T &aLogText) { return *this; }
};
template<int L>
class Log
{
public:
Log() {}
~Log() { mMessage << '\n'; WriteLog(mMessage.str()); }
Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; }
Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; }
Log &operator <<(const Size &aSize)
{ mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
Log &operator <<(const IntSize &aSize)
{ mMessage << "(" << aSize.width << "x" << aSize.height << ")"; return *this; }
private:
void WriteLog(const std::string &aString) {
OutputMessage(aString, L);
}
std::stringstream mMessage;
};
typedef Log<LOG_DEBUG> DebugLog;
typedef Log<LOG_WARNING> WarningLog;
#ifdef GFX_LOG_DEBUG
#define gfxDebug DebugLog
#else
#define gfxDebug if (1) ; else NoLog
#endif
#ifdef GFX_LOG_WARNING
#define gfxWarning WarningLog
#else
#define gfxWarning if (1) ; else NoLog
#endif
}
}
#endif /* MOZILLA_GFX_LOGGING_H_ */

100
gfx/2d/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,100 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation code.
#
# The Initial Developer of the Original Code is Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Bas Schouten <bschouten@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = gfx2d
LIBRARY_NAME = gfx2d
LIBXUL_LIBRARY = 1
EXPORT_LIBRARY = 1
EXPORTS_NAMESPACES = mozilla/gfx
EXPORTS_mozilla/gfx = \
2D.h \
BasePoint.h \
BaseMargin.h \
BaseRect.h \
BaseSize.h \
Point.h \
Matrix.h \
Rect.h \
Types.h \
$(NULL)
CPPSRCS = \
Factory.cpp \
Matrix.cpp \
DrawTargetCairo.cpp \
SourceSurfaceCairo.cpp \
$(NULL)
DEFINES += -DMOZ_GFX -DUSE_CAIRO
ifdef MOZ_DEBUG
DEFINES += -DGFX_LOG_DEBUG -DGFX_LOG_WARNING
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CPPSRCS += \
DrawTargetD2D.cpp \
SourceSurfaceD2D.cpp \
SourceSurfaceD2DTarget.cpp \
PathD2D.cpp \
ScaledFontDWrite.cpp \
$(NULL)
DEFINES += -DWIN32
endif
#ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
#CPPSRCS += \
# DrawTargetCG.cpp \
# SourceSurfaceCG.cpp \
# $(NULL)
#
## Always link with OpenGL/AGL
#EXTRA_DSO_LDOPTS += -framework OpenGL -framework AGL -framework QuickTime -framework AppKit -framework QuartzCore
#endif
include $(topsrcdir)/config/rules.mk

92
gfx/2d/Matrix.cpp Normal file
Просмотреть файл

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "Matrix.h"
#include <math.h>
namespace mozilla {
namespace gfx {
Matrix
Matrix::Rotation(Float aAngle)
{
Matrix newMatrix;
Float s = sin(aAngle);
Float c = cos(aAngle);
newMatrix._11 = c;
newMatrix._12 = s;
newMatrix._21 = -s;
newMatrix._22 = c;
return newMatrix;
}
Rect
Matrix::TransformBounds(const Rect &aRect) const
{
int i;
Point quad[4];
Float min_x, max_x;
Float min_y, max_y;
quad[0] = *this * aRect.TopLeft();
quad[1] = *this * aRect.TopRight();
quad[2] = *this * aRect.BottomLeft();
quad[3] = *this * aRect.BottomRight();
min_x = max_x = quad[0].x;
min_y = max_y = quad[0].y;
for (i = 1; i < 4; i++) {
if (quad[i].x < min_x)
min_x = quad[i].x;
if (quad[i].x > max_x)
max_x = quad[i].x;
if (quad[i].y < min_y)
min_y = quad[i].y;
if (quad[i].y > max_y)
max_y = quad[i].y;
}
return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
}
}
}

151
gfx/2d/Matrix.h Normal file
Просмотреть файл

@ -0,0 +1,151 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_MATRIX_H_
#define MOZILLA_GFX_MATRIX_H_
#include "Types.h"
#include "Rect.h"
#include "Point.h"
#include <math.h>
namespace mozilla {
namespace gfx {
class Matrix
{
public:
Matrix()
: _11(1.0f), _12(0)
, _21(0), _22(1.0f)
, _31(0), _32(0)
{}
Matrix(Float a11, Float a12, Float a21, Float a22, Float a31, Float a32)
: _11(a11), _12(a12)
, _21(a21), _22(a22)
, _31(a31), _32(a32)
{}
Float _11, _12;
Float _21, _22;
Float _31, _32;
Point operator *(const Point &aPoint) const
{
Point retPoint;
retPoint.x = aPoint.x * _11 + aPoint.y * _21 + _31;
retPoint.y = aPoint.x * _12 + aPoint.y * _22 + _32;
return retPoint;
}
Rect TransformBounds(const Rect& rect) const;
// Apply a scale to this matrix. This scale will be applied -before- the
// existing transformation of the matrix.
Matrix &Scale(Float aX, Float aY)
{
_11 *= aX;
_12 *= aX;
_21 *= aY;
_22 *= aY;
return *this;
}
Matrix &Translate(Float aX, Float aY)
{
_31 += _11 * aX + _21 * aY;
_32 += _12 * aX + _22 * aY;
return *this;
}
bool Invert()
{
// Compute co-factors.
Float A = _22;
Float B = -_21;
Float C = _21 * _32 - _22 * _31;
Float D = -_12;
Float E = _11;
Float F = _31 * _12 - _11 * _32;
Float det = Determinant();
if (!det) {
return false;
}
Float inv_det = 1 / det;
_11 = inv_det * A;
_12 = inv_det * D;
_21 = inv_det * B;
_22 = inv_det * E;
_31 = inv_det * C;
_32 = inv_det * F;
return true;
}
Float Determinant() const
{
return _11 * _22 - _12 * _21;
}
static Matrix Rotation(Float aAngle);
Matrix operator*(const Matrix &aMatrix) const
{
Matrix resultMatrix;
resultMatrix._11 = this->_11 * aMatrix._11 + this->_12 * aMatrix._21;
resultMatrix._12 = this->_11 * aMatrix._12 + this->_12 * aMatrix._22;
resultMatrix._21 = this->_21 * aMatrix._11 + this->_22 * aMatrix._21;
resultMatrix._22 = this->_21 * aMatrix._12 + this->_22 * aMatrix._22;
resultMatrix._31 = this->_31 * aMatrix._11 + this->_32 * aMatrix._21 + aMatrix._31;
resultMatrix._32 = this->_31 * aMatrix._12 + this->_32 * aMatrix._22 + aMatrix._32;
return resultMatrix;
}
};
}
}
#endif /* MOZILLA_GFX_MATRIX_H_ */

348
gfx/2d/PathD2D.cpp Normal file
Просмотреть файл

@ -0,0 +1,348 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma once
#include "PathD2D.h"
#include "HelpersD2D.h"
#include <math.h>
#include "DrawTargetD2D.h"
#include "Logging.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
namespace mozilla {
namespace gfx {
// This class exists as a wrapper for ID2D1SimplifiedGeometry sink, it allows
// a geometry to be duplicated into a geometry sink, while removing the final
// figure end and thus allowing a figure that was implicitly closed to be
// continued.
class OpeningGeometrySink : public ID2D1SimplifiedGeometrySink
{
public:
OpeningGeometrySink(ID2D1SimplifiedGeometrySink *aSink)
: mSink(aSink)
, mNeedsFigureEnded(false)
{
}
HRESULT STDMETHODCALLTYPE QueryInterface(const IID &aIID, void **aPtr)
{
if (!aPtr) {
return E_POINTER;
}
if (aIID == IID_IUnknown) {
*aPtr = static_cast<IUnknown*>(this);
return S_OK;
} else if (aIID == IID_ID2D1SimplifiedGeometrySink) {
*aPtr = static_cast<ID2D1SimplifiedGeometrySink*>(this);
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef()
{
return 1;
}
ULONG STDMETHODCALLTYPE Release()
{
return 1;
}
// We ignore SetFillMode, the copier will decide.
STDMETHOD_(void, SetFillMode)(D2D1_FILL_MODE aMode)
{ EnsureFigureEnded(); return; }
STDMETHOD_(void, BeginFigure)(D2D1_POINT_2F aPoint, D2D1_FIGURE_BEGIN aBegin)
{ EnsureFigureEnded(); return mSink->BeginFigure(aPoint, aBegin); }
STDMETHOD_(void, AddLines)(const D2D1_POINT_2F *aLines, UINT aCount)
{ EnsureFigureEnded(); return mSink->AddLines(aLines, aCount); }
STDMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *aSegments, UINT aCount)
{ EnsureFigureEnded(); return mSink->AddBeziers(aSegments, aCount); }
STDMETHOD(Close)()
{ /* Should never be called! */ return S_OK; }
STDMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT aFlags)
{ return mSink->SetSegmentFlags(aFlags); }
// This function is special - it's the reason this class exists.
// It needs to intercept the very last endfigure. So that a user can
// continue writing to this sink as if they never stopped.
STDMETHOD_(void, EndFigure)(D2D1_FIGURE_END aEnd)
{
if (aEnd == D2D1_FIGURE_END_CLOSED) {
return mSink->EndFigure(aEnd);
} else {
mNeedsFigureEnded = true;
}
}
private:
void EnsureFigureEnded()
{
if (mNeedsFigureEnded) {
mSink->EndFigure(D2D1_FIGURE_END_OPEN);
mNeedsFigureEnded = false;
}
}
ID2D1SimplifiedGeometrySink *mSink;
bool mNeedsFigureEnded;
};
PathBuilderD2D::~PathBuilderD2D()
{
}
void
PathBuilderD2D::MoveTo(const Point &aPoint)
{
if (mFigureActive) {
mSink->EndFigure(D2D1_FIGURE_END_OPEN);
mFigureActive = false;
}
EnsureActive(aPoint);
mCurrentPoint = aPoint;
}
void
PathBuilderD2D::LineTo(const Point &aPoint)
{
EnsureActive(aPoint);
mSink->AddLine(D2DPoint(aPoint));
mCurrentPoint = aPoint;
}
void
PathBuilderD2D::BezierTo(const Point &aCP1,
const Point &aCP2,
const Point &aCP3)
{
EnsureActive(aCP1);
mSink->AddBezier(D2D1::BezierSegment(D2DPoint(aCP1),
D2DPoint(aCP2),
D2DPoint(aCP3)));
mCurrentPoint = aCP3;
}
void
PathBuilderD2D::QuadraticBezierTo(const Point &aCP1,
const Point &aCP2)
{
EnsureActive(aCP1);
mSink->AddQuadraticBezier(D2D1::QuadraticBezierSegment(D2DPoint(aCP1),
D2DPoint(aCP2)));
mCurrentPoint = aCP2;
}
void
PathBuilderD2D::Close()
{
if (mFigureActive) {
mSink->EndFigure(D2D1_FIGURE_END_CLOSED);
mFigureActive = false;
EnsureActive(mBeginPoint);
}
}
void
PathBuilderD2D::Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise)
{
if (aAntiClockwise && aStartAngle < aEndAngle) {
// D2D does things a little differently, and draws the arc by specifying an
// beginning and an end point. This means the circle will be the wrong way
// around if the start angle is smaller than the end angle. It might seem
// tempting to invert aAntiClockwise but that would change the sweeping
// direction of the arc to instead we exchange start/begin.
Float oldStart = aStartAngle;
aStartAngle = aEndAngle;
aEndAngle = oldStart;
}
// XXX - Workaround for now, D2D does not appear to do the desired thing when
// the angle sweeps a complete circle.
if (aEndAngle - aStartAngle >= 2 * M_PI) {
aEndAngle = Float(aStartAngle + M_PI * 1.9999);
} else if (aStartAngle - aEndAngle >= 2 * M_PI) {
aStartAngle = Float(aEndAngle + M_PI * 1.9999);
}
Point startPoint;
startPoint.x = aOrigin.x + aRadius * cos(aStartAngle);
startPoint.y = aOrigin.y + aRadius * sin(aStartAngle);
if (!mFigureActive) {
EnsureActive(startPoint);
} else {
mSink->AddLine(D2DPoint(startPoint));
}
Point endPoint;
endPoint.x = aOrigin.x + aRadius * cos(aEndAngle);
endPoint.y = aOrigin.y + aRadius * sin(aEndAngle);
D2D1_ARC_SIZE arcSize = D2D1_ARC_SIZE_SMALL;
if (aAntiClockwise) {
if (aStartAngle - aEndAngle > M_PI) {
arcSize = D2D1_ARC_SIZE_LARGE;
}
} else {
if (aEndAngle - aStartAngle > M_PI) {
arcSize = D2D1_ARC_SIZE_LARGE;
}
}
mSink->AddArc(D2D1::ArcSegment(D2DPoint(endPoint),
D2D1::SizeF(aRadius, aRadius),
0.0f,
aAntiClockwise ? D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE :
D2D1_SWEEP_DIRECTION_CLOCKWISE,
arcSize));
mCurrentPoint = endPoint;
}
Point
PathBuilderD2D::CurrentPoint() const
{
return mCurrentPoint;
}
void
PathBuilderD2D::EnsureActive(const Point &aPoint)
{
if (!mFigureActive) {
mSink->BeginFigure(D2DPoint(aPoint), D2D1_FIGURE_BEGIN_FILLED);
mBeginPoint = aPoint;
mFigureActive = true;
}
}
TemporaryRef<Path>
PathBuilderD2D::Finish()
{
if (mFigureActive) {
mSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
HRESULT hr = mSink->Close();
if (FAILED(hr)) {
gfxDebug() << "Failed to close PathSink. Code: " << hr;
return NULL;
}
return new PathD2D(mGeometry, mFigureActive, mCurrentPoint, mFillRule);
}
TemporaryRef<PathBuilder>
PathD2D::CopyToBuilder(FillRule aFillRule) const
{
return TransformedCopyToBuilder(Matrix(), aFillRule);
}
TemporaryRef<PathBuilder>
PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
{
RefPtr<ID2D1PathGeometry> path;
HRESULT hr = DrawTargetD2D::factory()->CreatePathGeometry(byRef(path));
if (FAILED(hr)) {
gfxWarning() << "Failed to create PathGeometry. Code: " << hr;
return NULL;
}
RefPtr<ID2D1GeometrySink> sink;
hr = path->Open(byRef(sink));
if (FAILED(hr)) {
gfxWarning() << "Failed to open Geometry for writing. Code: " << hr;
return NULL;
}
if (aFillRule == FILL_WINDING) {
sink->SetFillMode(D2D1_FILL_MODE_WINDING);
}
if (mEndedActive) {
OpeningGeometrySink wrapSink(sink);
mGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
D2DMatrix(aTransform),
&wrapSink);
} else {
mGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
D2DMatrix(aTransform),
sink);
}
RefPtr<PathBuilderD2D> pathBuilder = new PathBuilderD2D(sink, path, mFillRule);
pathBuilder->mCurrentPoint = aTransform * mEndPoint;
if (mEndedActive) {
pathBuilder->mFigureActive = true;
}
return pathBuilder;
}
bool
PathD2D::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
{
BOOL result;
HRESULT hr = mGeometry->FillContainsPoint(D2DPoint(aPoint), D2DMatrix(aTransform), 0.001f, &result);
if (FAILED(hr)) {
// Log
return false;
}
return !!result;
}
}
}

126
gfx/2d/PathD2D.h Normal file
Просмотреть файл

@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_PATHD2D_H_
#define MOZILLA_GFX_PATHD2D_H_
#include "2D.h"
#include <D2D1.h>
namespace mozilla {
namespace gfx {
class PathD2D;
class PathBuilderD2D : public PathBuilder
{
public:
PathBuilderD2D(ID2D1GeometrySink *aSink, ID2D1PathGeometry *aGeom, FillRule aFillRule)
: mSink(aSink)
, mGeometry(aGeom)
, mFigureActive(false)
, mFillRule(aFillRule)
{
}
virtual ~PathBuilderD2D();
virtual void MoveTo(const Point &aPoint);
virtual void LineTo(const Point &aPoint);
virtual void BezierTo(const Point &aCP1,
const Point &aCP2,
const Point &aCP3);
virtual void QuadraticBezierTo(const Point &aCP1,
const Point &aCP2);
virtual void Close();
virtual void Arc(const Point &aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise = false);
virtual Point CurrentPoint() const;
virtual TemporaryRef<Path> Finish();
ID2D1GeometrySink *GetSink() { return mSink; }
private:
friend class PathD2D;
void EnsureActive(const Point &aPoint);
RefPtr<ID2D1GeometrySink> mSink;
RefPtr<ID2D1PathGeometry> mGeometry;
bool mFigureActive;
Point mCurrentPoint;
Point mBeginPoint;
FillRule mFillRule;
};
class PathD2D : public Path
{
public:
PathD2D(ID2D1PathGeometry *aGeometry, bool aEndedActive,
const Point &aEndPoint, FillRule aFillRule)
: mGeometry(aGeometry)
, mEndedActive(aEndedActive)
, mEndPoint(aEndPoint)
, mFillRule(aFillRule)
{}
virtual BackendType GetBackendType() const { return BACKEND_DIRECT2D; }
virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FILL_WINDING) const;
virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
FillRule aFillRule = FILL_WINDING) const;
virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const;
virtual FillRule GetFillRule() const { return mFillRule; }
ID2D1Geometry *GetGeometry() { return mGeometry; }
private:
friend class DrawTargetD2D;
mutable RefPtr<ID2D1PathGeometry> mGeometry;
bool mEndedActive;
Point mEndPoint;
FillRule mFillRule;
};
}
}
#endif /* MOZILLA_GFX_PATHD2D_H_ */

81
gfx/2d/Point.h Normal file
Просмотреть файл

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_POINT_H_
#define MOZILLA_GFX_POINT_H_
#include "Types.h"
#include "BasePoint.h"
#include "BaseSize.h"
namespace mozilla {
namespace gfx {
struct Point :
public BasePoint<Float, Point> {
typedef BasePoint<Float, Point> Super;
Point() : Super() {}
Point(Float aX, Float aY) : Super(aX, aY) {}
};
struct IntPoint :
public BasePoint<int32_t, Point> {
typedef BasePoint<int32_t, Point> Super;
IntPoint() : Super() {}
IntPoint(int32_t aX, int32_t aY) : Super(aX, aY) {}
};
struct Size :
public BaseSize<Float, Size> {
typedef BaseSize<Float, Size> Super;
Size() : Super() {}
Size(Float aWidth, Float aHeight) : Super(aWidth, aHeight) {}
};
struct IntSize :
public BaseSize<int32_t, IntSize> {
typedef BaseSize<int32_t, IntSize> Super;
IntSize() : Super() {}
IntSize(int32_t aWidth, int32_t aHeight) : Super(aWidth, aHeight) {}
};
}
}
#endif /* MOZILLA_GFX_POINT_H_ */

83
gfx/2d/Rect.h Normal file
Просмотреть файл

@ -0,0 +1,83 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (Sub) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan <robert@ocallahan.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_RECT_H_
#define MOZILLA_GFX_RECT_H_
#include "BaseRect.h"
#include "BaseMargin.h"
#include "Point.h"
namespace mozilla {
namespace gfx {
struct Margin :
public BaseMargin<Float, Margin> {
typedef BaseMargin<Float, Margin> Super;
// Constructors
Margin(const Margin& aMargin) : Super(aMargin) {}
Margin(Float aLeft, Float aTop, Float aRight, Float aBottom)
: Super(aLeft, aTop, aRight, aBottom) {}
};
struct Rect :
public BaseRect<Float, Rect, Point, Size, Margin> {
typedef BaseRect<Float, Rect, Point, mozilla::gfx::Size, Margin> Super;
Rect() : Super() {}
Rect(Point aPos, mozilla::gfx::Size aSize) :
Super(aPos, aSize) {}
Rect(Float _x, Float _y, Float _width, Float _height) :
Super(_x, _y, _width, _height) {}
};
struct IntRect :
public BaseRect<int32_t, IntRect, IntPoint, IntSize, Margin> {
typedef BaseRect<int32_t, IntRect, IntPoint, mozilla::gfx::IntSize, Margin> Super;
IntRect() : Super() {}
IntRect(IntPoint aPos, mozilla::gfx::IntSize aSize) :
Super(aPos, aSize) {}
IntRect(int32_t _x, int32_t _y, int32_t _width, int32_t _height) :
Super(_x, _y, _width, _height) {}
};
}
}
#endif /* MOZILLA_GFX_RECT_H_ */

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

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ScaledFontDWrite.h"
#include "PathD2D.h"
#include <vector>
namespace mozilla {
namespace gfx {
TemporaryRef<Path>
ScaledFontDWrite::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
{
if (aTarget->GetType() != BACKEND_DIRECT2D) {
// For now we only support Direct2D.
return NULL;
}
RefPtr<PathBuilder> pathBuilder = aTarget->CreatePathBuilder();
PathBuilderD2D *pathBuilderD2D =
static_cast<PathBuilderD2D*>(pathBuilder.get());
std::vector<UINT16> indices;
std::vector<FLOAT> advances;
std::vector<DWRITE_GLYPH_OFFSET> offsets;
indices.resize(aBuffer.mNumGlyphs);
advances.resize(aBuffer.mNumGlyphs);
offsets.resize(aBuffer.mNumGlyphs);
memset(&advances.front(), 0, sizeof(FLOAT) * aBuffer.mNumGlyphs);
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
indices[i] = aBuffer.mGlyphs[i].mIndex;
offsets[i].advanceOffset = aBuffer.mGlyphs[i].mPosition.x;
offsets[i].ascenderOffset = -aBuffer.mGlyphs[i].mPosition.y;
}
mFontFace->GetGlyphRunOutline(mSize, &indices.front(), &advances.front(),
&offsets.front(), aBuffer.mNumGlyphs,
FALSE, FALSE, pathBuilderD2D->GetSink());
return pathBuilder->Finish();
}
}
}

69
gfx/2d/ScaledFontDWrite.h Normal file
Просмотреть файл

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_SCALEDFONTDWRITE_H_
#define MOZILLA_GFX_SCALEDFONTDWRITE_H_
#include "2D.h"
#include <dwrite.h>
namespace mozilla {
namespace gfx {
class ScaledFontDWrite : public ScaledFont
{
public:
ScaledFontDWrite(IDWriteFontFace *aFont, Float aSize)
: mFontFace(aFont)
, mSize(aSize)
{}
virtual FontType GetType() const { return FONT_DWRITE; }
virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
private:
friend class DrawTargetD2D;
RefPtr<IDWriteFontFace> mFontFace;
Float mSize;
};
}
}
#endif /* MOZILLA_GFX_SCALEDFONTDWRITE_H_ */

156
gfx/2d/ShadersD2D.fx Normal file
Просмотреть файл

@ -0,0 +1,156 @@
// We store vertex coordinates and the quad shape in a constant buffer, this is
// easy to update and allows us to use a single call to set the x, y, w, h of
// the quad.
// The QuadDesc and TexCoords both work as follows:
// The x component is the quad left point, the y component is the top point
// the z component is the width, and the w component is the height. The quad
// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
// space <0, 1.0f> left to right and top to bottom. The input vertices of the
// shader stage always form a rectangle from {0, 0} - {1, 1}
cbuffer cb0
{
float4 QuadDesc;
float4 TexCoords;
}
cbuffer cb1
{
float4 BlurOffsetsH[3];
float4 BlurOffsetsV[3];
float4 BlurWeights[3];
float4 ShadowColor;
}
struct VS_OUTPUT
{
float4 Position : SV_Position;
float2 TexCoord : TEXCOORD0;
};
Texture2D tex;
sampler sSampler = sampler_state {
Filter = MIN_MAG_MIP_LINEAR;
Texture = tex;
AddressU = Clamp;
AddressV = Clamp;
};
sampler sShadowSampler = sampler_state {
Filter = MIN_MAG_MIP_LINEAR;
Texture = tex;
AddressU = Border;
AddressV = Border;
BorderColor = float4(0, 0, 0, 0);
};
RasterizerState TextureRast
{
ScissorEnable = False;
CullMode = None;
};
BlendState ShadowBlendH
{
BlendEnable[0] = False;
RenderTargetWriteMask[0] = 0xF;
};
BlendState ShadowBlendV
{
BlendEnable[0] = True;
SrcBlend = One;
DestBlend = Inv_Src_Alpha;
BlendOp = Add;
SrcBlendAlpha = One;
DestBlendAlpha = Inv_Src_Alpha;
BlendOpAlpha = Add;
RenderTargetWriteMask[0] = 0xF;
};
VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
{
VS_OUTPUT Output;
Output.Position.w = 1.0f;
Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
Output.Position.z = 0;
Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
return Output;
}
float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
{
return tex.Sample(sSampler, In.TexCoord);
};
float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
{
float outputStrength = 0;
outputStrength += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].x, In.TexCoord.y)).a;
outputStrength += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].y, In.TexCoord.y)).a;
outputStrength += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].z, In.TexCoord.y)).a;
outputStrength += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].w, In.TexCoord.y)).a;
outputStrength += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].x, In.TexCoord.y)).a;
outputStrength += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].y, In.TexCoord.y)).a;
outputStrength += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].z, In.TexCoord.y)).a;
outputStrength += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].w, In.TexCoord.y)).a;
outputStrength += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[2].x, In.TexCoord.y)).a;
return ShadowColor * outputStrength;
};
float4 SampleShadowVPS( VS_OUTPUT In) : SV_Target
{
float4 outputColor = float4(0, 0, 0, 0);
outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));
return outputColor;
};
technique10 SampleTexture
{
pass P0
{
SetRasterizerState(TextureRast);
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
}
}
technique10 SampleTextureWithShadow
{
// Horizontal pass
pass P0
{
SetRasterizerState(TextureRast);
SetBlendState(ShadowBlendH, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowHPS()));
}
// Vertical pass
pass P1
{
SetRasterizerState(TextureRast);
SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowVPS()));
}
}

2411
gfx/2d/ShadersD2D.h Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

156
gfx/2d/SourceSurfaceCG.cpp Normal file
Просмотреть файл

@ -0,0 +1,156 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jeff Muizelaar <jmuizelaar@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "SourceSurfaceCG.h"
namespace mozilla {
namespace gfx {
SourceSurfaceCG::SourceSurfaceCG()
{
}
SourceSurfaceCG::~SourceSurfaceCG()
{
CGImageRelease(mImage);
}
IntSize
SourceSurfaceCG::GetSize() const
{
IntSize size;
size.width = CGImageGetHeight(mImage);
size.height = CGImageGetWidth(mImage);
return size;
}
SurfaceFormat
SourceSurfaceCG::GetFormat() const
{
return mFormat;
}
TemporaryRef<DataSourceSurface>
SourceSurfaceCG::GetDataSurface()
{
return NULL;
}
static void releaseCallback(void *info, const void *data, size_t size) {
free(info);
}
bool
SourceSurfaceCG::InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat)
{
//XXX: we should avoid creating this colorspace everytime
CGColorSpaceRef colorSpace = NULL;
CGBitmapInfo bitinfo = 0;
CGDataProviderRef dataProvider = NULL;
int bitsPerComponent = 0;
int bitsPerPixel = 0;
switch (aFormat) {
case B8G8R8A8:
colorSpace = CGColorSpaceCreateDeviceRGB();
bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
bitsPerComponent = 8;
bitsPerPixel = 32;
break;
case B8G8R8X8:
colorSpace = CGColorSpaceCreateDeviceRGB();
bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
bitsPerComponent = 8;
bitsPerPixel = 32;
break;
case A8:
// XXX: why don't we set a colorspace here?
bitsPerComponent = 8;
bitsPerPixel = 8;
};
void *data = malloc(aStride * aSize.height);
memcpy(aData, data, aStride * aSize.height);
mFormat = aFormat;
dataProvider = CGDataProviderCreateWithData (data,
data,
aSize.height * aStride,
releaseCallback);
if (aFormat == A8) {
CGFloat decode[] = {1.0, 0.0};
mImage = CGImageMaskCreate (aSize.width, aSize.height,
bitsPerComponent,
bitsPerPixel,
aStride,
dataProvider,
decode,
true);
} else {
mImage = CGImageCreate (aSize.width, aSize.height,
bitsPerComponent,
bitsPerPixel,
aStride,
colorSpace,
bitinfo,
dataProvider,
NULL,
true,
kCGRenderingIntentDefault);
}
CGDataProviderRelease(dataProvider);
CGColorSpaceRelease (colorSpace);
if (mImage) {
return false;
}
return true;
}
}
}

75
gfx/2d/SourceSurfaceCG.h Normal file
Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma once
#include <ApplicationServices/ApplicationServices.h>
#include "2D.h"
namespace mozilla {
namespace gfx {
class SourceSurfaceCG : public SourceSurface
{
public:
SourceSurfaceCG();
~SourceSurfaceCG();
virtual SurfaceType GetType() const { return COREGRAPHICS_IMAGE; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual TemporaryRef<DataSourceSurface> GetDataSurface();
CGImageRef GetImage() { return mImage; }
bool InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat);
private:
CGImageRef mImage;
/* It might be better to just use the bitmap info from the CGImageRef to
* deduce the format to save space in SourceSurfaceCG,
* for now we just store it in mFormat */
SurfaceFormat mFormat;
};
}
}

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

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "SourceSurfaceCairo.h"
#include "cairo/cairo.h"
namespace mozilla {
namespace gfx {
SourceSurfaceCairo::SourceSurfaceCairo()
{
}
SourceSurfaceCairo::~SourceSurfaceCairo()
{
cairo_surface_destroy(mSurface);
}
IntSize
SourceSurfaceCairo::GetSize() const
{
return mSize;
}
SurfaceFormat
SourceSurfaceCairo::GetFormat() const
{
return mFormat;
}
TemporaryRef<DataSourceSurface>
SourceSurfaceCairo::GetDataSurface()
{
return NULL;
}
cairo_surface_t*
SourceSurfaceCairo::GetSurface()
{
return mSurface;
}
bool
SourceSurfaceCairo::InitFromSurface(cairo_surface_t* aSurface,
const IntSize& aSize,
const SurfaceFormat& aFormat)
{
mSurface = aSurface;
cairo_surface_reference(mSurface);
mSize = aSize;
mFormat = aFormat;
return true;
}
}
}

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

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H_
#define _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H
#include "2D.h"
namespace mozilla {
namespace gfx {
class SourceSurfaceCairo : public SourceSurface
{
public:
SourceSurfaceCairo();
~SourceSurfaceCairo();
virtual SurfaceType GetType() const { return SURFACE_CAIRO; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual TemporaryRef<DataSourceSurface> GetDataSurface();
cairo_surface_t* GetSurface();
bool InitFromSurface(cairo_surface_t* aSurface,
const IntSize& aSize,
const SurfaceFormat& aFormat);
private:
IntSize mSize;
SurfaceFormat mFormat;
cairo_surface_t* mSurface;
};
}
}
#endif // _MOZILLA_GFX_OP_SOURCESURFACE_CAIRO_H

140
gfx/2d/SourceSurfaceD2D.cpp Normal file
Просмотреть файл

@ -0,0 +1,140 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "SourceSurfaceD2D.h"
#include "Logging.h"
namespace mozilla {
namespace gfx {
SourceSurfaceD2D::SourceSurfaceD2D()
{
}
SourceSurfaceD2D::~SourceSurfaceD2D()
{
}
IntSize
SourceSurfaceD2D::GetSize() const
{
return mSize;
}
SurfaceFormat
SourceSurfaceD2D::GetFormat() const
{
return mFormat;
}
TemporaryRef<DataSourceSurface>
SourceSurfaceD2D::GetDataSurface()
{
return NULL;
}
bool
SourceSurfaceD2D::InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT)
{
HRESULT hr;
mFormat = aFormat;
mSize = aSize;
if ((uint32_t)aSize.width > aRT->GetMaximumBitmapSize() ||
(uint32_t)aSize.height > aRT->GetMaximumBitmapSize()) {
int newStride = BytesPerPixel(aFormat) * aSize.width;
mRawData.resize(aSize.height * newStride);
for (int y = 0; y < aSize.height; y++) {
memcpy(&mRawData.front() + y * newStride, aData + y * aStride, newStride);
}
gfxDebug() << "Bitmap does not fit in texture, saving raw data.";
return true;
}
D2D1_BITMAP_PROPERTIES props =
D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat)));
hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr;
return false;
}
return true;
}
bool
SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT)
{
HRESULT hr;
RefPtr<IDXGISurface> surf;
hr = aTexture->QueryInterface((IDXGISurface**)&surf);
if (FAILED(hr)) {
gfxWarning() << "Failed to QI texture to surface. Code: " << hr;
return false;
}
D3D10_TEXTURE2D_DESC desc;
aTexture->GetDesc(&desc);
mSize = IntSize(desc.Width, desc.Height);
mFormat = aFormat;
D2D1_BITMAP_PROPERTIES props =
D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat)));
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create SharedBitmap. Code: " << hr;
return false;
}
return true;
}
}
}

82
gfx/2d/SourceSurfaceD2D.h Normal file
Просмотреть файл

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_SOURCESURFACED2D_H_
#define MOZILLA_GFX_SOURCESURFACED2D_H_
#include "2D.h"
#include "HelpersD2D.h"
#include <vector>
namespace mozilla {
namespace gfx {
class SourceSurfaceD2D : public SourceSurface
{
public:
SourceSurfaceD2D();
~SourceSurfaceD2D();
virtual SurfaceType GetType() const { return SURFACE_D2D1_BITMAP; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual TemporaryRef<DataSourceSurface> GetDataSurface();
ID2D1Bitmap *GetBitmap() { return mBitmap; }
bool InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT);
bool InitFromTexture(ID3D10Texture2D *aTexture,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT);
private:
friend class DrawTargetD2D;
RefPtr<ID2D1Bitmap> mBitmap;
std::vector<unsigned char> mRawData;
SurfaceFormat mFormat;
IntSize mSize;
};
}
}
#endif /* MOZILLA_GFX_SOURCESURFACED2D_H_ */

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

@ -0,0 +1,237 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "SourceSurfaceD2DTarget.h"
#include "Logging.h"
#include "DrawTargetD2D.h"
#include <algorithm>
namespace mozilla {
namespace gfx {
SourceSurfaceD2DTarget::SourceSurfaceD2DTarget()
: mFormat(FORMAT_B8G8R8A8)
, mIsCopy(false)
{
}
SourceSurfaceD2DTarget::~SourceSurfaceD2DTarget()
{
// Our drawtarget no longer needs to worry about us.
MarkIndependent();
}
IntSize
SourceSurfaceD2DTarget::GetSize() const
{
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
return IntSize(desc.Width, desc.Height);
}
SurfaceFormat
SourceSurfaceD2DTarget::GetFormat() const
{
return mFormat;
}
TemporaryRef<DataSourceSurface>
SourceSurfaceD2DTarget::GetDataSurface()
{
RefPtr<DataSourceSurfaceD2DTarget> dataSurf =
new DataSourceSurfaceD2DTarget();
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
desc.Usage = D3D10_USAGE_STAGING;
desc.BindFlags = 0;
desc.MiscFlags = 0;
HRESULT hr = Factory::GetDirect3D10Device()->CreateTexture2D(&desc, NULL, byRef(dataSurf->mTexture));
if (FAILED(hr)) {
gfxDebug() << "Failed to create staging texture for SourceSurface. Code: " << hr;
return NULL;
}
Factory::GetDirect3D10Device()->CopyResource(dataSurf->mTexture, mTexture);
return dataSurf;
}
ID3D10ShaderResourceView*
SourceSurfaceD2DTarget::GetSRView()
{
if (mSRView) {
return mSRView;
}
HRESULT hr = Factory::GetDirect3D10Device()->CreateShaderResourceView(mTexture, NULL, byRef(mSRView));
if (FAILED(hr)) {
gfxWarning() << "Failed to create ShaderResourceView. Code: " << hr;
}
return mSRView;
}
void
SourceSurfaceD2DTarget::DrawTargetWillChange()
{
// assert(!mIsCopy)
RefPtr<ID3D10Texture2D> oldTexture = mTexture;
// It's important we set this here, that way DrawTargets that we are calling
// flush on will not try to remove themselves from our dependent surfaces.
mIsCopy = true;
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
// Get a copy of the surface data so the content at snapshot time was saved.
Factory::GetDirect3D10Device()->CreateTexture2D(&desc, NULL, byRef(mTexture));
Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture);
mBitmap = NULL;
// We now no longer depend on the source surface content remaining the same.
MarkIndependent();
}
ID2D1Bitmap*
SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
{
if (mBitmap) {
return mBitmap;
}
HRESULT hr;
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
IntSize size(desc.Width, desc.Height);
RefPtr<IDXGISurface> surf;
hr = mTexture->QueryInterface((IDXGISurface**)byRef(surf));
if (FAILED(hr)) {
gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hr;
return NULL;
}
D2D1_BITMAP_PROPERTIES props =
D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(mFormat), AlphaMode(mFormat)));
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create shared bitmap for DrawTarget snapshot. Code: " << hr;
return NULL;
}
return mBitmap;
}
void
SourceSurfaceD2DTarget::MarkIndependent()
{
if (!mIsCopy) {
std::vector<SourceSurfaceD2DTarget*> *snapshots = &mDrawTarget->mSnapshots;
snapshots->erase(std::find(snapshots->begin(), snapshots->end(), this));
}
}
DataSourceSurfaceD2DTarget::DataSourceSurfaceD2DTarget()
: mFormat(FORMAT_B8G8R8A8)
, mMapped(false)
{
}
DataSourceSurfaceD2DTarget::~DataSourceSurfaceD2DTarget()
{
if (mMapped) {
mTexture->Unmap(0);
}
}
IntSize
DataSourceSurfaceD2DTarget::GetSize() const
{
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
return IntSize(desc.Width, desc.Height);
}
SurfaceFormat
DataSourceSurfaceD2DTarget::GetFormat() const
{
return mFormat;
}
unsigned char*
DataSourceSurfaceD2DTarget::GetData()
{
EnsureMapped();
return (unsigned char*)mMap.pData;
}
int32_t
DataSourceSurfaceD2DTarget::Stride()
{
EnsureMapped();
return mMap.RowPitch;
}
void
DataSourceSurfaceD2DTarget::EnsureMapped()
{
if (!mMapped) {
HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
if (FAILED(hr)) {
gfxWarning() << "Failed to map texture to memory. Code: " << hr;
return;
}
mMapped = true;
}
}
}
}

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

@ -0,0 +1,119 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
#define MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
#include "2D.h"
#include "HelpersD2D.h"
#include <vector>
#include <d3d10_1.h>
namespace mozilla {
namespace gfx {
class DrawTargetD2D;
class SourceSurfaceD2DTarget : public SourceSurface
{
public:
SourceSurfaceD2DTarget();
~SourceSurfaceD2DTarget();
virtual SurfaceType GetType() const { return SURFACE_D2D1_DRAWTARGET; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual TemporaryRef<DataSourceSurface> GetDataSurface();
private:
friend class DrawTargetD2D;
ID3D10ShaderResourceView *GetSRView();
// This returns true if this source surface has been copied from its
// drawtarget, in that case changes no longer need to be tracked.
bool IsCopy() { return mIsCopy; }
// This function is called by the draw target this texture belongs to when
// it is about to be changed. The texture will be required to make a copy
// of itself when this happens.
void DrawTargetWillChange();
// This will mark the surface as no longer depending on its drawtarget,
// this may happen on destruction or copying.
void MarkIndependent();
ID2D1Bitmap *GetBitmap(ID2D1RenderTarget *aRT);
RefPtr<ID3D10ShaderResourceView> mSRView;
RefPtr<ID2D1Bitmap> mBitmap;
RefPtr<DrawTargetD2D> mDrawTarget;
mutable RefPtr<ID3D10Texture2D> mTexture;
SurfaceFormat mFormat;
// This is a list of the drawtargets that need to be notified when the
// underlying drawtarget is changed.
std::vector<RefPtr<DrawTargetD2D>> mDependentSurfaces;
bool mIsCopy;
};
class DataSourceSurfaceD2DTarget : public DataSourceSurface
{
public:
DataSourceSurfaceD2DTarget();
~DataSourceSurfaceD2DTarget();
virtual SurfaceType GetType() const { return SURFACE_DATA; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual unsigned char *GetData();
virtual int32_t Stride();
private:
friend class SourceSurfaceD2DTarget;
void EnsureMapped();
mutable RefPtr<ID3D10Texture2D> mTexture;
SurfaceFormat mFormat;
D3D10_MAPPED_TEXTURE2D mMap;
bool mMapped;
};
}
}
#endif /* MOZILLA_GFX_SOURCESURFACED2DTARGET_H_ */

63
gfx/2d/Tools.h Normal file
Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_TOOLS_H_
#define MOZILLA_GFX_TOOLS_H_
#include "Types.h"
namespace mozilla {
namespace gfx {
bool
IsOperatorBoundByMask(CompositionOp aOp) {
switch (aOp) {
case OP_IN:
case OP_OUT:
case OP_DEST_IN:
case OP_DEST_ATOP:
case OP_SOURCE:
return false;
default:
return true;
}
}
}
}
#endif /* MOZILLA_GFX_TOOLS_H_ */

161
gfx/2d/Types.h Normal file
Просмотреть файл

@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_TYPES_H_
#define MOZILLA_GFX_TYPES_H_
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__)
# include <inttypes.h>
#elif defined (_MSC_VER)
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#elif defined (_AIX)
# include <sys/inttypes.h>
#else
# include <stdint.h>
#endif
#include <stddef.h>
namespace mozilla {
namespace gfx {
typedef float Float;
enum SurfaceType
{
SURFACE_DATA, /* Data surface - bitmap in memory */
SURFACE_D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
SURFACE_D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
SURFACE_CAIRO, /* Surface wrapping a cairo surface */
SURFACE_COREGRAPHICS_IMAGE /* Surface wrapping a CoreGraphics Image */
};
enum SurfaceFormat
{
FORMAT_B8G8R8A8,
FORMAT_B8G8R8X8,
FORMAT_A8
};
enum BackendType
{
BACKEND_DIRECT2D,
BACKEND_COREGRAPHICS,
BACKEND_CAIRO
};
enum FontType
{
FONT_DWRITE
};
enum NativeSurfaceType
{
NATIVE_SURFACE_D3D10_TEXTURE
};
enum NativeFontType
{
NATIVE_FONT_DWRITE_FONT_FACE
};
enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
enum ExtendMode { EXTEND_CLAMP, EXTEND_WRAP, EXTEND_MIRROR };
enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
enum Snapping { SNAP_NONE, SNAP_ALIGNED };
enum Filter { FILTER_LINEAR, FILTER_POINT };
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
enum CapStyle { CAP_BUTT, CAP_ROUND, CAP_SQUARE };
struct Color
{
public:
Color()
: r(0.0f), g(0.0f), b(0.0f), a(0.0f)
{}
Color(Float aR, Float aG, Float aB, Float aA)
: r(aR), g(aG), b(aB), a(aA)
{}
Color(Float aR, Float aG, Float aB)
: r(aR), g(aG), b(aB), a(1.0f)
{}
static Color FromABGR(uint32_t aColor)
{
Color newColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
((aColor >> 8) & 0xff) * (1.0f / 255.0f),
((aColor >> 16) & 0xff) * (1.0f / 255.0f),
((aColor >> 24) & 0xff) * (1.0f / 255.0f));
return newColor;
}
Float r, g, b, a;
};
struct GradientStop
{
Float offset;
Color color;
};
}
}
// Side constants for use in various places
namespace mozilla {
namespace css {
enum Side {eSideTop, eSideRight, eSideBottom, eSideLeft};
}
}
// XXX - These don't really belong here. But for now this is where they go.
#define NS_SIDE_TOP mozilla::css::eSideTop
#define NS_SIDE_RIGHT mozilla::css::eSideRight
#define NS_SIDE_BOTTOM mozilla::css::eSideBottom
#define NS_SIDE_LEFT mozilla::css::eSideLeft
#endif /* MOZILLA_GFX_TYPES_H_ */

20
gfx/2d/gfx2d.sln Normal file
Просмотреть файл

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gfx2d", "gfx2d.vcxproj", "{5C80732F-8093-D263-7DD1-7D30B9A76091}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5C80732F-8093-D263-7DD1-7D30B9A76091}.Debug|Win32.ActiveCfg = Debug|Win32
{5C80732F-8093-D263-7DD1-7D30B9A76091}.Debug|Win32.Build.0 = Debug|Win32
{5C80732F-8093-D263-7DD1-7D30B9A76091}.Release|Win32.ActiveCfg = Release|Win32
{5C80732F-8093-D263-7DD1-7D30B9A76091}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

114
gfx/2d/gfx2d.vcxproj Normal file
Просмотреть файл

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<ExecutablePath>$(DXSDK_DIR)\Utilities\bin\x86;$(ExecutablePath)</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_DEBUG;GFX_LOG_WARNING;MFBT_STAND_ALONE;XP_WIN</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>C:\Users\Bas\Dev\gfx-debug\dist\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>
</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="2D.h" />
<ClInclude Include="BaseMargin.h" />
<ClInclude Include="BasePoint.h" />
<ClInclude Include="BaseRect.h" />
<ClInclude Include="BaseSize.h" />
<ClInclude Include="DrawTargetD2D.h" />
<ClInclude Include="GradientStopsD2D.h" />
<ClInclude Include="HelpersD2D.h" />
<ClInclude Include="Logging.h" />
<ClInclude Include="Matrix.h" />
<ClInclude Include="PathD2D.h" />
<ClInclude Include="Point.h" />
<ClInclude Include="Rect.h" />
<ClInclude Include="ScaledFontDWrite.h" />
<ClInclude Include="SourceSurfaceD2D.h" />
<ClInclude Include="SourceSurfaceD2DTarget.h" />
<ClInclude Include="Tools.h" />
<ClInclude Include="Types.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="DrawTargetD2D.cpp" />
<ClCompile Include="Factory.cpp" />
<ClCompile Include="Matrix.cpp" />
<ClCompile Include="PathD2D.cpp" />
<ClCompile Include="ScaledFontDWrite.cpp" />
<ClCompile Include="SourceSurfaceD2D.cpp" />
<ClCompile Include="SourceSurfaceD2DTarget.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.in" />
<CustomBuild Include="ShadersD2D.fx">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">fxc /Tfx_4_0 /FhShadersD2D.h ShadersD2D.fx /Vn d2deffect</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ShadersD2D.h</Outputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

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

@ -48,7 +48,7 @@ ifdef MOZ_TREE_CAIRO
DIRS = cairo DIRS = cairo
endif endif
DIRS += ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc DIRS += 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
ifdef ENABLE_TESTS ifdef ENABLE_TESTS
TOOL_DIRS += tests TOOL_DIRS += tests

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

@ -4603,6 +4603,21 @@ FAIL_CREATE:
return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY)); return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
} }
ID3D10Texture2D*
cairo_d2d_surface_get_texture(cairo_surface_t *surface)
{
if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
return NULL;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
RefPtr<ID3D10Texture2D> texture;
d2dsurf->surface->QueryInterface(&texture);
return texture;
}
void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip) void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip)
{ {
if (surface->type != CAIRO_SURFACE_TYPE_D2D) { if (surface->type != CAIRO_SURFACE_TYPE_D2D) {

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

@ -250,6 +250,11 @@ cairo_d2d_surface_create_for_texture(cairo_device_t *device,
struct ID3D10Texture2D *texture, struct ID3D10Texture2D *texture,
cairo_content_t content); cairo_content_t content);
/**
* Get the ID3D10Texture2D used for a surface.
*/
cairo_public struct ID3D10Texture2D *cairo_d2d_surface_get_texture(cairo_surface_t *surf);
/** /**
* Present the backbuffer for a surface create for an HWND. This needs * Present the backbuffer for a surface create for an HWND. This needs
* to be called when the owner of the original window surface wants to * to be called when the owner of the original window surface wants to

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

@ -48,6 +48,7 @@
#include "mozilla/Util.h" #include "mozilla/Util.h"
using namespace mozilla::layers; using namespace mozilla::layers;
using namespace mozilla::gfx;
typedef FrameMetrics::ViewID ViewID; typedef FrameMetrics::ViewID ViewID;
const ViewID FrameMetrics::NULL_SCROLL_ID = 0; const ViewID FrameMetrics::NULL_SCROLL_ID = 0;
@ -210,6 +211,14 @@ LayerManager::CreateOptimalSurface(const gfxIntSize &aSize,
CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFormat)); CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFormat));
} }
TemporaryRef<DrawTarget>
LayerManager::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)
{
// Right now this doesn't work on the general layer manager.
return NULL;
}
#ifdef DEBUG #ifdef DEBUG
void void
LayerManager::Mutated(Layer* aLayer) LayerManager::Mutated(Layer* aLayer)

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

@ -49,6 +49,8 @@
#include "gfxColor.h" #include "gfxColor.h"
#include "gfxPattern.h" #include "gfxPattern.h"
#include "mozilla/gfx/2D.h"
#if defined(DEBUG) || defined(PR_LOGGING) #if defined(DEBUG) || defined(PR_LOGGING)
# include <stdio.h> // FILE # include <stdio.h> // FILE
# include "prlog.h" # include "prlog.h"
@ -424,6 +426,15 @@ public:
CreateOptimalSurface(const gfxIntSize &aSize, CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat); gfxASurface::gfxImageFormat imageFormat);
/**
* Creates a DrawTarget which is optimized for inter-operating with this
* layermanager.
*/
virtual TemporaryRef<mozilla::gfx::DrawTarget>
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
mozilla::gfx::SurfaceFormat aFormat);
/** /**
* Return the name of the layer manager's backend. * Return the name of the layer manager's backend.
*/ */
@ -1199,13 +1210,14 @@ class THEBES_API CanvasLayer : public Layer {
public: public:
struct Data { struct Data {
Data() Data()
: mSurface(nsnull), mGLContext(nsnull), : mSurface(nsnull), mGLContext(nsnull)
mGLBufferIsPremultiplied(PR_FALSE) , mDrawTarget(nsnull), mGLBufferIsPremultiplied(PR_FALSE)
{ } { }
/* One of these two must be specified, but never both */ /* One of these two must be specified, but never both */
gfxASurface* mSurface; // a gfx Surface for the canvas contents gfxASurface* mSurface; // a gfx Surface for the canvas contents
mozilla::gl::GLContext* mGLContext; // a GL PBuffer Context mozilla::gl::GLContext* mGLContext; // a GL PBuffer Context
mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents
/* The size of the canvas content */ /* The size of the canvas content */
nsIntSize mSize; nsIntSize mSize;

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

@ -41,6 +41,8 @@
#include "mozilla/layers/PLayerChild.h" #include "mozilla/layers/PLayerChild.h"
#include "mozilla/layers/PLayersChild.h" #include "mozilla/layers/PLayersChild.h"
#include "mozilla/layers/PLayersParent.h" #include "mozilla/layers/PLayersParent.h"
#include "mozilla/gfx/2D.h"
#include "ipc/ShadowLayerChild.h" #include "ipc/ShadowLayerChild.h"
#include "BasicLayers.h" #include "BasicLayers.h"
@ -1020,6 +1022,8 @@ protected:
nsRefPtr<gfxASurface> mSurface; nsRefPtr<gfxASurface> mSurface;
nsRefPtr<mozilla::gl::GLContext> mGLContext; nsRefPtr<mozilla::gl::GLContext> mGLContext;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
PRUint32 mCanvasFramebuffer; PRUint32 mCanvasFramebuffer;
PRPackedBool mGLBufferIsPremultiplied; PRPackedBool mGLBufferIsPremultiplied;
@ -1042,8 +1046,12 @@ BasicCanvasLayer::Initialize(const Data& aData)
mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied; mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
mCanvasFramebuffer = mGLContext->GetOffscreenFBO(); mCanvasFramebuffer = mGLContext->GetOffscreenFBO();
mNeedsYFlip = PR_TRUE; mNeedsYFlip = PR_TRUE;
} else if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
mNeedsYFlip = PR_FALSE;
} else { } else {
NS_ERROR("CanvasLayer created without mSurface or mGLContext?"); NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
} }
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
@ -1052,6 +1060,10 @@ BasicCanvasLayer::Initialize(const Data& aData)
void void
BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface) BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface)
{ {
if (mDrawTarget) {
mDrawTarget->Flush();
}
if (!mGLContext && aDestSurface) { if (!mGLContext && aDestSurface) {
nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface); nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE); tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);

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

@ -42,6 +42,8 @@
#include "gfxWindowsSurface.h" #include "gfxWindowsSurface.h"
#include "gfxWindowsPlatform.h" #include "gfxWindowsPlatform.h"
using namespace mozilla::gfx;
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -56,8 +58,8 @@ CanvasLayerD3D10::Initialize(const Data& aData)
if (aData.mSurface) { if (aData.mSurface) {
mSurface = aData.mSurface; mSurface = aData.mSurface;
NS_ASSERTION(aData.mGLContext == nsnull, NS_ASSERTION(aData.mGLContext == nsnull && !aData.mDrawTarget,
"CanvasLayer can't have both surface and GLContext"); "CanvasLayer can't have both surface and GLContext/DrawTarget");
mNeedsYFlip = PR_FALSE; mNeedsYFlip = PR_FALSE;
mDataIsPremultiplied = PR_TRUE; mDataIsPremultiplied = PR_TRUE;
} else if (aData.mGLContext) { } else if (aData.mGLContext) {
@ -66,8 +68,29 @@ CanvasLayerD3D10::Initialize(const Data& aData)
mCanvasFramebuffer = mGLContext->GetOffscreenFBO(); mCanvasFramebuffer = mGLContext->GetOffscreenFBO();
mDataIsPremultiplied = aData.mGLBufferIsPremultiplied; mDataIsPremultiplied = aData.mGLBufferIsPremultiplied;
mNeedsYFlip = PR_TRUE; mNeedsYFlip = PR_TRUE;
} else if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
void *texture = mDrawTarget->GetNativeSurface(NATIVE_SURFACE_D3D10_TEXTURE);
if (!texture) {
// XXX - Once we have non-D2D drawtargets we should do something more sensible here.
NS_WARNING("Failed to get D3D10 texture from DrawTarget.");
return;
}
mTexture = static_cast<ID3D10Texture2D*>(texture);
NS_ASSERTION(aData.mGLContext == nsnull && aData.mSurface == nsnull,
"CanvasLayer can't have both surface and GLContext/Surface");
mNeedsYFlip = PR_FALSE;
mDataIsPremultiplied = PR_TRUE;
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(mSRView));
return;
} else { } else {
NS_ERROR("CanvasLayer created without mSurface or mGLContext?"); NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
} }
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
@ -116,6 +139,11 @@ CanvasLayerD3D10::UpdateSurface()
return; return;
mDirty = PR_FALSE; mDirty = PR_FALSE;
if (mDrawTarget) {
mDrawTarget->Flush();
return;
}
if (mIsD2DTexture) { if (mIsD2DTexture) {
mSurface->Flush(); mSurface->Flush();
return; return;

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

@ -75,6 +75,7 @@ private:
void UpdateSurface(); void UpdateSurface();
nsRefPtr<gfxASurface> mSurface; nsRefPtr<gfxASurface> mSurface;
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
nsRefPtr<GLContext> mGLContext; nsRefPtr<GLContext> mGLContext;
nsRefPtr<ID3D10Texture2D> mTexture; nsRefPtr<ID3D10Texture2D> mTexture;
nsRefPtr<ID3D10ShaderResourceView> mSRView; nsRefPtr<ID3D10ShaderResourceView> mSRView;

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

@ -54,6 +54,8 @@
#include "gfxCrashReporterUtils.h" #include "gfxCrashReporterUtils.h"
using namespace mozilla::gfx;
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -427,6 +429,38 @@ LayerManagerD3D10::CreateOptimalSurface(const gfxIntSize &aSize,
return surface.forget(); return surface.forget();
} }
TemporaryRef<DrawTarget>
LayerManagerD3D10::CreateDrawTarget(const IntSize &aSize,
SurfaceFormat aFormat)
{
if ((aFormat != FORMAT_B8G8R8A8 &&
aFormat != FORMAT_B8G8R8X8)) {
return LayerManager::CreateDrawTarget(aSize, aFormat);
}
nsRefPtr<ID3D10Texture2D> texture;
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(texture));
if (FAILED(hr)) {
NS_WARNING("Failed to create new texture for CreateOptimalSurface!");
return LayerManager::CreateDrawTarget(aSize, aFormat);
}
RefPtr<DrawTarget> surface =
Factory::CreateDrawTargetForD3D10Texture(texture, aFormat);
if (!surface) {
return LayerManager::CreateDrawTarget(aSize, aFormat);
}
return surface;
}
ReadbackManagerD3D10* ReadbackManagerD3D10*
LayerManagerD3D10::readbackManager() LayerManagerD3D10::readbackManager()
{ {

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

@ -133,6 +133,10 @@ public:
CreateOptimalSurface(const gfxIntSize &aSize, CreateOptimalSurface(const gfxIntSize &aSize,
gfxASurface::gfxImageFormat imageFormat); gfxASurface::gfxImageFormat imageFormat);
virtual TemporaryRef<mozilla::gfx::DrawTarget>
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
mozilla::gfx::SurfaceFormat aFormat);
virtual LayersBackend GetBackendType() { return LAYERS_D3D10; } virtual LayersBackend GetBackendType() { return LAYERS_D3D10; }
virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); } virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Direct3D 10"); }

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

@ -58,16 +58,7 @@ XPIDLSRCS = \
gfxIFormats.idl \ gfxIFormats.idl \
gfxidltypes.idl \ gfxidltypes.idl \
$(NULL) $(NULL)
EXPORTS_NAMESPACES = mozilla
EXPORTS_mozilla = \
BaseMargin.h \
BasePoint.h \
BaseRect.h \
BaseSize.h \
$(NULL)
EXPORTS = \ EXPORTS = \
gfxCore.h \ gfxCore.h \
gfxCrashReporterUtils.h \ gfxCrashReporterUtils.h \
@ -93,6 +84,8 @@ EXPORTS = \
$(NULL) $(NULL)
ifdef MOZ_X11 ifdef MOZ_X11
EXPORTS_NAMESPACES = mozilla
EXPORTS_mozilla += X11Util.h EXPORTS_mozilla += X11Util.h
endif endif

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

@ -40,16 +40,6 @@
#include "nscore.h" #include "nscore.h"
// Side constants for use in various places
namespace mozilla {
namespace css {
enum Side {eSideTop, eSideRight, eSideBottom, eSideLeft};
}
}
#define NS_SIDE_TOP mozilla::css::eSideTop
#define NS_SIDE_RIGHT mozilla::css::eSideRight
#define NS_SIDE_BOTTOM mozilla::css::eSideBottom
#define NS_SIDE_LEFT mozilla::css::eSideLeft
#define NS_GFX #define NS_GFX
#define NS_GFX_(type) type #define NS_GFX_(type) type
#define NS_GFX_STATIC_MEMBER_(type) type #define NS_GFX_STATIC_MEMBER_(type) type

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

@ -41,10 +41,10 @@
#include "nsCoord.h" #include "nsCoord.h"
#include "nsPoint.h" #include "nsPoint.h"
#include "gfxCore.h" #include "gfxCore.h"
#include "mozilla/BaseMargin.h" #include "mozilla/gfx/BaseMargin.h"
struct nsMargin : public mozilla::BaseMargin<nscoord, nsMargin> { struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
typedef mozilla::BaseMargin<nscoord, nsMargin> Super; typedef mozilla::gfx::BaseMargin<nscoord, nsMargin> Super;
// Constructors // Constructors
nsMargin() : Super() {} nsMargin() : Super() {}
@ -53,8 +53,8 @@ struct nsMargin : public mozilla::BaseMargin<nscoord, nsMargin> {
: Super(aLeft, aTop, aRight, aBottom) {} : Super(aLeft, aTop, aRight, aBottom) {}
}; };
struct nsIntMargin : public mozilla::BaseMargin<PRInt32, nsIntMargin> { struct nsIntMargin : public mozilla::gfx::BaseMargin<PRInt32, nsIntMargin> {
typedef mozilla::BaseMargin<PRInt32, nsIntMargin> Super; typedef mozilla::gfx::BaseMargin<PRInt32, nsIntMargin> Super;
// Constructors // Constructors
nsIntMargin() : Super() {} nsIntMargin() : Super() {}

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

@ -39,14 +39,14 @@
#define NSPOINT_H #define NSPOINT_H
#include "nsCoord.h" #include "nsCoord.h"
#include "mozilla/BaseSize.h" #include "mozilla/gfx/BaseSize.h"
#include "mozilla/BasePoint.h" #include "mozilla/gfx/BasePoint.h"
#include "nsSize.h" #include "nsSize.h"
struct nsIntPoint; struct nsIntPoint;
struct nsPoint : public mozilla::BasePoint<nscoord, nsPoint> { struct nsPoint : public mozilla::gfx::BasePoint<nscoord, nsPoint> {
typedef mozilla::BasePoint<nscoord, nsPoint> Super; typedef mozilla::gfx::BasePoint<nscoord, nsPoint> Super;
nsPoint() : Super() {} nsPoint() : Super() {}
nsPoint(const nsPoint& aPoint) : Super(aPoint) {} nsPoint(const nsPoint& aPoint) : Super(aPoint) {}
@ -60,8 +60,8 @@ struct nsPoint : public mozilla::BasePoint<nscoord, nsPoint> {
inline nsPoint ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const; inline nsPoint ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
}; };
struct nsIntPoint : public mozilla::BasePoint<PRInt32, nsIntPoint> { struct nsIntPoint : public mozilla::gfx::BasePoint<PRInt32, nsIntPoint> {
typedef mozilla::BasePoint<PRInt32, nsIntPoint> Super; typedef mozilla::gfx::BasePoint<PRInt32, nsIntPoint> Super;
nsIntPoint() : Super() {} nsIntPoint() : Super() {}
nsIntPoint(const nsIntPoint& aPoint) : Super(aPoint) {} nsIntPoint(const nsIntPoint& aPoint) : Super(aPoint) {}

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

@ -46,13 +46,13 @@
#include "nsMargin.h" #include "nsMargin.h"
#include "gfxCore.h" #include "gfxCore.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "mozilla/BaseRect.h" #include "mozilla/gfx/BaseRect.h"
struct nsIntRect; struct nsIntRect;
struct NS_GFX nsRect : struct NS_GFX nsRect :
public mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> { public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
typedef mozilla::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super; typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); } static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); }
@ -103,8 +103,8 @@ struct NS_GFX nsRect :
}; };
struct NS_GFX nsIntRect : struct NS_GFX nsIntRect :
public mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> { public mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
typedef mozilla::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super; typedef mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
// Constructors // Constructors
nsIntRect() : Super() nsIntRect() : Super()

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

@ -39,15 +39,15 @@
#define NSSIZE_H #define NSSIZE_H
#include "nsCoord.h" #include "nsCoord.h"
#include "mozilla/BaseSize.h" #include "mozilla/gfx/BaseSize.h"
// Maximum allowable size // Maximum allowable size
#define NS_MAXSIZE nscoord_MAX #define NS_MAXSIZE nscoord_MAX
struct nsIntSize; struct nsIntSize;
struct nsSize : public mozilla::BaseSize<nscoord, nsSize> { struct nsSize : public mozilla::gfx::BaseSize<nscoord, nsSize> {
typedef mozilla::BaseSize<nscoord, nsSize> Super; typedef mozilla::gfx::BaseSize<nscoord, nsSize> Super;
nsSize() : Super() {} nsSize() : Super() {}
nsSize(nscoord aWidth, nscoord aHeight) : Super(aWidth, aHeight) {} nsSize(nscoord aWidth, nscoord aHeight) : Super(aWidth, aHeight) {}
@ -59,8 +59,8 @@ struct nsSize : public mozilla::BaseSize<nscoord, nsSize> {
inline nsSize ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const; inline nsSize ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
}; };
struct nsIntSize : public mozilla::BaseSize<PRInt32, nsIntSize> { struct nsIntSize : public mozilla::gfx::BaseSize<PRInt32, nsIntSize> {
typedef mozilla::BaseSize<PRInt32, nsIntSize> Super; typedef mozilla::gfx::BaseSize<PRInt32, nsIntSize> Super;
nsIntSize() : Super() {} nsIntSize() : Super() {}
nsIntSize(PRInt32 aWidth, PRInt32 aHeight) : Super(aWidth, aHeight) {} nsIntSize(PRInt32 aWidth, PRInt32 aHeight) : Super(aWidth, aHeight) {}

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

@ -12,6 +12,7 @@ LIBXUL_LIBRARY = 1
EXPORT_LIBRARY = 1 EXPORT_LIBRARY = 1
EXPORTS = \ EXPORTS = \
gfx2DGlue.h \
gfx3DMatrix.h \ gfx3DMatrix.h \
gfxASurface.h \ gfxASurface.h \
gfxAlphaRecovery.h \ gfxAlphaRecovery.h \

40
gfx/thebes/gfx2DGlue.h Normal file
Просмотреть файл

@ -0,0 +1,40 @@
#include "gfxRect.h"
#include "mozilla/gfx/Rect.h"
namespace mozilla {
namespace gfx {
class DrawTarget;
class SourceSurface;
class ScaledFont;
}
}
namespace mozilla {
namespace gfx {
inline Rect ToRect(const gfxRect &aRect)
{
return Rect(Float(aRect.x), Float(aRect.y),
Float(aRect.width), Float(aRect.height));
}
inline gfxRect GFXRect(const Rect &aRect)
{
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
}
inline gfxASurface::gfxContentType ContentForFormat(const SurfaceFormat &aFormat)
{
switch (aFormat) {
case FORMAT_B8G8R8X8:
return gfxASurface::CONTENT_COLOR;
case FORMAT_A8:
return gfxASurface::CONTENT_ALPHA;
default:
return gfxASurface::CONTENT_COLOR_ALPHA;
}
}
}
}

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

@ -71,10 +71,18 @@ gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
: gfxFontShaper(aFont) : gfxFontShaper(aFont)
{ {
// Create our CTFontRef // Create our CTFontRef
mCTFont = ::CTFontCreateWithPlatformFont(aFont->GetATSFontRef(), if (gfxMacPlatformFontList::UseATSFontEntry()) {
aFont->GetAdjustedSize(), ATSFontEntry *fe = static_cast<ATSFontEntry*>(aFont->GetFontEntry());
NULL, mCTFont = ::CTFontCreateWithPlatformFont(fe->GetATSFontRef(),
GetDefaultFeaturesDescriptor()); aFont->GetAdjustedSize(),
NULL,
GetDefaultFeaturesDescriptor());
} else {
mCTFont = ::CTFontCreateWithGraphicsFont(aFont->GetCGFontRef(),
aFont->GetAdjustedSize(),
NULL,
GetDefaultFeaturesDescriptor());
}
// Set up the default attribute dictionary that we will need each time we create a CFAttributedString // Set up the default attribute dictionary that we will need each time we create a CFAttributedString
mAttributesDict = ::CFDictionaryCreate(kCFAllocatorDefault, mAttributesDict = ::CFDictionaryCreate(kCFAllocatorDefault,
@ -161,10 +169,8 @@ gfxCoreTextShaper::InitTextRun(gfxContext *aContext,
if (disableLigatures) { if (disableLigatures) {
// For letterspacing (or maybe other situations) we need to make a copy of the CTFont // For letterspacing (or maybe other situations) we need to make a copy of the CTFont
// with the ligature feature disabled // with the ligature feature disabled
gfxMacFont *font = static_cast<gfxMacFont*>(mFont);
CTFontRef ctFont = CTFontRef ctFont =
CreateCTFontWithDisabledLigatures(font->GetATSFontRef(), CreateCTFontWithDisabledLigatures(::CTFontGetSize(mCTFont));
::CTFontGetSize(mCTFont));
attrObj = attrObj =
::CFDictionaryCreate(kCFAllocatorDefault, ::CFDictionaryCreate(kCFAllocatorDefault,
@ -595,9 +601,9 @@ gfxCoreTextShaper::CreateDefaultFeaturesDescriptor()
::CFRelease(attributesDict); ::CFRelease(attributesDict);
} }
// Create a CTFontRef, with the Common Ligatures feature disabled [static] // Create a CTFontRef, with the Common Ligatures feature disabled
CTFontRef CTFontRef
gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize) gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(CGFloat aSize)
{ {
if (sDisableLigaturesDescriptor == NULL) { if (sDisableLigaturesDescriptor == NULL) {
// initialize cached descriptor to turn off the Common Ligatures feature // initialize cached descriptor to turn off the Common Ligatures feature
@ -643,11 +649,20 @@ gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloa
::CFRelease(featuresArray); ::CFRelease(featuresArray);
sDisableLigaturesDescriptor = sDisableLigaturesDescriptor =
::CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(), attributesDict); ::CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(),
attributesDict);
::CFRelease(attributesDict); ::CFRelease(attributesDict);
} }
return ::CTFontCreateWithPlatformFont(aFontRef, aSize, NULL, sDisableLigaturesDescriptor); if (gfxMacPlatformFontList::UseATSFontEntry()) {
ATSFontEntry *fe = static_cast<ATSFontEntry*>(mFont->GetFontEntry());
return ::CTFontCreateWithPlatformFont(fe->GetATSFontRef(), aSize, NULL,
sDisableLigaturesDescriptor);
}
gfxMacFont *f = static_cast<gfxMacFont*>(mFont);
return ::CTFontCreateWithGraphicsFont(f->GetCGFontRef(), aSize, NULL,
sDisableLigaturesDescriptor);
} }
void void

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

@ -77,6 +77,8 @@ protected:
PRInt32 aLayoutStart, PRInt32 aLayoutStart,
PRInt32 aLayoutLength); PRInt32 aLayoutLength);
CTFontRef CreateCTFontWithDisabledLigatures(CGFloat aSize);
static void CreateDefaultFeaturesDescriptor(); static void CreateDefaultFeaturesDescriptor();
static CTFontDescriptorRef GetDefaultFeaturesDescriptor() { static CTFontDescriptorRef GetDefaultFeaturesDescriptor() {
@ -86,8 +88,6 @@ protected:
return sDefaultFeaturesDescriptor; return sDefaultFeaturesDescriptor;
} }
static CTFontRef CreateCTFontWithDisabledLigatures(ATSFontRef aFontRef, CGFloat aSize);
// cached font descriptor, created the first time it's needed // cached font descriptor, created the first time it's needed
static CTFontDescriptorRef sDefaultFeaturesDescriptor; static CTFontDescriptorRef sDefaultFeaturesDescriptor;

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

@ -97,6 +97,12 @@ gfxD2DSurface::Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip)
cairo_d2d_scroll(CairoSurface(), aDelta.x, aDelta.y, &rect); cairo_d2d_scroll(CairoSurface(), aDelta.x, aDelta.y, &rect);
} }
ID3D10Texture2D*
gfxD2DSurface::GetTexture()
{
return cairo_d2d_surface_get_texture(CairoSurface());
}
HDC HDC
gfxD2DSurface::GetDC(PRBool aRetainContents) gfxD2DSurface::GetDC(PRBool aRetainContents)
{ {

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

@ -70,6 +70,8 @@ public:
void Present(); void Present();
void Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip); void Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip);
ID3D10Texture2D *GetTexture();
HDC GetDC(PRBool aRetainContents); HDC GetDC(PRBool aRetainContents);
void ReleaseDC(const nsIntRect *aUpdatedRect); void ReleaseDC(const nsIntRect *aUpdatedRect);
}; };

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

@ -53,7 +53,6 @@ using namespace mozilla;
gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle, gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
PRBool aNeedsBold) PRBool aNeedsBold)
: gfxFont(aFontEntry, aFontStyle), : gfxFont(aFontEntry, aFontStyle),
mATSFont(aFontEntry->GetFontRef()),
mCGFont(nsnull), mCGFont(nsnull),
mFontFace(nsnull), mFontFace(nsnull),
mScaledFont(nsnull) mScaledFont(nsnull)
@ -62,7 +61,7 @@ gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyl
mSyntheticBoldOffset = 1; // devunit offset when double-striking text to fake boldness mSyntheticBoldOffset = 1; // devunit offset when double-striking text to fake boldness
} }
mCGFont = ::CGFontCreateWithPlatformFont(&mATSFont); mCGFont = aFontEntry->GetFontRef();
if (!mCGFont) { if (!mCGFont) {
mIsValid = PR_FALSE; mIsValid = PR_FALSE;
return; return;
@ -148,9 +147,6 @@ gfxMacFont::~gfxMacFont()
if (mFontFace) { if (mFontFace) {
cairo_font_face_destroy(mFontFace); cairo_font_face_destroy(mFontFace);
} }
// this is documented to be safe if mCGFont is null
::CGFontRelease(mCGFont);
} }
PRBool PRBool
@ -267,7 +263,7 @@ gfxMacFont::InitMetrics()
// platform APIs. The InitMetrics...() functions will set mIsValid on success. // platform APIs. The InitMetrics...() functions will set mIsValid on success.
if (!InitMetricsFromSfntTables(mMetrics) && if (!InitMetricsFromSfntTables(mMetrics) &&
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) { (!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
InitMetricsFromATSMetrics(); InitMetricsFromPlatform();
} }
if (!mIsValid) { if (!mIsValid) {
return; return;
@ -291,7 +287,7 @@ gfxMacFont::InitMetrics()
mMetrics.xHeight = 0.0; mMetrics.xHeight = 0.0;
if (!InitMetricsFromSfntTables(mMetrics) && if (!InitMetricsFromSfntTables(mMetrics) &&
(!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) { (!mFontEntry->IsUserFont() || mFontEntry->IsLocalUserFont())) {
InitMetricsFromATSMetrics(); InitMetricsFromPlatform();
} }
if (!mIsValid) { if (!mIsValid) {
// this shouldn't happen, as we succeeded earlier before applying // this shouldn't happen, as we succeeded earlier before applying
@ -415,19 +411,65 @@ gfxMacFont::GetFontTable(PRUint32 aTag)
return nsnull; return nsnull;
} }
// Try to initialize font metrics via ATS font metrics APIs, // Try to initialize font metrics via platform APIs (CG/CT),
// and set mIsValid = TRUE on success. // and set mIsValid = TRUE on success.
// We ONLY call this for local (platform) fonts that are not sfnt format; // We ONLY call this for local (platform) fonts that are not sfnt format;
// for sfnts, including ALL downloadable fonts, use InitMetricsFromSfntTables // for sfnts, including ALL downloadable fonts, we prefer to use
// because ATSFontGetHorizontalMetrics() has been known to crash when // InitMetricsFromSfntTables and avoid platform APIs.
// presented with bad fonts.
void void
gfxMacFont::InitMetricsFromATSMetrics() gfxMacFont::InitMetricsFromPlatform()
{
if (gfxMacPlatformFontList::UseATSFontEntry()) {
ATSFontEntry *fe = static_cast<ATSFontEntry*>(GetFontEntry());
InitMetricsFromATSMetrics(fe->GetATSFontRef());
return;
}
CTFontRef ctFont = ::CTFontCreateWithGraphicsFont(mCGFont,
mAdjustedSize,
NULL, NULL);
if (!ctFont) {
return;
}
mMetrics.underlineOffset = ::CTFontGetUnderlinePosition(ctFont);
mMetrics.underlineSize = ::CTFontGetUnderlineThickness(ctFont);
mMetrics.externalLeading = ::CTFontGetLeading(ctFont);
mMetrics.maxAscent = ::CTFontGetAscent(ctFont);
mMetrics.maxDescent = ::CTFontGetDescent(ctFont);
// this is not strictly correct, but neither CTFont nor CGFont seems to
// provide maxAdvance, unless we were to iterate over all the glyphs
// (which isn't worth the cost here)
CGRect r = ::CTFontGetBoundingBox(ctFont);
mMetrics.maxAdvance = r.size.width;
// aveCharWidth is also not provided, so leave it at zero
// (fallback code in gfxMacFont::InitMetrics will then try measuring 'x');
// this could lead to less-than-"perfect" text field sizing when width is
// specified as a number of characters, and the font in use is a non-sfnt
// legacy font, but that's a sufficiently obscure edge case that we can
// ignore the potential discrepancy.
mMetrics.aveCharWidth = 0;
mMetrics.xHeight = ::CTFontGetXHeight(ctFont);
::CFRelease(ctFont);
mIsValid = PR_TRUE;
}
// For OS X 10.5, try to initialize font metrics via ATS font metrics APIs,
// and set mIsValid = TRUE on success.
void
gfxMacFont::InitMetricsFromATSMetrics(ATSFontRef aFontRef)
{ {
ATSFontMetrics atsMetrics; ATSFontMetrics atsMetrics;
OSStatus err; OSStatus err;
err = ::ATSFontGetHorizontalMetrics(mATSFont, kATSOptionFlagsDefault, err = ::ATSFontGetHorizontalMetrics(aFontRef, kATSOptionFlagsDefault,
&atsMetrics); &atsMetrics);
if (err != noErr) { if (err != noErr) {
#ifdef DEBUG #ifdef DEBUG

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

@ -54,7 +54,6 @@ public:
virtual ~gfxMacFont(); virtual ~gfxMacFont();
ATSFontRef GetATSFontRef() const { return mATSFont; }
CGFontRef GetCGFontRef() const { return mCGFont; } CGFontRef GetCGFontRef() const { return mCGFont; }
/* overrides for the pure virtual methods in gfxFont */ /* overrides for the pure virtual methods in gfxFont */
@ -92,7 +91,8 @@ protected:
PRBool aPreferPlatformShaping = PR_FALSE); PRBool aPreferPlatformShaping = PR_FALSE);
void InitMetrics(); void InitMetrics();
void InitMetricsFromATSMetrics(); void InitMetricsFromPlatform();
void InitMetricsFromATSMetrics(ATSFontRef aFontRef);
// Get width and glyph ID for a character; uses aConvFactor // Get width and glyph ID for a character; uses aConvFactor
// to convert font units as returned by CG to actual dimensions // to convert font units as returned by CG to actual dimensions
@ -101,7 +101,8 @@ protected:
static void DestroyBlobFunc(void* aUserData); static void DestroyBlobFunc(void* aUserData);
ATSFontRef mATSFont; // a weak reference to the CoreGraphics font: this is owned by the
// MacOSFontEntry, it is not retained or released by gfxMacFont
CGFontRef mCGFont; CGFontRef mCGFont;
cairo_font_face_t *mFontFace; cairo_font_face_t *mFontFace;

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

@ -46,6 +46,7 @@
#include "gfxPlatformFontList.h" #include "gfxPlatformFontList.h"
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include "gfxPlatformMac.h"
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
@ -60,33 +61,83 @@ class MacOSFontEntry : public gfxFontEntry
public: public:
friend class gfxMacPlatformFontList; friend class gfxMacPlatformFontList;
MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight, virtual ~MacOSFontEntry() {
gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE); ::CGFontRelease(mFontRef);
}
virtual CGFontRef GetFontRef() = 0;
virtual nsresult GetFontTable(PRUint32 aTableTag,
FallibleTArray<PRUint8>& aBuffer) = 0;
ATSFontRef GetFontRef();
nsresult ReadCMAP(); nsresult ReadCMAP();
PRBool RequiresAATLayout() const { return mRequiresAAT; } PRBool RequiresAATLayout() const { return mRequiresAAT; }
virtual nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
PRBool IsCFF(); PRBool IsCFF();
protected: protected:
// for use with data fonts MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef, gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
gfxUserFontData *aUserFontData);
virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold); virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
ATSFontRef mATSFontRef; virtual PRBool HasFontTable(PRUint32 aTableTag) = 0;
PRPackedBool mATSFontRefInitialized;
CGFontRef mFontRef; // owning reference to the CGFont, released on destruction
PRPackedBool mFontRefInitialized;
PRPackedBool mRequiresAAT; PRPackedBool mRequiresAAT;
PRPackedBool mIsCFF; PRPackedBool mIsCFF;
PRPackedBool mIsCFFInitialized; PRPackedBool mIsCFFInitialized;
}; };
// concrete subclasses of MacOSFontEntry: ATSFontEntry for 10.5, CGFontEntry for 10.6+
class ATSFontEntry : public MacOSFontEntry
{
public:
ATSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
// for use with data fonts
ATSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
gfxUserFontData *aUserFontData, PRBool aIsLocal);
ATSFontRef GetATSFontRef();
virtual CGFontRef GetFontRef();
virtual nsresult GetFontTable(PRUint32 aTableTag,
FallibleTArray<PRUint8>& aBuffer);
protected:
virtual PRBool HasFontTable(PRUint32 aTableTag);
ATSFontRef mATSFontRef;
PRPackedBool mATSFontRefInitialized;
};
class CGFontEntry : public MacOSFontEntry
{
public:
CGFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
// for use with data fonts
CGFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef,
PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
PRBool aIsUserFont, PRBool aIsLocal);
virtual CGFontRef GetFontRef();
virtual nsresult GetFontTable(PRUint32 aTableTag,
FallibleTArray<PRUint8>& aBuffer);
protected:
virtual PRBool HasFontTable(PRUint32 aTableTag);
};
class gfxMacPlatformFontList : public gfxPlatformFontList { class gfxMacPlatformFontList : public gfxPlatformFontList {
public: public:
static gfxMacPlatformFontList* PlatformFontList() { static gfxMacPlatformFontList* PlatformFontList() {
@ -107,6 +158,10 @@ public:
void ClearPrefFonts() { mPrefFonts.Clear(); } void ClearPrefFonts() { mPrefFonts.Clear(); }
static PRBool UseATSFontEntry() {
return gfxPlatformMac::GetPlatform()->OSXVersion() < MAC_OS_X_VERSION_10_6_HEX;
}
private: private:
friend class gfxPlatformMac; friend class gfxPlatformMac;
@ -118,8 +173,11 @@ private:
// special case font faces treated as font families (set via prefs) // special case font faces treated as font families (set via prefs)
void InitSingleFaceList(); void InitSingleFaceList();
// eliminate faces which have the same ATS font reference gfxFontEntry* MakePlatformFontCG(const gfxProxyFontEntry *aProxyEntry,
void EliminateDuplicateFaces(const nsAString& aFamilyName); const PRUint8 *aFontData, PRUint32 aLength);
gfxFontEntry* MakePlatformFontATS(const gfxProxyFontEntry *aProxyEntry,
const PRUint8 *aFontData, PRUint32 aLength);
static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg); static void ATSNotification(ATSFontNotificationInfoRef aInfo, void* aUserArg);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше