mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
Merge places to mozilla-central.
This commit is contained in:
commit
099fb925dc
@ -115,9 +115,9 @@ nsHTMLImageAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
imageRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (imgContainer) {
|
||||
PRUint32 numFrames;
|
||||
imgContainer->GetNumFrames(&numFrames);
|
||||
if (numFrames > 1)
|
||||
PRBool animated;
|
||||
imgContainer->GetAnimated(&animated);
|
||||
if (animated)
|
||||
*aState |= nsIAccessibleStates::STATE_ANIMATED;
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,8 @@ pref("browser.tabs.closeButtons", 1);
|
||||
// false return to the adjacent tab (old default)
|
||||
pref("browser.tabs.selectOwnerOnClose", true);
|
||||
|
||||
pref("browser.ctrlTab.previews", true);
|
||||
pref("browser.allTabs.previews", false);
|
||||
pref("browser.ctrlTab.previews", false);
|
||||
pref("browser.ctrlTab.recentlyUsedLimit", 7);
|
||||
|
||||
// Default bookmark sorting
|
||||
|
@ -441,6 +441,12 @@
|
||||
type="checkbox"
|
||||
command="View:FullScreen"/>
|
||||
#endif
|
||||
<menuitem id="menu_showAllTabs"
|
||||
hidden="true"
|
||||
accesskey="&showAllTabsCmd.accesskey;"
|
||||
label="&showAllTabsCmd.label;"
|
||||
command="Browser:ShowAllTabs"
|
||||
key="key_showAllTabs"/>
|
||||
<menuseparator hidden="true" id="documentDirection-separator"/>
|
||||
<menuitem id="documentDirection-swap"
|
||||
hidden="true"
|
||||
|
@ -115,6 +115,7 @@
|
||||
</command>
|
||||
<command id="Browser:NextTab" oncommand="gBrowser.mTabContainer.advanceSelectedTab(1, true);"/>
|
||||
<command id="Browser:PrevTab" oncommand="gBrowser.mTabContainer.advanceSelectedTab(-1, true);"/>
|
||||
<command id="Browser:ShowAllTabs" oncommand="allTabs.open();"/>
|
||||
<command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
|
||||
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
|
||||
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
|
||||
@ -317,7 +318,9 @@
|
||||
<key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
|
||||
<key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
|
||||
<key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/>
|
||||
|
||||
|
||||
<key id="key_showAllTabs" command="Browser:ShowAllTabs" keycode="VK_TAB" modifiers="control,shift"/>
|
||||
|
||||
<key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />
|
||||
|
||||
<key id="key_privatebrowsing" command="Tools:PrivateBrowsing" key="&privateBrowsingCmd.commandkey;" modifiers="accel,shift"/>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,21 +41,49 @@
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
<binding id="ctrlTab-thumbnail">
|
||||
<content align="center">
|
||||
<children/>
|
||||
<xul:label xbl:inherits="value=label,crop"/>
|
||||
<binding id="ctrlTab-preview" extends="chrome://global/content/bindings/button.xml#button-base">
|
||||
<content pack="center">
|
||||
<xul:stack>
|
||||
<xul:vbox class="ctrlTab-preview-inner" align="center" pack="center"
|
||||
xbl:inherits="width=canvaswidth">
|
||||
<xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
<xul:label xbl:inherits="value=label,crop" class="plain"/>
|
||||
</xul:vbox>
|
||||
<xul:hbox class="ctrlTab-favicon-container" xbl:inherits="hidden=noicon">
|
||||
<xul:image class="ctrlTab-favicon" xbl:inherits="src=image"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</content>
|
||||
<handlers>
|
||||
<handler event="click" button="0" action="ctrlTab.selectThumbnail(this);"/>
|
||||
<handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/>
|
||||
<handler event="mouseover" action="ctrlTab._mouseOverFocus(this);"/>
|
||||
<handler event="command" action="ctrlTab.pick(this);"/>
|
||||
<handler event="click" button="1" action="ctrlTab.remove(this);"/>
|
||||
#ifdef XP_MACOSX
|
||||
# Control+click is a right click on OS X
|
||||
<handler event="click" button="2"><![CDATA[
|
||||
if (!ctrlTab.sticky)
|
||||
ctrlTab.selectThumbnail(this);
|
||||
]]></handler>
|
||||
<handler event="click" button="2" action="ctrlTab.pick(this);"/>
|
||||
#endif
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
<binding id="allTabs-preview" extends="chrome://global/content/bindings/button.xml#button-base">
|
||||
<content pack="center" align="center">
|
||||
<xul:stack>
|
||||
<xul:vbox class="allTabs-preview-inner" align="center" pack="center">
|
||||
<xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle">
|
||||
<children/>
|
||||
</xul:hbox>
|
||||
<xul:label flex="1" xbl:inherits="value=label,crop" class="allTabs-preview-label plain"/>
|
||||
</xul:vbox>
|
||||
<xul:hbox class="allTabs-favicon-container">
|
||||
<xul:image class="allTabs-favicon" xbl:inherits="src=image"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</content>
|
||||
<handlers>
|
||||
<handler event="command" action="allTabs.pick(this);"/>
|
||||
<handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
@ -123,24 +123,46 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
/* Tab Previews */
|
||||
#ctrlTab-panel {
|
||||
-moz-user-focus: normal;
|
||||
/* ::::: Keyboard UI Panel ::::: */
|
||||
.KUI-panel-closebutton {
|
||||
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail {
|
||||
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-thumbnail");
|
||||
.ctrlTab-preview > html|canvas,
|
||||
.allTabs-preview > html|canvas {
|
||||
min-width: inherit;
|
||||
max-width: inherit;
|
||||
min-height: inherit;
|
||||
max-height: inherit;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail:not([valid]) {
|
||||
visibility: hidden;
|
||||
.ctrlTab-favicon-container,
|
||||
.allTabs-favicon-container {
|
||||
-moz-box-align: start;
|
||||
-moz-box-pack: start;
|
||||
}
|
||||
|
||||
#ctrlTab-pages {
|
||||
.ctrlTab-favicon,
|
||||
.allTabs-favicon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab Panel ::::: */
|
||||
.ctrlTab-preview {
|
||||
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-preview");
|
||||
}
|
||||
|
||||
/* ::::: All Tabs Panel ::::: */
|
||||
.allTabs-preview {
|
||||
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#allTabs-preview");
|
||||
}
|
||||
|
||||
#allTabs-tab-close-button {
|
||||
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#allTabs-container {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -1058,6 +1058,8 @@ function BrowserStartup() {
|
||||
gURLBar.setAttribute("enablehistory", "false");
|
||||
}
|
||||
|
||||
allTabs.readPref();
|
||||
|
||||
setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar);
|
||||
}
|
||||
|
||||
@ -1318,7 +1320,9 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
gBrowser.addEventListener("command", BrowserOnCommand, false);
|
||||
|
||||
tabPreviews.init();
|
||||
ctrlTab.init();
|
||||
ctrlTab.readPref();
|
||||
gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
|
||||
gPrefService.addObserver(allTabs.prefName, allTabs, false);
|
||||
|
||||
// Initialize the microsummary service by retrieving it, prompting its factory
|
||||
// to create its singleton, whose constructor initializes the service.
|
||||
@ -1371,6 +1375,7 @@ function BrowserShutdown()
|
||||
{
|
||||
tabPreviews.uninit();
|
||||
ctrlTab.uninit();
|
||||
allTabs.uninit();
|
||||
|
||||
gGestureSupport.init(false);
|
||||
|
||||
|
@ -242,30 +242,44 @@
|
||||
<label crop="center" flex="1" class="tooltip-label"/>
|
||||
</tooltip>
|
||||
|
||||
<panel id="ctrlTab-panel" class="KUI-panel" hidden="true" norestorefocus="true" ignorekeys="true">
|
||||
<panel id="ctrlTab-panel" class="KUI-panel" hidden="true" norestorefocus="true" level="top">
|
||||
<hbox>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
<button class="ctrlTab-preview" flex="1"/>
|
||||
</hbox>
|
||||
<hbox pack="center">
|
||||
<textbox id="ctrlTab-search"
|
||||
<button id="ctrlTab-showAll" class="ctrlTab-preview" noicon="true"/>
|
||||
</hbox>
|
||||
</panel>
|
||||
|
||||
<panel id="allTabs-panel" hidden="true" norestorefocus="true" ignorekeys="true"
|
||||
# XXX: KUI style disabled, because the transparent background slows down
|
||||
# interacting with the panel, esp. the search field.
|
||||
# class="KUI-panel"
|
||||
onmouseover="allTabs._updateTabCloseButton(event);">
|
||||
<hbox id="allTabs-meta" align="center">
|
||||
<spacer flex="1"/>
|
||||
<textbox id="allTabs-filter"
|
||||
tooltiptext="&allTabs.filter.emptyText;"
|
||||
type="search"
|
||||
emptytext="&ctrlTab.search.emptyText;"
|
||||
oncommand="ctrlTab.search();"
|
||||
onfocus="ctrlTab.sticky = true;"/>
|
||||
oncommand="allTabs.filter();"/>
|
||||
<spacer flex="1"/>
|
||||
<toolbarbutton class="KUI-panel-closebutton"
|
||||
oncommand="allTabs.close()"
|
||||
tooltiptext="&closeCmd.label;"/>
|
||||
</hbox>
|
||||
<hbox class="ctrlTab-row">
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
<vbox class="ctrlTab-thumbnail"/>
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
</hbox>
|
||||
<hbox class="ctrlTab-row">
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
<vbox class="ctrlTab-thumbnail"/>
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
</hbox>
|
||||
<hbox class="ctrlTab-row">
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
<vbox class="ctrlTab-thumbnail"/>
|
||||
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox>
|
||||
</hbox>
|
||||
<hbox id="ctrlTab-pages"/>
|
||||
<stack id="allTabs-stack">
|
||||
<box id="allTabs-container"/>
|
||||
<toolbarbutton id="allTabs-tab-close-button"
|
||||
class="tab-close-button"
|
||||
oncommand="allTabs.closeTab(event);"
|
||||
tooltiptext="&closeCmd.label;"
|
||||
style="visibility:hidden"/>
|
||||
</stack>
|
||||
</panel>
|
||||
</popupset>
|
||||
|
||||
|
@ -2879,8 +2879,11 @@
|
||||
<xul:stack align="center" pack="end" chromedir="&locale.dir;">
|
||||
<xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
|
||||
<xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
|
||||
tooltiptext="&listAllTabs.label;"
|
||||
oncommand="ctrlTab.open(true);"/>
|
||||
type="menu"
|
||||
tooltiptext="&listAllTabs.label;">
|
||||
<xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
|
||||
position="after_end"/>
|
||||
</xul:toolbarbutton>
|
||||
</xul:stack>
|
||||
<xul:toolbarbutton anonid="tabs-closebutton"
|
||||
class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
|
||||
@ -3293,25 +3296,6 @@
|
||||
<binding id="tabbrowser-alltabs-popup"
|
||||
extends="chrome://global/content/bindings/popup.xml#popup">
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<field name="_xulWindow">
|
||||
null
|
||||
</field>
|
||||
|
||||
<constructor><![CDATA[
|
||||
// We cannot cache the XULBrowserWindow object itself since it might
|
||||
// be set after this binding is constructed.
|
||||
try {
|
||||
this._xulWindow =
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.treeOwner
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIXULWindow);
|
||||
}
|
||||
catch(ex) { }
|
||||
]]></constructor>
|
||||
|
||||
<method name="_menuItemOnCommand">
|
||||
<parameter name="aEvent"/>
|
||||
|
||||
@ -3471,9 +3455,6 @@
|
||||
|
||||
<handler event="DOMMenuItemActive">
|
||||
<![CDATA[
|
||||
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow)
|
||||
return;
|
||||
|
||||
var tab = event.target.tab;
|
||||
if (tab) {
|
||||
var statusText = tab.linkedBrowser.currentURI.spec;
|
||||
@ -3484,16 +3465,13 @@
|
||||
statusText = " ";
|
||||
}
|
||||
|
||||
this._xulWindow.XULBrowserWindow.setOverLink(statusText, null);
|
||||
XULBrowserWindow.setOverLink(statusText, null);
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="DOMMenuItemInactive">
|
||||
<![CDATA[
|
||||
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow)
|
||||
return;
|
||||
|
||||
this._xulWindow.XULBrowserWindow.setOverLink("", null);
|
||||
XULBrowserWindow.setOverLink("", null);
|
||||
]]></handler>
|
||||
|
||||
</handlers>
|
||||
|
@ -1,5 +1,5 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gPrefService.setBoolPref("browser.ctrlTab.previews", true);
|
||||
|
||||
gBrowser.addTab();
|
||||
gBrowser.addTab();
|
||||
@ -9,7 +9,7 @@ function test() {
|
||||
|
||||
ctrlTabTest([2] , 1, 0);
|
||||
ctrlTabTest([2, 3, 1], 2, 2);
|
||||
ctrlTabTest([] , 4, 2);
|
||||
ctrlTabTest([] , 5, 2);
|
||||
|
||||
{
|
||||
let selectedIndex = gBrowser.tabContainer.selectedIndex;
|
||||
@ -27,9 +27,12 @@ function test() {
|
||||
is(gBrowser.mTabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab");
|
||||
releaseCtrl();
|
||||
}
|
||||
assertTabs(3);
|
||||
|
||||
ctrlTabTest([2, 1, 0], 7, 1);
|
||||
assertTabs(3);
|
||||
ctrlTabTest([2, 1, 0], 9, 1);
|
||||
|
||||
gBrowser.addTab();
|
||||
assertTabs(4);
|
||||
|
||||
{ // test for bug 445369
|
||||
selectTabs([1, 2, 0]);
|
||||
@ -49,12 +52,12 @@ function test() {
|
||||
ok(gBrowser.selectedTab == selectedTab,
|
||||
"Ctrl+Tab*2 -> Ctrl+W -> Ctrl+Shift+Tab*2 keeps the selected tab");
|
||||
}
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
assertTabs(2);
|
||||
|
||||
ctrlTabTest([1], 1, 0);
|
||||
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
|
||||
assertTabs(1);
|
||||
|
||||
{ // test for bug 445768
|
||||
@ -71,65 +74,8 @@ function test() {
|
||||
"Ctrl+Tab doesn't change focus if one tab is open");
|
||||
}
|
||||
|
||||
gBrowser.addTab();
|
||||
gBrowser.addTab();
|
||||
gBrowser.addTab();
|
||||
|
||||
assertTabs(4);
|
||||
selectTabs([0, 1, 2, 3]);
|
||||
pressCtrlTab();
|
||||
ctrlTab.panel.addEventListener("popupshown", stickyTests, false);
|
||||
|
||||
function stickyTests() {
|
||||
ctrlTab.panel.removeEventListener("popupshown", stickyTests, false);
|
||||
|
||||
EventUtils.synthesizeKey("f", { ctrlKey: true });
|
||||
is(document.activeElement, ctrlTab.searchField.inputField,
|
||||
"Ctrl+Tab -> Ctrl+F focuses the panel's search field");
|
||||
|
||||
releaseCtrl();
|
||||
ok(isOpen(),
|
||||
"panel is sticky after focusing the search field and releasing the Ctrl key");
|
||||
|
||||
EventUtils.synthesizeKey("f", {});
|
||||
EventUtils.synthesizeKey("o", {});
|
||||
EventUtils.synthesizeKey("o", {});
|
||||
is(ctrlTab.searchField.value, "foo",
|
||||
"text entered into search field");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
ok(isOpen(),
|
||||
"Enter key kicks pending search off; the panel stays open as there's no match");
|
||||
is(ctrlTab.searchField.value, "foo",
|
||||
"search field value persists after Enter pressed");
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
is(ctrlTab.searchField.value, "",
|
||||
"ESC key clears the search field");
|
||||
ok(isOpen(),
|
||||
"Clearing the search field with ESC keeps the panel open");
|
||||
|
||||
// blur the search field
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
isnot(document.activeElement, ctrlTab.searchField.inputField,
|
||||
"Tab key blurs the panel's search field");
|
||||
|
||||
// advance selection and close panel
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
ok(!isOpen(),
|
||||
"Enter key closes the panel");
|
||||
is(gBrowser.tabContainer.selectedIndex, 1,
|
||||
"Tab key advances the selection while the panel is sticky");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeCurrentTab();
|
||||
assertTabs(1);
|
||||
finish();
|
||||
}
|
||||
|
||||
// cleanup
|
||||
gPrefService.clearUserPref("browser.ctrlTab.previews");
|
||||
|
||||
/* private utility functions */
|
||||
|
||||
@ -140,7 +86,7 @@ function test() {
|
||||
EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
|
||||
|
||||
function isOpen()
|
||||
ctrlTab.panel.state == "showing" || ctrlTab.panel.state == "open";
|
||||
ctrlTab.isOpen;
|
||||
|
||||
function assertTabs(aTabs) {
|
||||
var tabs = gBrowser.mTabs.length;
|
||||
|
@ -91,4 +91,12 @@ EXTRA_DSO_LDOPTS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifndef MOZ_ENABLE_LIBXUL
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
# Doesn't work, couldn't figure out why
|
||||
#EXTRA_DSO_LIBS += thebes
|
||||
EXTRA_DSO_LDOPTS += $(LIBXUL_DIST)/lib/$(LIB_PREFIX)thebes.$(LIB_SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nsIGConfService.h"
|
||||
#include "nsIGnomeVFSService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIProcess.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -55,7 +54,6 @@
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsIImage.h"
|
||||
#include "prprf.h"
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
#include "nsIImageToPixbuf.h"
|
||||
@ -349,12 +347,8 @@ nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
|
||||
}
|
||||
|
||||
static nsresult
|
||||
WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
|
||||
WriteImage(const nsCString& aPath, imgIContainer* aImage)
|
||||
{
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(aImage));
|
||||
if (!img)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
#ifndef MOZ_WIDGET_GTK2
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#else
|
||||
@ -363,7 +357,7 @@ WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
|
||||
if (!imgToPixbuf)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(img);
|
||||
GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage);
|
||||
if (!pixbuf)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
@ -379,8 +373,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
PRInt32 aPosition)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<gfxIImageFrame> gfxFrame;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
|
||||
if (!imageContent) return rv;
|
||||
|
||||
@ -393,12 +385,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
rv = request->GetImage(getter_AddRefs(container));
|
||||
if (!container) return rv;
|
||||
|
||||
// get the current frame, which holds the image data
|
||||
container->GetCurrentFrame(getter_AddRefs(gfxFrame));
|
||||
|
||||
if (!gfxFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Write the background file to the home directory.
|
||||
nsCAutoString filePath(PR_GetEnv("HOME"));
|
||||
|
||||
@ -423,7 +409,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
filePath.Append("_wallpaper.png");
|
||||
|
||||
// write the image to a file in the home dir
|
||||
rv = WriteImage(filePath, gfxFrame);
|
||||
rv = WriteImage(filePath, container);
|
||||
|
||||
// if the file was written successfully, set it as the system wallpaper
|
||||
nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
|
||||
|
@ -41,7 +41,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
@ -519,23 +518,18 @@ nsWindowsShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
|
||||
}
|
||||
|
||||
static nsresult
|
||||
WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
||||
WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
|
||||
{
|
||||
PRInt32 width, height;
|
||||
aImage->GetWidth(&width);
|
||||
aImage->GetHeight(&height);
|
||||
nsRefPtr<gfxImageSurface> image;
|
||||
nsresult rv = aImage->CopyCurrentFrame(getter_AddRefs(image));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint8* bits;
|
||||
PRUint32 length;
|
||||
aImage->LockImageData();
|
||||
aImage->GetImageData(&bits, &length);
|
||||
if (!bits) {
|
||||
aImage->UnlockImageData();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PRInt32 width = image->Width();
|
||||
PRInt32 height = image->Height();
|
||||
|
||||
PRUint32 bpr;
|
||||
aImage->GetImageBytesPerRow(&bpr);
|
||||
PRUint8* bits = image->Data();
|
||||
PRUint32 length = image->GetDataSize();
|
||||
PRUint32 bpr = PRUint32(image->Stride());
|
||||
PRInt32 bitCount = bpr/width;
|
||||
|
||||
// initialize these bitmap structs which we will later
|
||||
@ -562,7 +556,7 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
||||
|
||||
// get a file output stream
|
||||
nsCOMPtr<nsIOutputStream> stream;
|
||||
nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// write the bitmap headers and rgb pixel data to the file
|
||||
@ -592,7 +586,6 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
||||
stream->Close();
|
||||
}
|
||||
|
||||
aImage->UnlockImageData();
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -602,8 +595,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> gfxFrame;
|
||||
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> imgElement(do_QueryInterface(aElement));
|
||||
if (!imgElement) {
|
||||
// XXX write background loading stuff!
|
||||
@ -620,18 +612,11 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
getter_AddRefs(request));
|
||||
if (!request)
|
||||
return rv;
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
rv = request->GetImage(getter_AddRefs(container));
|
||||
if (!container)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the current frame, which holds the image data
|
||||
container->GetCurrentFrame(getter_AddRefs(gfxFrame));
|
||||
}
|
||||
|
||||
if (!gfxFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the file name from localized strings
|
||||
nsCOMPtr<nsIStringBundleService>
|
||||
bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||
@ -664,7 +649,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// write the bitmap to a file in the profile directory
|
||||
rv = WriteBitmap(file, gfxFrame);
|
||||
rv = WriteBitmap(file, container);
|
||||
|
||||
// if the file was written successfully, set it as the system wallpaper
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -50,6 +50,8 @@
|
||||
<!ENTITY pageInfoCmd.commandkey "i">
|
||||
<!ENTITY fullScreenCmd.label "Full Screen">
|
||||
<!ENTITY fullScreenCmd.accesskey "F">
|
||||
<!ENTITY showAllTabsCmd.label "Show All Tabs">
|
||||
<!ENTITY showAllTabsCmd.accesskey "A">
|
||||
|
||||
<!ENTITY fullScreenMinimize.tooltip "Minimize">
|
||||
<!ENTITY fullScreenRestore.tooltip "Restore">
|
||||
@ -444,4 +446,4 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
||||
|
||||
<!ENTITY downloadMonitor2.tooltip "Click to open downloads window">
|
||||
|
||||
<!ENTITY ctrlTab.search.emptyText "Search Tabs">
|
||||
<!ENTITY allTabs.filter.emptyText "Search Tabs">
|
||||
|
@ -209,6 +209,12 @@ privateBrowsingYesTitle=&Start Private Browsing
|
||||
privateBrowsingNoTitle=&Cancel
|
||||
privateBrowsingNeverAsk=&Do not show this message again
|
||||
|
||||
# Ctrl-Tab
|
||||
# LOCALIZATION NOTE (ctrlTab.showAll.label): #1 represents the number
|
||||
# of tabs in the current browser window. It will always be 2 at least.
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
ctrlTab.showAll.label=;Show all #1 tabs
|
||||
|
||||
# LOCALIZATION NOTE (addKeywordTitleAutoFill): %S will be replaced by the page's title
|
||||
# Used as the bookmark name when saving a keyword for a search field.
|
||||
addKeywordTitleAutoFill=Search %S
|
||||
|
BIN
browser/themes/gnomestripe/browser/KUI-close.png
Normal file
BIN
browser/themes/gnomestripe/browser/KUI-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 393 B |
@ -1377,42 +1377,91 @@ toolbar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
|
||||
-moz-image-region: rect(0px 16px 16px 0px);
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab Panel ::::: */
|
||||
|
||||
/* ::::: Keyboard UI Panel ::::: */
|
||||
|
||||
.KUI-panel-closebutton {
|
||||
list-style-image: url(KUI-close.png);
|
||||
}
|
||||
|
||||
.KUI-panel-closebutton > .toolbarbutton-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
|
||||
|
||||
.ctrlTab-preview,
|
||||
.allTabs-preview {
|
||||
-moz-appearance: toolbarbutton;
|
||||
}
|
||||
|
||||
.tabPreview-canvas {
|
||||
-moz-box-shadow: 0 0 5px ThreeDShadow;
|
||||
}
|
||||
|
||||
.ctrlTab-preview:focus .tabPreview-canvas,
|
||||
.ctrlTab-preview:hover .tabPreview-canvas,
|
||||
.allTabs-preview:focus .tabPreview-canvas,
|
||||
.allTabs-preview:hover .tabPreview-canvas {
|
||||
-moz-box-shadow: none;
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src],
|
||||
.allTabs-favicon[src] {
|
||||
background-color: white;
|
||||
padding: 2px;
|
||||
/* XXX: Upscaling images is ugly on Linux (bug 422179)
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
opacity: .7;
|
||||
*/
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
/* Ctrl-Tab */
|
||||
|
||||
#ctrlTab-panel {
|
||||
padding-top: 15px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#ctrlTab-search {
|
||||
margin: 0 0 15px;
|
||||
.ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail {
|
||||
margin-bottom: 15px;
|
||||
cursor: pointer;
|
||||
#ctrlTab-showAll {
|
||||
-moz-appearance: button;
|
||||
color: ButtonText;
|
||||
padding: 0 3px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail > html|canvas {
|
||||
border: 1px solid ThreeDShadow;
|
||||
margin: -1px;
|
||||
/* All Tabs */
|
||||
|
||||
#allTabs-panel {
|
||||
/* compensate for the widget border and padding to center the panel correctly */
|
||||
margin-left: -13px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail[selected="true"] ,
|
||||
.ctrlTab-thumbnail:hover {
|
||||
background: Highlight;
|
||||
color: HighlightText;
|
||||
-moz-box-shadow: 0 0 2px Highlight, 0 0 2px Highlight, 0 0 3px Highlight, 0 0 4px Highlight, 0 0 10px Highlight, 0 0 15px Highlight;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer {
|
||||
margin: 0 1em 1em;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
-moz-border-radius: .75em;
|
||||
background: ThreeDShadow;
|
||||
cursor: pointer;
|
||||
#allTabs-tab-close-button {
|
||||
/*XXX without this, the closebutton can cause the panel to expand horizontally */
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer[selected="true"] {
|
||||
background: ThreeDDarkShadow;
|
||||
cursor: default;
|
||||
#allTabs-meta {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#allTabs-filter {
|
||||
-moz-margin-start: 36px;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
#allTabs-stack {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.allTabs-preview-label {
|
||||
-moz-transform: translate(0, -1px);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ classic.jar:
|
||||
skin/classic/browser/Go-arrow.png
|
||||
skin/classic/browser/identity.png
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
* skin/classic/browser/pageInfo.css
|
||||
|
BIN
browser/themes/pinstripe/browser/KUI-close.png
Normal file
BIN
browser/themes/pinstripe/browser/KUI-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 393 B |
@ -924,8 +924,9 @@ statusbarpanel#statusbar-display {
|
||||
.ac-result-type-keyword,
|
||||
.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
|
||||
list-style-image: url(chrome://global/skin/icons/search-textbox.png);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 2px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
richlistitem[selected="true"][current="true"] > hbox > .ac-result-type-bookmark,
|
||||
@ -1515,7 +1516,7 @@ tabbrowser > tabbox {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.tab-text {
|
||||
.tabbrowser-tab > .tab-text {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 0;
|
||||
font: message-box;
|
||||
@ -2124,63 +2125,143 @@ tabpanels.plain {
|
||||
}
|
||||
|
||||
/* ::::: Keyboard UI Panel ::::: */
|
||||
|
||||
.KUI-panel {
|
||||
-moz-appearance: none;
|
||||
background: rgba(68, 68, 68, .9) url(KUI-background.png) repeat-x;
|
||||
background: rgba(27%,27%,27%,.9) url(KUI-background.png) repeat-x;
|
||||
color: white;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
-moz-border-radius: 10px;
|
||||
margin-top: -1px;
|
||||
margin-left: -1px;
|
||||
border: 1px solid rgba(100%,100%,100%,.15);
|
||||
-moz-border-radius: 20px;
|
||||
}
|
||||
|
||||
.KUI-panel[level="top"] ,
|
||||
#ctrlTab-panel:not([sticky]) {
|
||||
background-color: rgba(68, 68, 68, .5);
|
||||
.KUI-panel[level="top"] {
|
||||
background-color: rgba(27%,27%,27%,.65);
|
||||
border-style: none;
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab Panel ::::: */
|
||||
.KUI-panel-closebutton {
|
||||
list-style-image: url(KUI-close.png);
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.KUI-panel-closebutton:not(:hover) {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.KUI-panel-closebutton > .toolbarbutton-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
|
||||
|
||||
.tabPreview-canvas {
|
||||
-moz-box-shadow: 1px 1px 3px rgb(12%,12%,12%);
|
||||
}
|
||||
|
||||
.ctrlTab-favicon-container,
|
||||
.allTabs-favicon-container {
|
||||
-moz-box-pack: end;
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src],
|
||||
.allTabs-favicon[src] {
|
||||
background-color: white;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 2px;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
/* Ctrl-Tab */
|
||||
|
||||
#ctrlTab-panel {
|
||||
padding-top: 20px;
|
||||
padding: 20px 10px 15px;
|
||||
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 3px rgb(27%,27%,27%);
|
||||
}
|
||||
|
||||
.ctrlTab-preview:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.ctrlTab-preview:focus:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
|
||||
background-color: #ccc;
|
||||
color: black;
|
||||
text-shadow: 0 0 1px white;
|
||||
-moz-box-shadow: 0 0 0 1px rgba(255,255,255,.5), 0 0 5px 1px -moz-mac-focusring, 0 0 8px white;
|
||||
padding: 2px;
|
||||
margin: -2px -2px 0;
|
||||
}
|
||||
|
||||
.ctrlTab-preview:focus .tabPreview-canvas {
|
||||
-moz-box-shadow: none;
|
||||
}
|
||||
|
||||
#ctrlTab-showAll {
|
||||
-moz-appearance: button;
|
||||
color: ButtonText;
|
||||
text-shadow: none;
|
||||
padding: 0 3px;
|
||||
margin-top: 15px;
|
||||
font-size: 1.2em;
|
||||
text-shadow: 0 0 3px black, 0 0 3px black;
|
||||
}
|
||||
|
||||
#ctrlTab-search {
|
||||
margin: 0 0 20px;
|
||||
#ctrlTab-showAll:focus {
|
||||
-moz-box-shadow: 0 0 8px white;
|
||||
-moz-border-radius: 100%;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
/* All Tabs */
|
||||
|
||||
#allTabs-panel {
|
||||
padding: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail > html|canvas {
|
||||
border: 2px solid white;
|
||||
margin: -2px;
|
||||
#allTabs-panel:not(.KUI-panel) {
|
||||
-moz-appearance: none;
|
||||
background: rgb(27%,27%,27%) url(KUI-background.png) repeat-x;
|
||||
border: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail[selected="true"] ,
|
||||
.ctrlTab-thumbnail:hover {
|
||||
background: Highlight;
|
||||
color: HighlightText;
|
||||
-moz-box-shadow: 0 0 2px Highlight, 0 0 2px Highlight, 0 0 3px Highlight, 0 0 4px Highlight, 0 0 10px Highlight, 0 0 20px white;
|
||||
text-shadow: 0 0 3px transparent;
|
||||
#allTabs-meta {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer {
|
||||
margin: 0 1em 1em;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
-moz-border-radius: .75em;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
border: 1px solid rgba(255, 255, 255, .3);
|
||||
cursor: pointer;
|
||||
#allTabs-filter {
|
||||
-moz-margin-start: 24px;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer[selected="true"] {
|
||||
background: rgba(255, 255, 255, .6);
|
||||
cursor: default;
|
||||
#allTabs-tab-close-button {
|
||||
/*XXX without this, the closebutton can cause the panel to expand horizontally */
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
#allTabs-tab-close-button > .toolbarbutton-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.allTabs-preview:hover,
|
||||
.allTabs-preview[closebuttonhover] {
|
||||
background-color: rgba(100%,100%,100%,.15);
|
||||
-moz-border-radius: 6px;
|
||||
}
|
||||
|
||||
.allTabs-preview:focus {
|
||||
background-color: rgba(100%,100%,100%,.3);
|
||||
-moz-border-radius: 6px;
|
||||
}
|
||||
|
||||
.allTabs-preview-label {
|
||||
-moz-transform: translate(0, -1px);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ classic.jar:
|
||||
skin/classic/browser/identity.png
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/KUI-background.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
skin/classic/browser/menu-back.png
|
||||
skin/classic/browser/menu-forward.png
|
||||
skin/classic/browser/page-livemarks.png
|
||||
|
@ -160,8 +160,9 @@ tabpanels {
|
||||
}
|
||||
|
||||
caption {
|
||||
border-bottom: 1px solid #ECECEC;
|
||||
padding: 4px 4px 0px 0px !important;
|
||||
-moz-padding-start: 5px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
#paneMain description,
|
||||
|
BIN
browser/themes/winstripe/browser/KUI-close.png
Normal file
BIN
browser/themes/winstripe/browser/KUI-close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 393 B |
@ -63,17 +63,29 @@
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/*XXX Bug 473152 - Aero Glass clips panel content
|
||||
#allTabs-panel:-moz-system-metric(windows-compositor),*/
|
||||
#ctrlTab-panel:-moz-system-metric(windows-compositor) {
|
||||
background: transparent;
|
||||
-moz-appearance: -moz-win-glass;
|
||||
-moz-border-radius: 0;
|
||||
border: none;
|
||||
font: "Segoe UI", window;
|
||||
font-weight: normal;
|
||||
font: normal 1.2em "Segoe UI";
|
||||
color: black;
|
||||
text-shadow: white -1px -1px .5em, white -1px 1px .5em, white 1px 1px .5em, white 1px -1px .5em;
|
||||
}
|
||||
|
||||
/*XXX Bug 473152 - Aero Glass clips panel content
|
||||
.allTabs-preview:hover:-moz-system-metric(windows-compositor),
|
||||
.allTabs-preview[closebuttonhover]:-moz-system-metric(windows-compositor) {
|
||||
background: rgba(0,0,0,.15) url(KUI-background.png) repeat-x;
|
||||
}
|
||||
|
||||
.allTabs-preview:focus:-moz-system-metric(windows-compositor) {
|
||||
background: rgba(0,0,0,.3) url(KUI-background.png) repeat-x;
|
||||
}
|
||||
*/
|
||||
|
||||
/* ::::: fullscreen window controls ::::: */
|
||||
|
||||
#window-controls {
|
||||
|
@ -1390,7 +1390,7 @@ tabpanels {
|
||||
}
|
||||
|
||||
/* tabbrowser-tab focus ring */
|
||||
.tab-text {
|
||||
.tabbrowser-tab > .tab-text {
|
||||
border: 1px dotted transparent;
|
||||
}
|
||||
|
||||
@ -2022,63 +2022,138 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
||||
}
|
||||
|
||||
/* ::::: Keyboard UI Panel ::::: */
|
||||
|
||||
.KUI-panel {
|
||||
-moz-appearance: none;
|
||||
background: rgba(68, 68, 68, .9) url(KUI-background.png) repeat-x;
|
||||
background: rgba(27%,27%,27%,.9) url(KUI-background.png) repeat-x;
|
||||
color: white;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
-moz-border-radius: 10px;
|
||||
margin-top: -1px;
|
||||
margin-left: -1px;
|
||||
border: 1px solid rgba(100%,100%,100%,.15);
|
||||
-moz-border-radius: 20px;
|
||||
}
|
||||
|
||||
.KUI-panel[level="top"] ,
|
||||
#ctrlTab-panel:not([sticky]) {
|
||||
background-color: rgba(68, 68, 68, .5);
|
||||
-moz-window-shadow: none;
|
||||
.KUI-panel[level="top"] {
|
||||
background-color: rgba(27%,27%,27%,.65);
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab Panel ::::: */
|
||||
.KUI-panel-closebutton {
|
||||
list-style-image: url(KUI-close.png);
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.KUI-panel-closebutton:not(:hover) {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.KUI-panel-closebutton > .toolbarbutton-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ::::: Ctrl-Tab and All Tabs Panels ::::: */
|
||||
|
||||
.tabPreview-canvas {
|
||||
-moz-box-shadow: 1px 1px 3px rgb(12%,12%,12%);
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src],
|
||||
.allTabs-favicon[src] {
|
||||
background-color: white;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 2px;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
/* Ctrl-Tab */
|
||||
|
||||
#ctrlTab-panel {
|
||||
padding-top: 20px;
|
||||
font-size: 1.2em;
|
||||
text-shadow: 0 0 3px black, 0 0 3px black, 0 0 3px black;
|
||||
}
|
||||
|
||||
#ctrlTab-search {
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
padding: 20px 10px 15px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 3px rgb(27%,27%,27%);
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail > html|canvas {
|
||||
border: 2px solid white;
|
||||
margin: -2px;
|
||||
.ctrlTab-preview:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.ctrlTab-thumbnail[selected="true"] ,
|
||||
.ctrlTab-thumbnail:hover {
|
||||
background: Highlight;
|
||||
color: HighlightText;
|
||||
-moz-box-shadow: 0 0 2px Highlight, 0 0 2px Highlight, 0 0 3px Highlight, 0 0 4px Highlight, 0 0 10px Highlight, 0 0 20px white;
|
||||
text-shadow: 0 0 3px transparent;
|
||||
.ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer {
|
||||
margin: 0 1em 1em;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
-moz-border-radius: .75em;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
border: 1px solid rgba(255, 255, 255, .3);
|
||||
cursor: pointer;
|
||||
.ctrlTab-preview:focus:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
|
||||
background-color: #ccc;
|
||||
color: black;
|
||||
text-shadow: 0 0 1px white;
|
||||
-moz-box-shadow: 0 0 0 1px rgba(255,255,255,.5), 0 0 5px 1px Highlight, 0 0 8px white;
|
||||
padding: 2px;
|
||||
margin: -2px -2px 0;
|
||||
}
|
||||
|
||||
.ctrlTab-pagePointer[selected="true"] {
|
||||
background: rgba(255, 255, 255, .6);
|
||||
cursor: default;
|
||||
.ctrlTab-preview:focus .tabPreview-canvas {
|
||||
-moz-box-shadow: none;
|
||||
}
|
||||
|
||||
#ctrlTab-showAll {
|
||||
-moz-appearance: button;
|
||||
color: ButtonText;
|
||||
font-weight: normal;
|
||||
text-shadow: none;
|
||||
padding: 3px 5px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#ctrlTab-showAll:focus {
|
||||
-moz-box-shadow: 0 0 8px white;
|
||||
-moz-border-radius: 3px;
|
||||
}
|
||||
|
||||
/* All Tabs */
|
||||
|
||||
#allTabs-panel {
|
||||
padding: 10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
#allTabs-panel:not(.KUI-panel) {
|
||||
-moz-appearance: none;
|
||||
background: rgb(27%,27%,27%) url(KUI-background.png) repeat-x;
|
||||
border: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#allTabs-meta {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#allTabs-filter {
|
||||
-moz-margin-start: 24px;
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
#allTabs-tab-close-button {
|
||||
/*XXX without this, the closebutton can cause the panel to expand horizontally */
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
#allTabs-tab-close-button > .toolbarbutton-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.allTabs-preview:hover,
|
||||
.allTabs-preview[closebuttonhover] {
|
||||
background-color: rgba(100%,100%,100%,.15);
|
||||
-moz-border-radius: 4px;
|
||||
}
|
||||
|
||||
.allTabs-preview:focus {
|
||||
background-color: rgba(100%,100%,100%,.3);
|
||||
-moz-border-radius: 4px;
|
||||
}
|
||||
|
||||
.allTabs-preview-label {
|
||||
-moz-transform: translate(0, -1px);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ classic.jar:
|
||||
skin/classic/browser/Info.png (Info.png)
|
||||
skin/classic/browser/identity.png (identity.png)
|
||||
skin/classic/browser/KUI-background.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
skin/classic/browser/mainwindow-dropdown-arrow.png
|
||||
skin/classic/browser/pageInfo.css
|
||||
skin/classic/browser/pageInfo.png (pageInfo.png)
|
||||
@ -106,6 +107,7 @@ classic.jar:
|
||||
skin/classic/aero/browser/Info.png (Info-aero.png)
|
||||
skin/classic/aero/browser/identity.png (identity-aero.png)
|
||||
skin/classic/aero/browser/KUI-background.png
|
||||
skin/classic/aero/browser/KUI-close.png
|
||||
skin/classic/aero/browser/mainwindow-dropdown-arrow.png (mainwindow-dropdown-arrow-aero.png)
|
||||
skin/classic/aero/browser/pageInfo.css
|
||||
skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png)
|
||||
|
@ -49,7 +49,6 @@ int mainReturn = 0;
|
||||
BOOL b16 = FALSE;
|
||||
BOOL bSimple = FALSE;
|
||||
|
||||
// freopen won't work on stdout in win16
|
||||
FILE *pAltFile = stdout;
|
||||
|
||||
CStringArray includeDirectories;
|
||||
|
@ -78,12 +78,12 @@ class nsIThreadJSContextStack;
|
||||
class nsIParserService;
|
||||
class nsIIOService;
|
||||
class nsIURI;
|
||||
class imgIContainer;
|
||||
class imgIDecoderObserver;
|
||||
class imgIRequest;
|
||||
class imgILoader;
|
||||
class imgICache;
|
||||
class nsIPrefBranch;
|
||||
class nsIImage;
|
||||
class nsIImageLoadingContent;
|
||||
class nsIDOMHTMLFormElement;
|
||||
class nsIDOMDocument;
|
||||
@ -654,13 +654,13 @@ public:
|
||||
static PRBool IsImageInCache(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Method to get an nsIImage from an image loading content
|
||||
* Method to get an imgIContainer from an image loading content
|
||||
*
|
||||
* @param aContent The image loading content. Must not be null.
|
||||
* @param aRequest The image request [out]
|
||||
* @return the nsIImage corresponding to the first frame of the image
|
||||
* @return the imgIContainer corresponding to the first frame of the image
|
||||
*/
|
||||
static already_AddRefed<nsIImage> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
|
||||
static already_AddRefed<imgIContainer> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
|
||||
|
||||
/**
|
||||
* Method that decides whether a content node is draggable
|
||||
|
@ -80,7 +80,6 @@
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
@ -93,6 +92,7 @@
|
||||
#include "nsEscape.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
@ -171,7 +171,7 @@ private:
|
||||
nsString mInfoString;
|
||||
|
||||
PRBool mIsAnchor;
|
||||
nsCOMPtr<nsIImage> mImage;
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
};
|
||||
|
||||
|
||||
@ -972,7 +972,7 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer,
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
|
||||
// grab the image data, and its request.
|
||||
nsCOMPtr<nsIImage> img =
|
||||
nsCOMPtr<imgIContainer> img =
|
||||
nsContentUtils::GetImageFromContent(image,
|
||||
getter_AddRefs(imgRequest));
|
||||
|
||||
|
@ -53,7 +53,6 @@ class nsIDOMDocument;
|
||||
class nsIDOMDragEvent;
|
||||
class nsISelection;
|
||||
class nsITransferable;
|
||||
class nsIImage;
|
||||
class nsIPresShell;
|
||||
class nsPresContext;
|
||||
class nsIContent;
|
||||
|
@ -98,8 +98,6 @@
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsIImage.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -2446,7 +2444,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIImage>
|
||||
already_AddRefed<imgIContainer>
|
||||
nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
|
||||
imgIRequest **aRequest)
|
||||
{
|
||||
@ -2470,26 +2468,11 @@ nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (aRequest) {
|
||||
imgRequest.swap(*aRequest);
|
||||
}
|
||||
|
||||
nsIImage* image = nsnull;
|
||||
CallGetInterface(ir.get(), &image);
|
||||
return image;
|
||||
return imgContainer.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIContentViewerEdit.h"
|
||||
@ -65,7 +66,6 @@
|
||||
// image copy stuff
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
@ -463,7 +463,7 @@ nsCopySupport::ImageCopy(nsIImageLoadingContent* aImageElement,
|
||||
|
||||
if (aCopyFlags & nsIContentViewerEdit::COPY_IMAGE_DATA) {
|
||||
// get the image data from the element
|
||||
nsCOMPtr<nsIImage> image =
|
||||
nsCOMPtr<imgIContainer> image =
|
||||
nsContentUtils::GetImageFromContent(aImageElement);
|
||||
NS_ENSURE_TRUE(image, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -158,10 +157,9 @@ nsImageLoadingContent::~nsImageLoadingContent()
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::FrameChanged(imgIContainer* aContainer,
|
||||
gfxIImageFrame* aFrame,
|
||||
nsIntRect* aDirtyRect)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aFrame, aDirtyRect));
|
||||
LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aDirtyRect));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -196,7 +194,7 @@ nsImageLoadingContent::OnStartContainer(imgIRequest* aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame));
|
||||
return NS_OK;
|
||||
@ -204,16 +202,16 @@ nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect* aRect)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aFrame, aRect));
|
||||
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aCurrentFrame, aRect));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
|
||||
return NS_OK;
|
||||
|
@ -58,14 +58,14 @@ nsStubImageDecoderObserver::OnStartContainer(imgIRequest *aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnStartFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect * aRect)
|
||||
{
|
||||
return NS_OK;
|
||||
@ -73,7 +73,7 @@ nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnStopFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
@ -102,7 +102,6 @@ nsStubImageDecoderObserver::OnStopRequest(imgIRequest *aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aFrame,
|
||||
nsIntRect * aDirtyRect)
|
||||
{
|
||||
return NS_OK;
|
||||
|
@ -61,8 +61,6 @@
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -5191,8 +5189,7 @@ public:
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
// imgIContainerObserver
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer);
|
||||
@ -5378,31 +5375,27 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance,
|
||||
if (currentRequest)
|
||||
currentRequest->GetImage(getter_AddRefs(imageContainer));
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
nsRefPtr<gfxASurface> currentFrame;
|
||||
if (imageContainer)
|
||||
imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
// We need to wrap the surface in a pattern to have somewhere to set the
|
||||
// graphics filter.
|
||||
nsRefPtr<gfxPattern> thebesPattern;
|
||||
if (currentFrame)
|
||||
thebesPattern = new gfxPattern(currentFrame);
|
||||
|
||||
if (thebesPattern) {
|
||||
thebesPattern->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
|
||||
|
||||
PRInt32 x, y, nativeWidth, nativeHeight;
|
||||
currentFrame->GetX(&x);
|
||||
currentFrame->GetY(&y);
|
||||
currentFrame->GetWidth(&nativeWidth);
|
||||
currentFrame->GetHeight(&nativeHeight);
|
||||
PRInt32 nativeWidth, nativeHeight;
|
||||
imageContainer->GetWidth(&nativeWidth);
|
||||
imageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> trans;
|
||||
const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
|
||||
trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
|
||||
x, y,
|
||||
nativeWidth, nativeHeight,
|
||||
0, 0, nativeWidth, nativeHeight,
|
||||
mPreserveAspectRatio);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> xy, fini;
|
||||
NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.X(), filterSubregion.Y());
|
||||
@ -5457,11 +5450,10 @@ nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest,
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGFEImageElement::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
nsresult rv =
|
||||
nsImageLoadingContent::FrameChanged(aContainer, newframe, dirtyRect);
|
||||
nsImageLoadingContent::FrameChanged(aContainer, dirtyRect);
|
||||
Invalidate();
|
||||
return rv;
|
||||
}
|
||||
|
@ -85,7 +85,6 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
|
@ -93,7 +93,6 @@
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "SetDocTitleTxn.h"
|
||||
|
@ -181,12 +181,13 @@ nsContentBlocker::ShouldLoad(PRUint32 aContentType,
|
||||
rv = TestPermission(aContentLocation, aRequestingLocation, aContentType,
|
||||
&shouldLoad, &fromPrefs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!shouldLoad)
|
||||
if (fromPrefs)
|
||||
if (!shouldLoad) {
|
||||
if (fromPrefs) {
|
||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||
else
|
||||
} else {
|
||||
*aDecision = nsIContentPolicy::REJECT_SERVER;
|
||||
|
||||
}
|
||||
}
|
||||
if (aContentType != nsIContentPolicy::TYPE_OBJECT || aMimeGuess.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
|
@ -50,7 +50,6 @@ XPIDLSRCS = \
|
||||
nsIFontEnumerator.idl \
|
||||
nsIScriptableRegion.idl \
|
||||
gfxIFormats.idl \
|
||||
gfxIImageFrame.idl \
|
||||
gfxidltypes.idl \
|
||||
$(NULL)
|
||||
|
||||
|
@ -1,168 +0,0 @@
|
||||
/** -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Chris Saari <saari@netscape.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 ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxidltypes.idl"
|
||||
#include "gfxIFormats.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
%}
|
||||
|
||||
native nsRectRef(nsIntRect &);
|
||||
|
||||
/**
|
||||
* gfxIImageFrame interface
|
||||
*
|
||||
* All x, y, width, height values are in pixels.
|
||||
*
|
||||
* @author Tim Rowley <tor@cs.brown.edu>
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
*/
|
||||
[scriptable, uuid(9c37930b-cadd-453c-89e1-9ed456715b9c)]
|
||||
interface gfxIImageFrame : nsISupports
|
||||
{
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image.
|
||||
*
|
||||
* @param aX The x-offset from the origin of the gfxIImageContainer parent.
|
||||
* @param aY The y-offset from the origin of the gfxIImageContainer parent.
|
||||
* @param aWidth The width of the image to create.
|
||||
* @param aHeight The height of the image to create.
|
||||
* @param aFormat the width of the image to create.
|
||||
*
|
||||
* @note The data in a new image is uninitialized.
|
||||
*/
|
||||
void init(in PRInt32 aX,
|
||||
in PRInt32 aY,
|
||||
in PRInt32 aWidth,
|
||||
in PRInt32 aHeight,
|
||||
in gfx_format aFormat,
|
||||
in gfx_depth aDepth);
|
||||
|
||||
/**
|
||||
* TRUE by default. When set to FALSE, you will no longer be able to make any modifications
|
||||
* to the data of the image. Any attempts will fail.
|
||||
*/
|
||||
attribute boolean mutable;
|
||||
|
||||
/**
|
||||
* The x-offset of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 x;
|
||||
|
||||
/**
|
||||
* The y-offset of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 y;
|
||||
|
||||
/**
|
||||
* The width of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 width;
|
||||
|
||||
/**
|
||||
* The height of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 height;
|
||||
|
||||
/**
|
||||
* The rectangle this frame ocupies.
|
||||
* @param rect this is really an out parameter.
|
||||
*/
|
||||
[noscript] void getRect(in nsRectRef rect);
|
||||
|
||||
/**
|
||||
* The image data format the image was created with.
|
||||
* @see gfxIFormats
|
||||
*/
|
||||
readonly attribute gfx_format format;
|
||||
|
||||
/**
|
||||
* returns whether the image requires the background to be painted
|
||||
*/
|
||||
readonly attribute boolean needsBackground;
|
||||
|
||||
/* data accessors */
|
||||
readonly attribute unsigned long imageBytesPerRow;
|
||||
|
||||
/**
|
||||
* returns the number of bytes allocated for the image
|
||||
*/
|
||||
readonly attribute unsigned long imageDataLength;
|
||||
|
||||
// XXX do we copy here? lets not...
|
||||
void getImageData([array, size_is(length)] out PRUint8 bits, out unsigned long length);
|
||||
|
||||
/**
|
||||
* Get Palette data pointer
|
||||
*/
|
||||
void getPaletteData([array, size_is(length)] out gfx_color palette, out unsigned long length);
|
||||
|
||||
/**
|
||||
* Lock image pixels before addressing the data directly
|
||||
*/
|
||||
void lockImageData();
|
||||
|
||||
/**
|
||||
* Unlock image pixels
|
||||
*/
|
||||
void unlockImageData();
|
||||
|
||||
|
||||
/* GIF Specific methods. These should be in a different class or interface. */
|
||||
|
||||
/**
|
||||
* Represents the number of milliseconds until the next frame should be displayed.
|
||||
* @note -1 means that this frame should be displayed forever.
|
||||
*/
|
||||
attribute long timeout;
|
||||
|
||||
/* frame disposal method, used only by GIFs. Should probably subclass image frame
|
||||
* and image container for GIFs special needs, but for simplicity it is here for the
|
||||
* moment
|
||||
*/
|
||||
attribute long frameDisposalMethod;
|
||||
|
||||
/* PNG specific methods */
|
||||
|
||||
attribute long blendMethod;
|
||||
};
|
@ -60,7 +60,6 @@ EXPORTS = \
|
||||
nsIRenderingContext.h \
|
||||
nsIFontMetrics.h \
|
||||
nsIDeviceContext.h \
|
||||
nsIImage.h \
|
||||
nsGfxCIID.h \
|
||||
nsIRegion.h \
|
||||
nsITheme.h \
|
||||
|
@ -1,307 +0,0 @@
|
||||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef nsIImage_h___
|
||||
#define nsIImage_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsRect.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
class gfxASurface;
|
||||
struct gfxMatrix;
|
||||
struct gfxRect;
|
||||
class gfxContext;
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
struct nsColorMap
|
||||
{
|
||||
//I lifted this from the image lib. The difference is that
|
||||
//this uses nscolor instead of NI_RGB. Multiple color pollution
|
||||
//is a bad thing. MMP
|
||||
PRInt32 NumColors; // Number of colors in the colormap.
|
||||
// A negative value can be used to denote a
|
||||
// possibly non-unique set.
|
||||
//nscolor *Map; // Colormap colors.
|
||||
PRUint8 *Index; // NULL, if map is in index order, otherwise
|
||||
// specifies the indices of the map entries. */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
nsMaskRequirements_kNoMask,
|
||||
nsMaskRequirements_kNeeds1Bit,
|
||||
nsMaskRequirements_kNeeds8Bit
|
||||
} nsMaskRequirements;
|
||||
|
||||
|
||||
#define nsImageUpdateFlags_kColorMapChanged 0x1
|
||||
#define nsImageUpdateFlags_kBitsChanged 0x2
|
||||
|
||||
// IID for the nsIImage interface
|
||||
// 0358ce68-b076-43b0-8f5c-36ed4592822c
|
||||
#define NS_IIMAGE_IID \
|
||||
{ 0x358ce68, 0xb076, 0x43b0, \
|
||||
{ 0x8f, 0x5c, 0x36, 0xed, 0x45, 0x92, 0x82, 0x2c } }
|
||||
|
||||
// Interface to Images
|
||||
class nsIImage : public nsISupports
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIMAGE_IID)
|
||||
|
||||
/**
|
||||
* Build and initialize the nsIImage
|
||||
* @param aWidth The width in pixels of the desired pixelmap
|
||||
* @param aHeight The height in pixels of the desired pixelmap
|
||||
* @param aDepth The number of bits per pixel for the pixelmap
|
||||
* @param aMaskRequirements A flag indicating if a alpha mask should be allocated
|
||||
*/
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements) = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes per pixel for this image
|
||||
* @update - dwc 2/3/99
|
||||
* @return - the number of bytes per pixel
|
||||
*/
|
||||
virtual PRInt32 GetBytesPix() = 0;
|
||||
|
||||
/**
|
||||
* Get whether rows are organized top to bottom, or bottom to top
|
||||
* @update - syd 3/29/99
|
||||
* @return PR_TRUE if top to bottom, else PR_FALSE
|
||||
*/
|
||||
virtual PRBool GetIsRowOrderTopToBottom() = 0;
|
||||
|
||||
/**
|
||||
* Get the width for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The width in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetWidth() = 0;
|
||||
|
||||
/**
|
||||
* Get the height for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The height in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetHeight() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the pixelmap, only if it is not optimized
|
||||
* @update - dwc 2/1/99
|
||||
* @return address of the DIB pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes needed to get to the next scanline for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Get whether this image has an alpha mask. Preferable to testing
|
||||
* if GetAlphaBits() is non-null.
|
||||
* @update - sfraser 10/19/99
|
||||
* @return PR_TRUE if the image has an alpha mask, PR_FALSE otherwise
|
||||
*/
|
||||
virtual PRBool GetHasAlphaMask() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the alpha mask
|
||||
* @update - dwc 2/1/99
|
||||
* @return address of the alpha mask pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetAlphaBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes per scanline for the alpha mask
|
||||
* @update - dwc 2/1/99
|
||||
* @return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetAlphaLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Update the nsIImage color table
|
||||
* @update - dougt 9/9/08
|
||||
* @param aFlags Used to pass in parameters for the update
|
||||
* @param aUpdateRect The rectangle to update
|
||||
* @return success code. failure means stop decoding
|
||||
*/
|
||||
virtual nsresult ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect) = 0;
|
||||
|
||||
/**
|
||||
* Get whether this image's region is completely filled with data.
|
||||
* @return PR_TRUE if image is complete, PR_FALSE if image is not yet
|
||||
* complete or broken
|
||||
*/
|
||||
virtual PRBool GetIsImageComplete() = 0;
|
||||
|
||||
/**
|
||||
* Converted this pixelmap to an optimized pixelmap for the device
|
||||
* @update - dwc 2/1/99
|
||||
* @param aContext The device to optimize for
|
||||
* @return the result of the operation, if NS_OK, then the pixelmap is optimized
|
||||
*/
|
||||
virtual nsresult Optimize(nsIDeviceContext* aContext) = 0;
|
||||
|
||||
/**
|
||||
* Get the colormap for the nsIImage
|
||||
* @update - dwc 2/1/99
|
||||
* @return if non null, the colormap for the pixelmap,otherwise the image is not color mapped
|
||||
*/
|
||||
virtual nsColorMap * GetColorMap() = 0;
|
||||
|
||||
/**
|
||||
* BitBlit the nsIImage to a device, the source and dest can be scaled.
|
||||
* @param aContext the destination
|
||||
* @param aFilter the filter for the image
|
||||
* @param aUserSpaceToImageSpace the transform that maps user-space
|
||||
* coordinates to coordinates in (tiled, post-padding) image pixels
|
||||
* @param aFill the area to fill with tiled images
|
||||
* @param aPadding the padding to be added to this image before tiling,
|
||||
* in image pixels
|
||||
* @param aSubimage the subimage in padded+tiled image space that we're
|
||||
* extracting the contents from. Pixels outside this rectangle must not
|
||||
* be sampled.
|
||||
*
|
||||
* So this is supposed to
|
||||
* -- add aPadding transparent pixels around the image
|
||||
* -- use that image to tile the plane
|
||||
* -- replace everything outside the aSubimage region with the nearest
|
||||
* border pixel of that region (like EXTEND_PAD)
|
||||
* -- fill aFill with the image, using aImageSpaceToDeviceSpace as the
|
||||
* image-space-to-device-space transform
|
||||
*/
|
||||
virtual void Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage) = 0;
|
||||
|
||||
/**
|
||||
* Get the alpha depth for the image mask
|
||||
* @update - lordpixel 2001/05/16
|
||||
* @return the alpha mask depth for the image, ie, 0, 1 or 8
|
||||
*/
|
||||
virtual PRInt8 GetAlphaDepth() = 0;
|
||||
|
||||
/**
|
||||
* Return information about the bits for this structure
|
||||
* @update - dwc 2/1/99
|
||||
* @return a bitmap info structure for the Device Dependent Bits
|
||||
*/
|
||||
virtual void* GetBitInfo() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* LockImagePixels
|
||||
* Lock the image pixels so that we can access them directly,
|
||||
* with safety. May be a noop on some platforms.
|
||||
*
|
||||
* If you want to be able to call GetSurface(), wrap the call in
|
||||
* LockImagePixels()/UnlockImagePixels(). This also allows you to write to
|
||||
* the surface returned by GetSurface().
|
||||
*
|
||||
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
|
||||
*
|
||||
* Must be balanced by a call to UnlockImagePixels().
|
||||
*
|
||||
* @update - sfraser 10/18/99
|
||||
* @return error result
|
||||
*/
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels) = 0;
|
||||
|
||||
/**
|
||||
* UnlockImagePixels
|
||||
* Unlock the image pixels. May be a noop on some platforms.
|
||||
*
|
||||
* Should balance an earlier call to LockImagePixels().
|
||||
*
|
||||
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
|
||||
*
|
||||
* @update - sfraser 10/18/99
|
||||
* @return error result
|
||||
*/
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels) = 0;
|
||||
|
||||
/**
|
||||
* GetSurface
|
||||
* Return the Thebes gfxASurface in aSurface, if there is one. Should be
|
||||
* wrapped by LockImagePixels()/UnlockImagePixels().
|
||||
*
|
||||
* aSurface will be AddRef'd (as with most getters), so
|
||||
* getter_AddRefs should be used.
|
||||
*/
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) = 0;
|
||||
|
||||
/**
|
||||
* GetSurface
|
||||
* Return the Thebes gfxPattern in aPattern. It is always possible to get a
|
||||
* gfxPattern (unlike the gfxASurface from GetSurface()).
|
||||
*
|
||||
* aPattern will be AddRef'd (as with most getters), so
|
||||
* getter_AddRefs should be used.
|
||||
*/
|
||||
NS_IMETHOD GetPattern(gfxPattern **aPattern) = 0;
|
||||
|
||||
/**
|
||||
* SetHasNoAlpha
|
||||
*
|
||||
* Hint to the image that all the pixels are fully opaque, even if
|
||||
* the original format requested a 1-bit or 8-bit alpha mask
|
||||
*/
|
||||
virtual void SetHasNoAlpha() = 0;
|
||||
|
||||
/**
|
||||
* Extract a rectangular region of the nsIImage and return it as a new
|
||||
* nsIImage.
|
||||
* @param aSubimage the region to extract
|
||||
* @param aResult the extracted image
|
||||
*/
|
||||
NS_IMETHOD Extract(const nsIntRect& aSubimage,
|
||||
nsIImage** aResult NS_OUTPARAM) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIImage, NS_IIMAGE_IID)
|
||||
|
||||
#endif
|
@ -59,7 +59,7 @@ REQUIRES = xpcom \
|
||||
xpconnect \
|
||||
$(NULL)
|
||||
|
||||
DIRS = shared thebes
|
||||
DIRS = thebes
|
||||
|
||||
ifdef MOZ_ENABLE_POSTSCRIPT
|
||||
DIRS += psshared
|
||||
|
@ -1,67 +0,0 @@
|
||||
#
|
||||
# ***** 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.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# 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 = gfx
|
||||
LIBRARY_NAME = gfxshared_s
|
||||
FORCE_STATIC_LIB=1
|
||||
EXPORT_LIBRARY=1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES= \
|
||||
xpcom \
|
||||
string \
|
||||
imglib2 \
|
||||
widget \
|
||||
thebes \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
gfxImageFrame.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/.. \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -1,428 +0,0 @@
|
||||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.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 ***** */
|
||||
|
||||
#include "gfxImageFrame.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <limits.h>
|
||||
#include "prmem.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(gfxImageFrame, gfxIImageFrame, nsIInterfaceRequestor)
|
||||
|
||||
gfxImageFrame::gfxImageFrame() :
|
||||
mImageData(nsnull),
|
||||
mTimeout(100),
|
||||
mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */
|
||||
mBlendMethod(1), /* imgIContainer::kBlendOver */
|
||||
mInitialized(PR_FALSE),
|
||||
mMutable(PR_TRUE)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
gfxImageFrame::~gfxImageFrame()
|
||||
{
|
||||
/* destructor code */
|
||||
PR_FREEIF(mImageData);
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
/* void init (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfx_format aFormat); */
|
||||
NS_IMETHODIMP gfxImageFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, gfx_format aFormat,gfx_depth aDepth)
|
||||
{
|
||||
if (mInitialized)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// assert for properties that should be verified by decoders, warn for properties related to bad content
|
||||
|
||||
if (aWidth <= 0 || aHeight <= 0) {
|
||||
NS_ASSERTION(0, "error - negative image size\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* check to make sure we don't overflow a 32-bit */
|
||||
PRInt32 tmp = aWidth * aHeight;
|
||||
if (tmp / aHeight != aWidth) {
|
||||
NS_WARNING("width or height too large");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
tmp = tmp * 4;
|
||||
if (tmp / 4 != aWidth * aHeight) {
|
||||
NS_WARNING("width or height too large");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* reject over-wide or over-tall images */
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if ( aWidth > k64KLimit || aHeight > k64KLimit ){
|
||||
NS_WARNING("image too big");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces on the Mac to that height
|
||||
if (aHeight > SHRT_MAX) {
|
||||
NS_WARNING("image too big");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mOffset.MoveTo(aX, aY);
|
||||
mSize.SizeTo(aWidth, aHeight);
|
||||
|
||||
mFormat = aFormat;
|
||||
mDepth = aDepth;
|
||||
|
||||
PRBool needImage = PR_TRUE;
|
||||
nsMaskRequirements maskReq;
|
||||
|
||||
switch (aFormat) {
|
||||
case gfxIFormats::BGR:
|
||||
case gfxIFormats::RGB:
|
||||
maskReq = nsMaskRequirements_kNoMask;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGRA:
|
||||
case gfxIFormats::RGBA:
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGR_A1:
|
||||
case gfxIFormats::RGB_A1:
|
||||
maskReq = nsMaskRequirements_kNeeds1Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGR_A8:
|
||||
case gfxIFormats::RGB_A8:
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::PAL:
|
||||
case gfxIFormats::PAL_A1:
|
||||
needImage = PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("unsupported gfx_format\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (needImage) {
|
||||
if (aDepth != 24) {
|
||||
NS_ERROR("This Depth is not supported");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mImage = do_CreateInstance("@mozilla.org/gfx/image;1", &rv);
|
||||
NS_ASSERTION(mImage, "creation of image failed");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mImage->Init(aWidth, aHeight, aDepth, maskReq);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
if ((aDepth < 1) || (aDepth > 8)) {
|
||||
NS_ERROR("This Depth is not supported\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mImageData = (PRUint8*)PR_MALLOC(PaletteDataLength() + ImageDataLength());
|
||||
NS_ENSURE_TRUE(mImageData, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* attribute boolean mutable */
|
||||
NS_IMETHODIMP gfxImageFrame::GetMutable(PRBool *aMutable)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ASSERTION(mInitialized, "gfxImageFrame::GetMutable called on non-inited gfxImageFrame");
|
||||
*aMutable = mMutable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::SetMutable(PRBool aMutable)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mMutable = aMutable;
|
||||
|
||||
if (!aMutable && mImage)
|
||||
mImage->Optimize(nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 x; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetX(PRInt32 *aX)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aX = mOffset.x;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 y; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetY(PRInt32 *aY)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aY = mOffset.y;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute PRInt32 width; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetWidth(PRInt32 *aWidth)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aWidth = mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 height; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetHeight(PRInt32 *aHeight)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aHeight = mSize.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getRect(in nsRectRef rect); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetRect(nsIntRect &aRect)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
aRect.SetRect(mOffset.x, mOffset.y, mSize.width, mSize.height);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute gfx_format format; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetFormat(gfx_format *aFormat)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aFormat = mFormat;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean needsBackground; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetNeedsBackground(PRBool *aNeedsBackground)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aNeedsBackground = (mFormat != gfxIFormats::RGB &&
|
||||
mFormat != gfxIFormats::PAL &&
|
||||
mFormat != gfxIFormats::BGR) ||
|
||||
!mImage->GetIsImageComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute unsigned long imageBytesPerRow; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageBytesPerRow(PRUint32 *aBytesPerRow)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBytesPerRow = mImage ? mImage->GetLineStride(): mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute unsigned long imageDataLength; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageDataLength(PRUint32 *aBitsLength)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBitsLength = ImageDataLength();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getImageData([array, size_is(length)] out PRUint8 bits, out unsigned long length); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageData(PRUint8 **aData, PRUint32 *length)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ASSERTION(mMutable, "trying to get data on an immutable frame");
|
||||
|
||||
*aData = mImage ? mImage->GetBits() : (mImageData + PaletteDataLength());
|
||||
*length = ImageDataLength();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getPaletteData ([array, size_is (length)] out PRUint32 palette, out unsigned long length); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetPaletteData(gfx_color **aPalette, PRUint32 *length)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImageData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aPalette = (gfx_color*)mImageData;
|
||||
*length = PaletteDataLength();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void lockImageData (); */
|
||||
NS_IMETHODIMP gfxImageFrame::LockImageData()
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImage)
|
||||
return NS_OK;
|
||||
return mImage->LockImagePixels(PR_FALSE);
|
||||
}
|
||||
|
||||
/* void unlockImageData (); */
|
||||
NS_IMETHODIMP gfxImageFrame::UnlockImageData()
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImage)
|
||||
return NS_OK;
|
||||
return mImage->UnlockImagePixels(PR_FALSE);
|
||||
}
|
||||
|
||||
/* attribute long timeout; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetTimeout(PRInt32 *aTimeout)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Ensure a minimal time between updates so we don't throttle the UI thread.
|
||||
// consider 0 == unspecified and make it fast but not too fast. See bug
|
||||
// 125137, bug 139677, and bug 207059. The behavior of recent IE and Opera
|
||||
// versions seems to be:
|
||||
// IE 6/Win:
|
||||
// 10 - 50ms go 100ms
|
||||
// >50ms go correct speed
|
||||
// Opera 7 final/Win:
|
||||
// 10ms goes 100ms
|
||||
// >10ms go correct speed
|
||||
// It seems that there are broken tools out there that set a 0ms or 10ms
|
||||
// timeout when they really want a "default" one. So munge values in that
|
||||
// range.
|
||||
if (mTimeout >= 0 && mTimeout <= 10)
|
||||
*aTimeout = 100;
|
||||
else
|
||||
*aTimeout = mTimeout;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::SetTimeout(PRInt32 aTimeout)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mTimeout = aTimeout;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute long frameDisposalMethod; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetFrameDisposalMethod(PRInt32 *aFrameDisposalMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aFrameDisposalMethod = mDisposalMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP gfxImageFrame::SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mDisposalMethod = aFrameDisposalMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute long blendMethod; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetBlendMethod(PRInt32 *aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBlendMethod = mBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP gfxImageFrame::SetBlendMethod(PRInt32 aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mBlendMethod = (PRInt8)aBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::GetInterface(const nsIID & aIID, void * *result)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
if (NS_SUCCEEDED(QueryInterface(aIID, result)))
|
||||
return NS_OK;
|
||||
if (mImage && aIID.Equals(NS_GET_IID(nsIImage)))
|
||||
return mImage->QueryInterface(aIID, result);
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/* -*- 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000-2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.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 ***** */
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define GFX_IMAGEFRAME_CID \
|
||||
{ /* aa699204-1dd1-11b2-84a9-a280c268e4fb */ \
|
||||
0xaa699204, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x84, 0xa9, 0xa2, 0x80, 0xc2, 0x68, 0xe4, 0xfb} \
|
||||
}
|
||||
|
||||
class gfxImageFrame : public gfxIImageFrame,
|
||||
public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_GFXIIMAGEFRAME
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
gfxImageFrame();
|
||||
virtual ~gfxImageFrame();
|
||||
|
||||
protected:
|
||||
nsIntSize mSize;
|
||||
|
||||
private:
|
||||
PRUint32 PaletteDataLength() const {
|
||||
return ((1 << mDepth) * sizeof(gfx_color));
|
||||
}
|
||||
|
||||
PRUint32 ImageDataLength() const {
|
||||
return (mImage ? mImage->GetLineStride() : mSize.width) * mSize.height;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIImage> mImage;
|
||||
PRUint8* mImageData;
|
||||
|
||||
PRInt32 mTimeout; // -1 means display forever
|
||||
nsIntPoint mOffset;
|
||||
PRInt32 mDisposalMethod;
|
||||
|
||||
gfx_format mFormat;
|
||||
gfx_depth mDepth;
|
||||
PRInt8 mBlendMethod;
|
||||
PRPackedBool mInitialized;
|
||||
PRPackedBool mMutable;
|
||||
};
|
@ -72,7 +72,6 @@ endif
|
||||
|
||||
CPPSRCS = \
|
||||
nsThebesDeviceContext.cpp \
|
||||
nsThebesImage.cpp \
|
||||
nsThebesRegion.cpp \
|
||||
nsThebesGfxFactory.cpp \
|
||||
nsThebesRenderingContext.cpp \
|
||||
@ -128,7 +127,6 @@ LOCAL_INCLUDES = \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
../shared/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX) \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(DEPTH)/modules/libutil/src/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \
|
||||
|
@ -42,21 +42,17 @@
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "nsScriptableRegion.h"
|
||||
#include "gfxImageFrame.h"
|
||||
|
||||
#include "nsThebesDeviceContext.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsThebesRegion.h"
|
||||
#include "nsThebesFontMetrics.h"
|
||||
#include "nsThebesFontEnumerator.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontMetrics)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(gfxImageFrame)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesDeviceContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRenderingContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesImage)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRegion)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontEnumerator)
|
||||
|
||||
@ -119,10 +115,6 @@ static const nsModuleComponentInfo components[] =
|
||||
NS_RENDERING_CONTEXT_CID,
|
||||
"@mozilla.org/gfx/renderingcontext;1",
|
||||
nsThebesRenderingContextConstructor },
|
||||
{ "Thebes nsImage",
|
||||
NS_IMAGE_CID,
|
||||
"@mozilla.org/gfx/image;1",
|
||||
nsThebesImageConstructor },
|
||||
{ "Thebes Region",
|
||||
NS_REGION_CID,
|
||||
"@mozilla.org/gfx/region/nsThebes;1",
|
||||
@ -131,10 +123,6 @@ static const nsModuleComponentInfo components[] =
|
||||
NS_SCRIPTABLE_REGION_CID,
|
||||
"@mozilla.org/gfx/region;1",
|
||||
nsScriptableRegionConstructor },
|
||||
{ "image frame",
|
||||
GFX_IMAGEFRAME_CID,
|
||||
"@mozilla.org/gfx/image/frame;2",
|
||||
gfxImageFrameConstructor },
|
||||
};
|
||||
|
||||
static nsresult
|
||||
|
@ -1,857 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.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 "nsThebesImage.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
static PRBool gDisableOptimize = PR_FALSE;
|
||||
|
||||
/*XXX get CAIRO_HAS_DDRAW_SURFACE */
|
||||
#include "cairo.h"
|
||||
|
||||
#ifdef CAIRO_HAS_DDRAW_SURFACE
|
||||
#include "gfxDDrawSurface.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || defined(WINCE)
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
|
||||
/* Whether to use the windows surface; only for desktop win32 */
|
||||
#define USE_WIN_SURFACE 1
|
||||
|
||||
static PRUint32 gTotalDDBs = 0;
|
||||
static PRUint32 gTotalDDBSize = 0;
|
||||
// only use up a maximum of 64MB in DDBs
|
||||
#define kMaxDDBSize (64*1024*1024)
|
||||
// and don't let anything in that's bigger than 4MB
|
||||
#define kMaxSingleDDBSize (4*1024*1024)
|
||||
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesImage, nsIImage)
|
||||
|
||||
nsThebesImage::nsThebesImage()
|
||||
: mFormat(gfxImageSurface::ImageFormatRGB24),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mDecoded(0,0,0,0),
|
||||
mImageComplete(PR_FALSE),
|
||||
mSinglePixel(PR_FALSE),
|
||||
mFormatChanged(PR_FALSE),
|
||||
mNeverUseDeviceSurface(PR_FALSE),
|
||||
mSinglePixelColor(0),
|
||||
mAlphaDepth(0)
|
||||
{
|
||||
static PRBool hasCheckedOptimize = PR_FALSE;
|
||||
if (!hasCheckedOptimize) {
|
||||
if (PR_GetEnv("MOZ_DISABLE_IMAGE_OPTIMIZE")) {
|
||||
gDisableOptimize = PR_TRUE;
|
||||
}
|
||||
hasCheckedOptimize = PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mIsDDBSurface = PR_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
|
||||
// Reject over-wide or over-tall images.
|
||||
if (!AllowedImageSize(aWidth, aHeight))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
switch(aMaskRequirements)
|
||||
{
|
||||
case nsMaskRequirements_kNeeds1Bit:
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
mAlphaDepth = 1;
|
||||
break;
|
||||
case nsMaskRequirements_kNeeds8Bit:
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
mAlphaDepth = 8;
|
||||
break;
|
||||
default:
|
||||
format = gfxImageSurface::ImageFormatRGB24;
|
||||
mAlphaDepth = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mFormat = format;
|
||||
|
||||
// For Windows, we must create the device surface first (if we're
|
||||
// going to) so that the image surface can wrap it. Can't be done
|
||||
// the other way around.
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mWinSurface = new gfxWindowsSurface(gfxIntSize(mWidth, mHeight), format);
|
||||
if (mWinSurface && mWinSurface->CairoStatus() == 0) {
|
||||
// no error
|
||||
mImageSurface = mWinSurface->GetImageSurface();
|
||||
} else {
|
||||
mWinSurface = nsnull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// For other platforms we create the image surface first and then
|
||||
// possibly wrap it in a device surface. This branch is also used
|
||||
// on Windows if we're not using device surfaces or if we couldn't
|
||||
// create one.
|
||||
if (!mImageSurface)
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
|
||||
|
||||
if (!mImageSurface || mImageSurface->CairoStatus()) {
|
||||
mImageSurface = nsnull;
|
||||
// guess
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mQuartzSurface = new gfxQuartzImageSurface(mImageSurface);
|
||||
}
|
||||
#endif
|
||||
|
||||
mStride = mImageSurface->Stride();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsThebesImage::~nsThebesImage()
|
||||
{
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (mIsDDBSurface) {
|
||||
gTotalDDBs--;
|
||||
gTotalDDBSize -= mWidth*mHeight*4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetBytesPix()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsRowOrderTopToBottom()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetWidth()
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetHeight()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetBits()
|
||||
{
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Data();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetLineStride()
|
||||
{
|
||||
return mStride;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetHasAlphaMask()
|
||||
{
|
||||
return mAlphaDepth > 0;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetAlphaBits()
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetAlphaLineStride()
|
||||
{
|
||||
return (mAlphaDepth > 0) ? mStride : 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect)
|
||||
{
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mDecoded.UnionRect(mDecoded, *aUpdateRect);
|
||||
|
||||
// clamp to bounds, in case someone sends a bogus
|
||||
// updateRect (I'm looking at you, gif decoder)
|
||||
nsIntRect boundsRect(0, 0, mWidth, mHeight);
|
||||
mDecoded.IntersectRect(mDecoded, boundsRect);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsImageComplete()
|
||||
{
|
||||
if (!mImageComplete)
|
||||
mImageComplete = (mDecoded == nsIntRect(0, 0, mWidth, mHeight));
|
||||
return mImageComplete;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
{
|
||||
if (gDisableOptimize)
|
||||
return NS_OK;
|
||||
|
||||
if (mOptSurface || mSinglePixel)
|
||||
return NS_OK;
|
||||
|
||||
/* Figure out if the entire image is a constant color */
|
||||
|
||||
// this should always be true
|
||||
if (mStride == mWidth * 4) {
|
||||
PRUint32 *imgData = (PRUint32*) mImageSurface->Data();
|
||||
PRUint32 firstPixel = * (PRUint32*) imgData;
|
||||
PRUint32 pixelCount = mWidth * mHeight + 1;
|
||||
|
||||
while (--pixelCount && *imgData++ == firstPixel)
|
||||
;
|
||||
|
||||
if (pixelCount == 0) {
|
||||
// all pixels were the same
|
||||
if (mFormat == gfxImageSurface::ImageFormatARGB32 ||
|
||||
mFormat == gfxImageSurface::ImageFormatRGB24)
|
||||
{
|
||||
mSinglePixelColor = gfxRGBA
|
||||
(firstPixel,
|
||||
(mFormat == gfxImageSurface::ImageFormatRGB24 ?
|
||||
gfxRGBA::PACKED_XRGB :
|
||||
gfxRGBA::PACKED_ARGB_PREMULTIPLIED));
|
||||
|
||||
mSinglePixel = PR_TRUE;
|
||||
|
||||
// blow away the older surfaces, to release data
|
||||
|
||||
mImageSurface = nsnull;
|
||||
mOptSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// if it's not RGB24/ARGB32, don't optimize, but we never hit this at the moment
|
||||
}
|
||||
|
||||
// if we're being forced to use image surfaces due to
|
||||
// resource constraints, don't try to optimize beyond same-pixel.
|
||||
if (mNeverUseDeviceSurface || ShouldUseImageSurfaces())
|
||||
return NS_OK;
|
||||
|
||||
mOptSurface = nsnull;
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
// we need to special-case windows here, because windows has
|
||||
// a distinction between DIB and DDB and we want to use DDBs as much
|
||||
// as we can.
|
||||
if (mWinSurface) {
|
||||
// Don't do DDBs for large images; see bug 359147
|
||||
// Note that we bother with DDBs at all because they are much faster
|
||||
// on some systems; on others there isn't much of a speed difference
|
||||
// between DIBs and DDBs.
|
||||
//
|
||||
// Originally this just limited to 1024x1024; but that still
|
||||
// had us hitting overall total memory usage limits (which was
|
||||
// around 220MB on my intel shared memory system with 2GB RAM
|
||||
// and 16-128mb in use by the video card, so I can't make
|
||||
// heads or tails out of this limit).
|
||||
//
|
||||
// So instead, we clamp the max size to 64MB (this limit shuld
|
||||
// be made dynamic based on.. something.. as soon a we figure
|
||||
// out that something) and also limit each individual image to
|
||||
// be less than 4MB to keep very large images out of DDBs.
|
||||
|
||||
// assume (almost -- we don't quadword-align) worst-case size
|
||||
PRUint32 ddbSize = mWidth * mHeight * 4;
|
||||
if (ddbSize <= kMaxSingleDDBSize &&
|
||||
ddbSize + gTotalDDBSize <= kMaxDDBSize)
|
||||
{
|
||||
nsRefPtr<gfxWindowsSurface> wsurf = mWinSurface->OptimizeToDDB(nsnull, gfxIntSize(mWidth, mHeight), mFormat);
|
||||
if (wsurf) {
|
||||
gTotalDDBs++;
|
||||
gTotalDDBSize += ddbSize;
|
||||
mIsDDBSurface = PR_TRUE;
|
||||
mOptSurface = wsurf;
|
||||
}
|
||||
}
|
||||
if (!mOptSurface && !mFormatChanged) {
|
||||
// just use the DIB if the format has not changed
|
||||
mOptSurface = mWinSurface;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface) {
|
||||
mQuartzSurface->Flush();
|
||||
mOptSurface = mQuartzSurface;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mOptSurface == nsnull)
|
||||
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
|
||||
|
||||
if (mOptSurface) {
|
||||
mImageSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsColorMap *
|
||||
nsThebesImage::GetColorMap()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRInt8
|
||||
nsThebesImage::GetAlphaDepth()
|
||||
{
|
||||
return mAlphaDepth;
|
||||
}
|
||||
|
||||
void *
|
||||
nsThebesImage::GetBitInfo()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::LockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if ((mOptSurface || mSinglePixel) && !mImageSurface) {
|
||||
// Recover the pixels
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
gfxContext context(mImageSurface);
|
||||
context.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel)
|
||||
context.SetDeviceColor(mSinglePixelColor);
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mOptSurface = nsnull;
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSafeImageTransformComponent(gfxFloat aValue)
|
||||
{
|
||||
return aValue >= -32768 && aValue <= 32767;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage)
|
||||
{
|
||||
NS_ASSERTION(!aFill.IsEmpty(), "zero dest size --- fix caller");
|
||||
NS_ASSERTION(!aSubimage.IsEmpty(), "zero source size --- fix caller");
|
||||
|
||||
PRBool doPadding = aPadding != nsIntMargin(0,0,0,0);
|
||||
PRBool doPartialDecode = !GetIsImageComplete();
|
||||
gfxContext::GraphicsOperator op = aContext->CurrentOperator();
|
||||
|
||||
if (mSinglePixel && !doPadding && !doPartialDecode) {
|
||||
// Single-color fast path
|
||||
// if a == 0, it's a noop
|
||||
if (mSinglePixelColor.a == 0.0)
|
||||
return;
|
||||
|
||||
if (op == gfxContext::OPERATOR_OVER && mSinglePixelColor.a == 1.0)
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
aContext->SetDeviceColor(mSinglePixelColor);
|
||||
aContext->NewPath();
|
||||
aContext->Rectangle(aFill);
|
||||
aContext->Fill();
|
||||
aContext->SetOperator(op);
|
||||
aContext->SetDeviceColor(gfxRGBA(0,0,0,0));
|
||||
return;
|
||||
}
|
||||
|
||||
gfxMatrix userSpaceToImageSpace = aUserSpaceToImageSpace;
|
||||
gfxRect sourceRect = userSpaceToImageSpace.Transform(aFill);
|
||||
gfxRect imageRect(0, 0, mWidth + aPadding.LeftRight(), mHeight + aPadding.TopBottom());
|
||||
gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height);
|
||||
gfxRect fill = aFill;
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
|
||||
NS_ASSERTION(!sourceRect.Intersect(subimage).IsEmpty(),
|
||||
"We must be allowed to sample *some* source pixels!");
|
||||
|
||||
PRBool doTile = !imageRect.Contains(sourceRect);
|
||||
if (doPadding || doPartialDecode) {
|
||||
gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height) +
|
||||
gfxPoint(aPadding.left, aPadding.top);
|
||||
|
||||
if (!doTile && !mSinglePixel) {
|
||||
// Not tiling, and we have a surface, so we can account for
|
||||
// padding and/or a partial decode just by twiddling parameters.
|
||||
// First, update our user-space fill rect.
|
||||
sourceRect = sourceRect.Intersect(available);
|
||||
gfxMatrix imageSpaceToUserSpace = userSpaceToImageSpace;
|
||||
imageSpaceToUserSpace.Invert();
|
||||
fill = imageSpaceToUserSpace.Transform(sourceRect);
|
||||
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
subimage = subimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
|
||||
userSpaceToImageSpace.Multiply(
|
||||
gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
|
||||
sourceRect = sourceRect - gfxPoint(aPadding.left, aPadding.top);
|
||||
imageRect = gfxRect(0, 0, mWidth, mHeight);
|
||||
} else {
|
||||
// Create a temporary surface
|
||||
gfxIntSize size(PRInt32(imageRect.Width()),
|
||||
PRInt32(imageRect.Height()));
|
||||
// Give this surface an alpha channel because there are
|
||||
// transparent pixels in the padding or undecoded area
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(size,
|
||||
format);
|
||||
if (!surface || surface->CairoStatus() != 0)
|
||||
return;
|
||||
|
||||
// Fill 'available' with whatever we've got
|
||||
gfxContext tmpCtx(surface);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
tmpCtx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
tmpCtx.SetSource(ThebesSurface(), gfxPoint(aPadding.left, aPadding.top));
|
||||
}
|
||||
tmpCtx.Rectangle(available);
|
||||
tmpCtx.Fill();
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(!mSinglePixel, "This should already have been handled");
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
}
|
||||
// At this point, we've taken care of mSinglePixel images, images with
|
||||
// aPadding, and partially-decoded images.
|
||||
|
||||
if (!AllowedImageSize(fill.size.width + 1, fill.size.height + 1)) {
|
||||
NS_WARNING("Destination area too large, bailing out");
|
||||
return;
|
||||
}
|
||||
// Compute device-space-to-image-space transform. We need to sanity-
|
||||
// check it to work around a pixman bug :-(
|
||||
// XXX should we only do this for certain surface types?
|
||||
gfxFloat deviceX, deviceY;
|
||||
nsRefPtr<gfxASurface> currentTarget =
|
||||
aContext->CurrentSurface(&deviceX, &deviceY);
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxMatrix deviceToUser = currentMatrix;
|
||||
deviceToUser.Invert();
|
||||
deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
|
||||
gfxMatrix deviceToImage = deviceToUser;
|
||||
deviceToImage.Multiply(userSpaceToImageSpace);
|
||||
|
||||
PRBool pushedGroup = PR_FALSE;
|
||||
if (currentTarget->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
// BEGIN working around cairo/pixman bug (bug 364968)
|
||||
// Quartz's limits for matrix are much larger than pixman
|
||||
|
||||
// Our device-space-to-image-space transform may not be acceptable to pixman.
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.xx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.xy) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yy)) {
|
||||
NS_WARNING("Scaling up too much, bailing out");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.x0) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.y0)) {
|
||||
// We'll push a group, which will hopefully reduce our transform's
|
||||
// translation so it's in bounds
|
||||
aContext->Save();
|
||||
|
||||
// Clip the rounded-out-to-device-pixels bounds of the
|
||||
// transformed fill area. This is the area for the group we
|
||||
// want to push.
|
||||
aContext->IdentityMatrix();
|
||||
gfxRect bounds = currentMatrix.TransformBounds(fill);
|
||||
bounds.RoundOut();
|
||||
aContext->Clip(bounds);
|
||||
aContext->SetMatrix(currentMatrix);
|
||||
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
pushedGroup = PR_TRUE;
|
||||
}
|
||||
// END working around cairo/pixman bug (bug 364968)
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pattern = new gfxPattern(surface);
|
||||
pattern->SetMatrix(userSpaceToImageSpace);
|
||||
|
||||
// OK now, the hard part left is to account for the subimage sampling
|
||||
// restriction. If all the transforms involved are just integer
|
||||
// translations, then we assume no resampling will occur so there's
|
||||
// nothing to do.
|
||||
// XXX if only we had source-clipping in cairo!
|
||||
if (!currentMatrix.HasNonIntegerTranslation() &&
|
||||
!userSpaceToImageSpace.HasNonIntegerTranslation()) {
|
||||
if (doTile) {
|
||||
pattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
}
|
||||
} else {
|
||||
if (doTile || !subimage.Contains(imageRect)) {
|
||||
// EXTEND_PAD won't help us here; we have to create a temporary
|
||||
// surface to hold the subimage of pixels we're allowed to
|
||||
// sample
|
||||
|
||||
gfxRect userSpaceClipExtents = aContext->GetClipExtents();
|
||||
// This isn't optimal --- if aContext has a rotation then
|
||||
// GetClipExtents will have to do a bounding-box computation,
|
||||
// and TransformBounds might too, so we could get a better
|
||||
// result if we computed image space clip extents in one go
|
||||
// --- but it doesn't really matter and this is easier to
|
||||
// understand.
|
||||
gfxRect imageSpaceClipExtents =
|
||||
userSpaceToImageSpace.TransformBounds(userSpaceClipExtents);
|
||||
// Inflate by one pixel because bilinear filtering will sample
|
||||
// at most one pixel beyond the computed image pixel coordinate.
|
||||
imageSpaceClipExtents.Outset(1.0);
|
||||
|
||||
gfxRect needed =
|
||||
imageSpaceClipExtents.Intersect(sourceRect).Intersect(subimage);
|
||||
needed.RoundOut();
|
||||
// if 'needed' is empty, nothing will be drawn since aFill
|
||||
// must be entirely outside the clip region, so it doesn't
|
||||
// matter what we do here, but we should avoid trying to
|
||||
// create a zero-size surface.
|
||||
if (!needed.IsEmpty()) {
|
||||
gfxIntSize size(PRInt32(needed.Width()), PRInt32(needed.Height()));
|
||||
nsRefPtr<gfxASurface> temp =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, format);
|
||||
if (temp && temp->CairoStatus() == 0) {
|
||||
gfxContext tmpCtx(temp);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
nsRefPtr<gfxPattern> tmpPattern = new gfxPattern(surface);
|
||||
if (tmpPattern) {
|
||||
tmpPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
tmpPattern->SetMatrix(gfxMatrix().Translate(needed.pos));
|
||||
tmpCtx.SetPattern(tmpPattern);
|
||||
tmpCtx.Paint();
|
||||
tmpPattern = new gfxPattern(temp);
|
||||
if (tmpPattern) {
|
||||
pattern.swap(tmpPattern);
|
||||
pattern->SetMatrix(
|
||||
gfxMatrix(userSpaceToImageSpace).Multiply(gfxMatrix().Translate(-needed.pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In theory we can handle this using cairo's EXTEND_PAD,
|
||||
// but implementation limitations mean we have to consult
|
||||
// the surface type.
|
||||
switch (currentTarget->GetType()) {
|
||||
case gfxASurface::SurfaceTypeXlib:
|
||||
case gfxASurface::SurfaceTypeXcb: {
|
||||
// See bug 324698. This is a workaround for EXTEND_PAD not being
|
||||
// implemented correctly on linux in the X server.
|
||||
//
|
||||
// Set the filter to CAIRO_FILTER_FAST --- otherwise,
|
||||
// pixman's sampling will sample transparency for the outside edges and we'll
|
||||
// get blurry edges. CAIRO_EXTEND_PAD would also work here, if
|
||||
// available
|
||||
//
|
||||
// But don't do this for simple downscales because it's horrible.
|
||||
// Downscaling means that device-space coordinates are
|
||||
// scaled *up* to find the image pixel coordinates.
|
||||
//
|
||||
// deviceToImage is slightly stale because up above we may
|
||||
// have adjusted the pattern's matrix ... but the adjustment
|
||||
// is only a translation so the scale factors in deviceToImage
|
||||
// are still valid.
|
||||
PRBool isDownscale =
|
||||
deviceToImage.xx >= 1.0 && deviceToImage.yy >= 1.0 &&
|
||||
deviceToImage.xy == 0.0 && deviceToImage.yx == 0.0;
|
||||
if (!isDownscale) {
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gfxASurface::SurfaceTypeQuartz:
|
||||
case gfxASurface::SurfaceTypeQuartzImage:
|
||||
// Don't set EXTEND_PAD, Mac seems to be OK. Really?
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
|
||||
default:
|
||||
// turn on EXTEND_PAD.
|
||||
// This is what we really want for all surface types, if the
|
||||
// implementation was universally good.
|
||||
pattern->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == gfxContext::OPERATOR_OVER || pushedGroup) &&
|
||||
format == gfxASurface::ImageFormatRGB24) {
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
// Phew! Now we can actually draw this image
|
||||
aContext->NewPath();
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
#endif
|
||||
aContext->SetPattern(pattern);
|
||||
aContext->Rectangle(fill);
|
||||
aContext->Fill();
|
||||
|
||||
aContext->SetOperator(op);
|
||||
if (pushedGroup) {
|
||||
aContext->PopGroupToSource();
|
||||
aContext->Paint();
|
||||
aContext->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Extract(const nsIntRect& aRegion,
|
||||
nsIImage** aResult)
|
||||
{
|
||||
nsRefPtr<nsThebesImage> subImage(new nsThebesImage());
|
||||
if (!subImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// The scaling problems described in bug 468496 are especially
|
||||
// likely to be visible for the sub-image, as at present the only
|
||||
// user is the border-image code and border-images tend to get
|
||||
// stretched a lot. At the same time, the performance concerns
|
||||
// that prevent us from just using Cairo's fallback scaler when
|
||||
// accelerated graphics won't cut it are less relevant to such
|
||||
// images, since they also tend to be small. Thus, we forcibly
|
||||
// disable the use of anything other than a client-side image
|
||||
// surface for the sub-image; this ensures that the correct
|
||||
// (albeit slower) Cairo fallback scaler will be used.
|
||||
subImage->mNeverUseDeviceSurface = PR_TRUE;
|
||||
|
||||
// ->Init() is just going to convert this back, bleah.
|
||||
nsMaskRequirements maskReq;
|
||||
switch (mAlphaDepth) {
|
||||
case 0: maskReq = nsMaskRequirements_kNoMask; break;
|
||||
case 1: maskReq = nsMaskRequirements_kNeeds1Bit; break;
|
||||
case 8: maskReq = nsMaskRequirements_kNeeds8Bit; break;
|
||||
default:
|
||||
NS_NOTREACHED("impossible alpha depth");
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit; // safe
|
||||
}
|
||||
|
||||
nsresult rv = subImage->Init(aRegion.width, aRegion.height,
|
||||
8 /* ignored */, maskReq);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
{ // scope to destroy ctx
|
||||
gfxContext ctx(subImage->ThebesSurface());
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
ctx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
// SetSource() places point (0,0) of its first argument at
|
||||
// the coordinages given by its second argument. We want
|
||||
// (x,y) of the image to be (0,0) of source space, so we
|
||||
// put (0,0) of the image at (-x,-y).
|
||||
ctx.SetSource(this->ThebesSurface(),
|
||||
gfxPoint(-aRegion.x, -aRegion.y));
|
||||
}
|
||||
ctx.Rectangle(gfxRect(0, 0, aRegion.width, aRegion.height));
|
||||
ctx.Fill();
|
||||
}
|
||||
|
||||
nsIntRect filled(0, 0, aRegion.width, aRegion.height);
|
||||
subImage->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &filled);
|
||||
subImage->Optimize(nsnull);
|
||||
|
||||
NS_ADDREF(*aResult = subImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::ShouldUseImageSurfaces()
|
||||
{
|
||||
#if defined(WINCE)
|
||||
// There is no test on windows mobile to check for Gui resources.
|
||||
// Allocate, until we run out of memory.
|
||||
gfxWindowsPlatform::RenderMode rmode = gfxWindowsPlatform::GetPlatform()->GetRenderMode();
|
||||
return rmode != gfxWindowsPlatform::RENDER_DDRAW &&
|
||||
rmode != gfxWindowsPlatform::RENDER_DDRAW_GL;
|
||||
|
||||
#elif defined(USE_WIN_SURFACE)
|
||||
static const DWORD kGDIObjectsHighWaterMark = 7000;
|
||||
|
||||
// at 7000 GDI objects, stop allocating normal images to make sure
|
||||
// we never hit the 10k hard limit.
|
||||
// GetCurrentProcess() just returns (HANDLE)-1, it's inlined afaik
|
||||
DWORD count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
|
||||
if (count == 0 ||
|
||||
count > kGDIObjectsHighWaterMark)
|
||||
{
|
||||
// either something's broken (count == 0),
|
||||
// or we hit our high water mark; disable
|
||||
// image allocations for a bit.
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// A hint from the image decoders that this image has no alpha, even
|
||||
// though we created is ARGB32. This changes our format to RGB24,
|
||||
// which in turn will cause us to Optimize() to RGB24. Has no effect
|
||||
// after Optimize() is called, though in all cases it will be just a
|
||||
// performance win -- the pixels are still correct and have the A byte
|
||||
// set to 0xff.
|
||||
void
|
||||
nsThebesImage::SetHasNoAlpha()
|
||||
{
|
||||
if (mFormat == gfxASurface::ImageFormatARGB32) {
|
||||
mFormat = gfxASurface::ImageFormatRGB24;
|
||||
mFormatChanged = PR_TRUE;
|
||||
mAlphaDepth = 0;
|
||||
}
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** 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 thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.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 _NSTHEBESIMAGE_H_
|
||||
#define _NSTHEBESIMAGE_H_
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "gfxColor.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPattern.h"
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsSurface.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "gfxQuartzImageSurface.h"
|
||||
#endif
|
||||
|
||||
class nsThebesImage : public nsIImage
|
||||
{
|
||||
public:
|
||||
nsThebesImage();
|
||||
~nsThebesImage();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||
virtual PRInt32 GetBytesPix();
|
||||
virtual PRBool GetIsRowOrderTopToBottom();
|
||||
virtual PRInt32 GetWidth();
|
||||
virtual PRInt32 GetHeight();
|
||||
virtual PRUint8 *GetBits();
|
||||
virtual PRInt32 GetLineStride();
|
||||
virtual PRBool GetHasAlphaMask();
|
||||
virtual PRUint8 *GetAlphaBits();
|
||||
virtual PRInt32 GetAlphaLineStride();
|
||||
virtual PRBool GetIsImageComplete();
|
||||
virtual nsresult ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect);
|
||||
virtual nsresult Optimize(nsIDeviceContext* aContext);
|
||||
virtual nsColorMap *GetColorMap();
|
||||
|
||||
virtual void Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage);
|
||||
|
||||
virtual PRInt8 GetAlphaDepth();
|
||||
virtual void* GetBitInfo();
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
|
||||
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) {
|
||||
*aSurface = ThebesSurface();
|
||||
NS_ADDREF(*aSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetPattern(gfxPattern **aPattern) {
|
||||
if (mSinglePixel)
|
||||
*aPattern = new gfxPattern(mSinglePixelColor);
|
||||
else
|
||||
*aPattern = new gfxPattern(ThebesSurface());
|
||||
NS_ADDREF(*aPattern);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface() {
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
if (mWinSurface)
|
||||
return mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
if (mQuartzSurface)
|
||||
return mQuartzSurface;
|
||||
#endif
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
void SetHasNoAlpha();
|
||||
|
||||
NS_IMETHOD Extract(const nsIntRect& aSubimage,
|
||||
nsIImage** aResult NS_OUTPARAM);
|
||||
|
||||
protected:
|
||||
static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight) {
|
||||
NS_ASSERTION(aWidth > 0, "invalid image width");
|
||||
NS_ASSERTION(aHeight > 0, "invalid image height");
|
||||
|
||||
// reject over-wide or over-tall images
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if (NS_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) {
|
||||
NS_WARNING("image too big");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// protect against division by zero - this really shouldn't happen
|
||||
// if our consumers were well behaved, but they aren't (bug 368427)
|
||||
if (NS_UNLIKELY(aHeight == 0)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// check to make sure we don't overflow a 32-bit
|
||||
PRInt32 tmp = aWidth * aHeight;
|
||||
if (NS_UNLIKELY(tmp / aHeight != aWidth)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
tmp = tmp * 4;
|
||||
if (NS_UNLIKELY(tmp / 4 != aWidth * aHeight)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageFormat mFormat;
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
PRInt32 mStride;
|
||||
nsIntRect mDecoded;
|
||||
PRPackedBool mImageComplete;
|
||||
PRPackedBool mSinglePixel;
|
||||
PRPackedBool mFormatChanged;
|
||||
PRPackedBool mNeverUseDeviceSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
PRPackedBool mIsDDBSurface;
|
||||
#endif
|
||||
|
||||
gfxRGBA mSinglePixelColor;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
nsRefPtr<gfxASurface> mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
nsRefPtr<gfxWindowsSurface> mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
|
||||
#endif
|
||||
|
||||
PRUint8 mAlphaDepth;
|
||||
|
||||
// this function should return true if
|
||||
// we should (temporarily) not allocate any
|
||||
// platform native surfaces and instead use
|
||||
// image surfaces for everything.
|
||||
static PRBool ShouldUseImageSurfaces();
|
||||
};
|
||||
|
||||
#endif /* _NSTHEBESIMAGE_H_ */
|
@ -46,12 +46,7 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsThebesRegion.h"
|
||||
#include "nsThebesImage.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -54,8 +54,6 @@
|
||||
#include "nsIThebesFontMetrics.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
class nsIImage;
|
||||
|
||||
class nsThebesRenderingContext : public nsIRenderingContext
|
||||
{
|
||||
public:
|
||||
|
@ -3044,7 +3044,7 @@ class RegExpNativeCompiler {
|
||||
exit->re_flags = re->flags;
|
||||
exit->re_length = re_length;
|
||||
memcpy(exit->re_chars, re_chars, re_length * sizeof(jschar));
|
||||
fragment->lastIns = lir->insGuard(LIR_loop, NULL, skip);
|
||||
fragment->lastIns = lir->insGuard(LIR_loop, lir->insImm(1), skip);
|
||||
return guard;
|
||||
}
|
||||
|
||||
|
@ -3607,7 +3607,7 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote)
|
||||
}
|
||||
|
||||
if (!stable) {
|
||||
fragment->lastIns = lir->insGuard(LIR_x, NULL, createGuardRecord(exit));
|
||||
fragment->lastIns = lir->insGuard(LIR_x, lir->insImm(1), createGuardRecord(exit));
|
||||
|
||||
/*
|
||||
* If we didn't find a type stable peer, we compile the loop anyway and
|
||||
@ -3639,7 +3639,7 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote)
|
||||
}
|
||||
} else {
|
||||
exit->target = fragment->root;
|
||||
fragment->lastIns = lir->insGuard(LIR_loop, NULL, createGuardRecord(exit));
|
||||
fragment->lastIns = lir->insGuard(LIR_loop, lir->insImm(1), createGuardRecord(exit));
|
||||
}
|
||||
compile(tm);
|
||||
|
||||
@ -3766,7 +3766,7 @@ TraceRecorder::endLoop(JSTraceMonitor* tm)
|
||||
}
|
||||
|
||||
fragment->lastIns =
|
||||
lir->insGuard(LIR_x, NULL, createGuardRecord(snapshot(LOOP_EXIT)));
|
||||
lir->insGuard(LIR_x, lir->insImm(1), createGuardRecord(snapshot(LOOP_EXIT)));
|
||||
compile(tm);
|
||||
|
||||
if (tm->fragmento->assm()->error() != nanojit::None)
|
||||
@ -4058,7 +4058,7 @@ nanojit::LirNameMap::formatGuard(LIns *i, char *out)
|
||||
"%s: %s %s -> pc=%p imacpc=%p sp%+ld rp%+ld",
|
||||
formatRef(i),
|
||||
lirNames[i->opcode()],
|
||||
i->oprnd1() ? formatRef(i->oprnd1()) : "",
|
||||
i->oprnd1()->isCond() ? formatRef(i->oprnd1()) : "",
|
||||
(void *)x->pc,
|
||||
(void *)x->imacpc,
|
||||
(long int)x->sp_adj,
|
||||
@ -8582,7 +8582,7 @@ TraceRecorder::emitNativeCall(JSTraceableNative* known, uintN argc, LIns* args[]
|
||||
|
||||
// Tell nanojit not to discard or defer stack writes before this call.
|
||||
LIns* guardRec = createGuardRecord(exit);
|
||||
lir->insGuard(LIR_xbarrier, NULL, guardRec);
|
||||
lir->insGuard(LIR_xbarrier, guardRec, guardRec);
|
||||
}
|
||||
|
||||
LIns* res_ins = lir->insCall(known->builtin, args);
|
||||
@ -10263,7 +10263,7 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
|
||||
dslots_ins,
|
||||
-(int)sizeof(jsval))),
|
||||
NULL);
|
||||
lir->insGuard(LIR_x, NULL, createGuardRecord(exit));
|
||||
lir->insGuard(LIR_x, lir->insImm(1), createGuardRecord(exit));
|
||||
LIns* label = lir->ins0(LIR_label);
|
||||
if (br1)
|
||||
br1->setTarget(label);
|
||||
|
@ -638,7 +638,7 @@ LirasmAssembler::endFragment()
|
||||
memset(exit, 0, sizeof(SideExit));
|
||||
exit->guards = NULL;
|
||||
exit->from = exit->target = mFragment;
|
||||
mFragment->lastIns = mLir->insGuard(LIR_loop, NULL, exitIns);
|
||||
mFragment->lastIns = mLir->insGuard(LIR_loop, mLir->insImm(1), exitIns);
|
||||
|
||||
::compile(mParent->mFragmento->assm(), mFragment);
|
||||
|
||||
|
@ -270,14 +270,6 @@ namespace nanojit
|
||||
return ins;
|
||||
}
|
||||
|
||||
LInsp LirBufWriter::ins3(LOpcode op, LInsp o1, LInsp o2, LInsp o3)
|
||||
{
|
||||
LInsOp3* insOp3 = (LInsOp3*)_buf->makeRoom(sizeof(LInsOp3));
|
||||
LIns* ins = insOp3->getLIns();
|
||||
ins->initLInsOp3(op, o1, o2, o3);
|
||||
return ins;
|
||||
}
|
||||
|
||||
LInsp LirBufWriter::insLoad(LOpcode op, LInsp base, int32_t d)
|
||||
{
|
||||
LInsLd* insLd = (LInsLd*)_buf->makeRoom(sizeof(LInsLd));
|
||||
@ -413,7 +405,7 @@ namespace nanojit
|
||||
}
|
||||
iop = ((LInsp)i)->opcode();
|
||||
}
|
||||
while (LIR_skip == iop);
|
||||
while (iop==LIR_skip || iop==LIR_2);
|
||||
_i = (LInsp)i;
|
||||
return cur;
|
||||
}
|
||||
@ -449,11 +441,6 @@ namespace nanojit
|
||||
return LRK_Op2 == repKinds[opcode()];
|
||||
}
|
||||
|
||||
bool LIns::isLInsOp3() const {
|
||||
NanoAssert(LRK_None != repKinds[opcode()]);
|
||||
return LRK_Op3 == repKinds[opcode()];
|
||||
}
|
||||
|
||||
bool LIns::isLInsLd() const {
|
||||
NanoAssert(LRK_None != repKinds[opcode()]);
|
||||
return LRK_Ld == repKinds[opcode()];
|
||||
@ -660,6 +647,16 @@ namespace nanojit
|
||||
LIns* ExprFilter::ins2(LOpcode v, LIns* oprnd1, LIns* oprnd2)
|
||||
{
|
||||
NanoAssert(oprnd1 && oprnd2);
|
||||
if (v == LIR_cmov || v == LIR_qcmov) {
|
||||
if (oprnd2->oprnd1() == oprnd2->oprnd2()) {
|
||||
// c ? a : a => a
|
||||
return oprnd2->oprnd1();
|
||||
}
|
||||
if (oprnd1->isconst()) {
|
||||
// const ? x : y => return x or y depending on const
|
||||
return oprnd1->imm32() ? oprnd2->oprnd1() : oprnd2->oprnd2();
|
||||
}
|
||||
}
|
||||
if (oprnd1 == oprnd2)
|
||||
{
|
||||
switch (v) {
|
||||
@ -893,22 +890,6 @@ namespace nanojit
|
||||
return out->ins2(v, oprnd1, oprnd2);
|
||||
}
|
||||
|
||||
LIns* ExprFilter::ins3(LOpcode v, LIns* oprnd1, LIns* oprnd2, LIns* oprnd3)
|
||||
{
|
||||
NanoAssert(oprnd1 && oprnd2 && oprnd3);
|
||||
NanoAssert(v == LIR_cmov || v == LIR_qcmov);
|
||||
if (oprnd2 == oprnd3) {
|
||||
// c ? a : a => a
|
||||
return oprnd2;
|
||||
}
|
||||
if (oprnd1->isconst()) {
|
||||
// const ? x : y => return x or y depending on const
|
||||
return oprnd1->imm32() ? oprnd2 : oprnd3;
|
||||
}
|
||||
|
||||
return out->ins3(v, oprnd1, oprnd2, oprnd3);
|
||||
}
|
||||
|
||||
LIns* ExprFilter::insGuard(LOpcode v, LInsp c, LInsp x)
|
||||
{
|
||||
if (v == LIR_xt || v == LIR_xf) {
|
||||
@ -925,7 +906,7 @@ namespace nanojit
|
||||
// so assert in debug builds.
|
||||
NanoAssertMsg(0, "Constantly false guard detected");
|
||||
#endif
|
||||
return out->insGuard(LIR_x, NULL, x);
|
||||
return out->insGuard(LIR_x, out->insImm(1), x);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -995,7 +976,7 @@ namespace nanojit
|
||||
}
|
||||
|
||||
if (avmplus::AvmCore::use_cmov())
|
||||
return ins3((iftrue->isQuad() || iffalse->isQuad()) ? LIR_qcmov : LIR_cmov, cond, iftrue, iffalse);
|
||||
return ins2((iftrue->isQuad() || iffalse->isQuad()) ? LIR_qcmov : LIR_cmov, cond, ins2(LIR_2, iftrue, iffalse));
|
||||
|
||||
LInsp ncond = ins1(LIR_neg, cond); // cond ? -1 : 0
|
||||
return ins2(LIR_or,
|
||||
@ -1193,9 +1174,7 @@ namespace nanojit
|
||||
return hashLoad(op, i->oprnd1(), i->disp());
|
||||
|
||||
default:
|
||||
if (operandCount[op] == 3)
|
||||
return hash3(op, i->oprnd1(), i->oprnd2(), i->oprnd3());
|
||||
else if (operandCount[op] == 2)
|
||||
if (operandCount[op] == 2)
|
||||
return hash2(op, i->oprnd1(), i->oprnd2());
|
||||
else
|
||||
return hash1(op, i->oprnd1());
|
||||
@ -1248,8 +1227,7 @@ namespace nanojit
|
||||
{
|
||||
const uint32_t count = operandCount[op];
|
||||
if ((count >= 1 && a->oprnd1() != b->oprnd1()) ||
|
||||
(count >= 2 && a->oprnd2() != b->oprnd2()) ||
|
||||
(count >= 3 && a->oprnd3() != b->oprnd3()))
|
||||
(count >= 2 && a->oprnd2() != b->oprnd2()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -1335,13 +1313,6 @@ namespace nanojit
|
||||
return _hashfinish(_hashptr(hash, b));
|
||||
}
|
||||
|
||||
uint32_t LInsHashSet::hash3(LOpcode op, LInsp a, LInsp b, LInsp c) {
|
||||
uint32_t hash = _hash8(0,uint8_t(op));
|
||||
hash = _hashptr(hash, a);
|
||||
hash = _hashptr(hash, b);
|
||||
return _hashfinish(_hashptr(hash, c));
|
||||
}
|
||||
|
||||
uint32_t LInsHashSet::hashLoad(LOpcode op, LInsp a, int32_t d) {
|
||||
uint32_t hash = _hash8(0,uint8_t(op));
|
||||
hash = _hashptr(hash, a);
|
||||
@ -1423,23 +1394,6 @@ namespace nanojit
|
||||
return k;
|
||||
}
|
||||
|
||||
LInsp LInsHashSet::find3(LOpcode op, LInsp a, LInsp b, LInsp c, uint32_t &i)
|
||||
{
|
||||
uint32_t cap = m_cap;
|
||||
const LInsp *list = m_list;
|
||||
const uint32_t bitmask = (cap - 1) & ~0x1;
|
||||
uint32_t hash = hash3(op,a,b,c) & bitmask;
|
||||
uint32_t n = 7 << 1;
|
||||
LInsp k;
|
||||
while ((k = list[hash]) != NULL &&
|
||||
(k->opcode() != op || k->oprnd1() != a || k->oprnd2() != b || k->oprnd3() != c))
|
||||
{
|
||||
hash = (hash + (n += 2)) & bitmask; // quadratic probe
|
||||
}
|
||||
i = hash;
|
||||
return k;
|
||||
}
|
||||
|
||||
LInsp LInsHashSet::findLoad(LOpcode op, LInsp a, int32_t d, uint32_t &i)
|
||||
{
|
||||
uint32_t cap = m_cap;
|
||||
@ -1960,17 +1914,6 @@ namespace nanojit
|
||||
return out->ins2(v,a,b);
|
||||
}
|
||||
|
||||
LIns* CseFilter::ins3(LOpcode v, LInsp a, LInsp b, LInsp c)
|
||||
{
|
||||
NanoAssert(isCseOpcode(v));
|
||||
NanoAssert(operandCount[v]==3);
|
||||
uint32_t k;
|
||||
LInsp found = exprs.find3(v, a, b, c, k);
|
||||
if (found)
|
||||
return found;
|
||||
return exprs.add(out->ins3(v,a,b,c), k);
|
||||
}
|
||||
|
||||
LIns* CseFilter::insLoad(LOpcode v, LInsp base, int32_t disp)
|
||||
{
|
||||
if (isCseOpcode(v)) {
|
||||
|
@ -280,7 +280,6 @@ namespace nanojit
|
||||
LRK_Op0,
|
||||
LRK_Op1,
|
||||
LRK_Op2,
|
||||
LRK_Op3,
|
||||
LRK_Ld,
|
||||
LRK_Sti,
|
||||
LRK_Sk,
|
||||
@ -335,24 +334,6 @@ namespace nanojit
|
||||
LIns* getLIns() { return (LIns*)&ins; };
|
||||
};
|
||||
|
||||
// 3-operand form. Used for conditional moves.
|
||||
class LInsOp3
|
||||
{
|
||||
private:
|
||||
friend class LIns;
|
||||
|
||||
LIns* oprnd_3;
|
||||
|
||||
LIns* oprnd_2;
|
||||
|
||||
LIns* oprnd_1;
|
||||
|
||||
void* ins;
|
||||
|
||||
public:
|
||||
LIns* getLIns() { return (LIns*)&ins; };
|
||||
};
|
||||
|
||||
// Used for all loads.
|
||||
class LInsLd
|
||||
{
|
||||
@ -479,7 +460,6 @@ namespace nanojit
|
||||
LInsOp0* toLInsOp0() const { return (LInsOp0*)( uintptr_t(this+1) - sizeof(LInsOp0) ); }
|
||||
LInsOp1* toLInsOp1() const { return (LInsOp1*)( uintptr_t(this+1) - sizeof(LInsOp1) ); }
|
||||
LInsOp2* toLInsOp2() const { return (LInsOp2*)( uintptr_t(this+1) - sizeof(LInsOp2) ); }
|
||||
LInsOp3* toLInsOp3() const { return (LInsOp3*)( uintptr_t(this+1) - sizeof(LInsOp3) ); }
|
||||
LInsLd* toLInsLd() const { return (LInsLd* )( uintptr_t(this+1) - sizeof(LInsLd ) ); }
|
||||
LInsSti* toLInsSti() const { return (LInsSti*)( uintptr_t(this+1) - sizeof(LInsSti) ); }
|
||||
LInsSk* toLInsSk() const { return (LInsSk* )( uintptr_t(this+1) - sizeof(LInsSk ) ); }
|
||||
@ -499,7 +479,6 @@ namespace nanojit
|
||||
NanoStaticAssert(sizeof(LInsOp0) == 1*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsOp1) == 2*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsOp2) == 3*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsOp3) == 4*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsLd) == 3*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsSti) == 4*sizeof(void*));
|
||||
NanoStaticAssert(sizeof(LInsSk) == 2*sizeof(void*));
|
||||
@ -512,22 +491,18 @@ namespace nanojit
|
||||
NanoStaticAssert(sizeof(LInsI64) == 3*sizeof(void*));
|
||||
#endif
|
||||
|
||||
// oprnd_1 must be in the same position in LIns{Op1,Op2,Op3,Ld,Sti}
|
||||
// oprnd_1 must be in the same position in LIns{Op1,Op2,Ld,Sti}
|
||||
// because oprnd1() is used for all of them.
|
||||
NanoStaticAssert( (offsetof(LInsOp1, ins) - offsetof(LInsOp1, oprnd_1)) ==
|
||||
(offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_1)) );
|
||||
NanoStaticAssert( (offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_1)) ==
|
||||
(offsetof(LInsOp3, ins) - offsetof(LInsOp3, oprnd_1)) );
|
||||
NanoStaticAssert( (offsetof(LInsOp3, ins) - offsetof(LInsOp3, oprnd_1)) ==
|
||||
(offsetof(LInsLd, ins) - offsetof(LInsLd, oprnd_1)) );
|
||||
NanoStaticAssert( (offsetof(LInsLd, ins) - offsetof(LInsLd, oprnd_1)) ==
|
||||
(offsetof(LInsSti, ins) - offsetof(LInsSti, oprnd_1)) );
|
||||
|
||||
// oprnd_2 must be in the same position in LIns{Op2,Op3,Sti}
|
||||
// oprnd_2 must be in the same position in LIns{Op2,Sti}
|
||||
// because oprnd2() is used for both of them.
|
||||
NanoStaticAssert( (offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_2)) ==
|
||||
(offsetof(LInsOp3, ins) - offsetof(LInsOp3, oprnd_2)) );
|
||||
NanoStaticAssert( (offsetof(LInsOp3, ins) - offsetof(LInsOp3, oprnd_2)) ==
|
||||
(offsetof(LInsSti, ins) - offsetof(LInsSti, oprnd_2)) );
|
||||
}
|
||||
|
||||
@ -550,14 +525,6 @@ namespace nanojit
|
||||
toLInsOp2()->oprnd_2 = oprnd2;
|
||||
NanoAssert(isLInsOp2());
|
||||
}
|
||||
void initLInsOp3(LOpcode opcode, LIns* oprnd1, LIns* oprnd2, LIns* oprnd3) {
|
||||
lastWord.clear();
|
||||
lastWord.opcode = opcode;
|
||||
toLInsOp3()->oprnd_1 = oprnd1;
|
||||
toLInsOp3()->oprnd_2 = oprnd2;
|
||||
toLInsOp3()->oprnd_3 = oprnd3;
|
||||
NanoAssert(isLInsOp3());
|
||||
}
|
||||
void initLInsLd(LOpcode opcode, LIns* val, int32_t d) {
|
||||
lastWord.clear();
|
||||
lastWord.opcode = opcode;
|
||||
@ -612,17 +579,13 @@ namespace nanojit
|
||||
}
|
||||
|
||||
LIns* oprnd1() const {
|
||||
NanoAssert(isLInsOp1() || isLInsOp2() || isLInsOp3() || isLInsLd() || isLInsSti());
|
||||
NanoAssert(isLInsOp1() || isLInsOp2() || isLInsLd() || isLInsSti());
|
||||
return toLInsOp2()->oprnd_1;
|
||||
}
|
||||
LIns* oprnd2() const {
|
||||
NanoAssert(isLInsOp2() || isLInsOp3() || isLInsSti());
|
||||
NanoAssert(isLInsOp2() || isLInsSti());
|
||||
return toLInsOp2()->oprnd_2;
|
||||
}
|
||||
LIns* oprnd3() const {
|
||||
NanoAssert(isLInsOp3());
|
||||
return toLInsOp3()->oprnd_3;
|
||||
}
|
||||
|
||||
LIns* prevLIns() const {
|
||||
NanoAssert(isLInsSk());
|
||||
@ -678,7 +641,6 @@ namespace nanojit
|
||||
bool isLInsOp0() const;
|
||||
bool isLInsOp1() const;
|
||||
bool isLInsOp2() const;
|
||||
bool isLInsOp3() const;
|
||||
bool isLInsSti() const;
|
||||
bool isLInsLd() const;
|
||||
bool isLInsSk() const;
|
||||
@ -773,9 +735,6 @@ namespace nanojit
|
||||
virtual LInsp ins2(LOpcode v, LIns* a, LIns* b) {
|
||||
return out->ins2(v, a, b);
|
||||
}
|
||||
virtual LInsp ins3(LOpcode v, LIns* a, LIns* b, LIns* c) {
|
||||
return out->ins3(v, a, b, c);
|
||||
}
|
||||
virtual LInsp insGuard(LOpcode v, LIns *c, LIns *x) {
|
||||
return out->insGuard(v, c, x);
|
||||
}
|
||||
@ -973,10 +932,7 @@ namespace nanojit
|
||||
return isRetOpcode(v) ? add_flush(out->ins1(v, a)) : add(out->ins1(v, a));
|
||||
}
|
||||
LIns* ins2(LOpcode v, LInsp a, LInsp b) {
|
||||
return add(out->ins2(v, a, b));
|
||||
}
|
||||
LIns* ins3(LOpcode v, LInsp a, LInsp b, LInsp c) {
|
||||
return add(out->ins3(v, a, b, c));
|
||||
return v == LIR_2 ? out->ins2(v,a,b) : add(out->ins2(v, a, b));
|
||||
}
|
||||
LIns* insCall(const CallInfo *call, LInsp args[]) {
|
||||
return add_flush(out->insCall(call, args));
|
||||
@ -1009,7 +965,6 @@ namespace nanojit
|
||||
ExprFilter(LirWriter *out) : LirWriter(out) {}
|
||||
LIns* ins1(LOpcode v, LIns* a);
|
||||
LIns* ins2(LOpcode v, LIns* a, LIns* b);
|
||||
LIns* ins3(LOpcode v, LIns* a, LIns* b, LIns* c);
|
||||
LIns* insGuard(LOpcode, LIns *cond, LIns *);
|
||||
LIns* insBranch(LOpcode, LIns *cond, LIns *target);
|
||||
};
|
||||
@ -1032,13 +987,13 @@ namespace nanojit
|
||||
void FASTCALL grow();
|
||||
|
||||
public:
|
||||
|
||||
LInsHashSet(GC* gc);
|
||||
~LInsHashSet();
|
||||
LInsp find32(int32_t a, uint32_t &i);
|
||||
LInsp find64(uint64_t a, uint32_t &i);
|
||||
LInsp find1(LOpcode v, LInsp a, uint32_t &i);
|
||||
LInsp find2(LOpcode v, LInsp a, LInsp b, uint32_t &i);
|
||||
LInsp find3(LOpcode v, LInsp a, LInsp b, LInsp c, uint32_t &i);
|
||||
LInsp findLoad(LOpcode v, LInsp a, int32_t b, uint32_t &i);
|
||||
LInsp findcall(const CallInfo *call, uint32_t argc, LInsp args[], uint32_t &i);
|
||||
LInsp add(LInsp i, uint32_t k);
|
||||
@ -1049,7 +1004,6 @@ namespace nanojit
|
||||
static uint32_t FASTCALL hashimmq(uint64_t);
|
||||
static uint32_t FASTCALL hash1(LOpcode v, LInsp);
|
||||
static uint32_t FASTCALL hash2(LOpcode v, LInsp, LInsp);
|
||||
static uint32_t FASTCALL hash3(LOpcode v, LInsp, LInsp, LInsp);
|
||||
static uint32_t FASTCALL hashLoad(LOpcode v, LInsp, int32_t);
|
||||
static uint32_t FASTCALL hashcall(const CallInfo *call, uint32_t argc, LInsp args[]);
|
||||
};
|
||||
@ -1064,7 +1018,6 @@ namespace nanojit
|
||||
LIns* ins0(LOpcode v);
|
||||
LIns* ins1(LOpcode v, LInsp);
|
||||
LIns* ins2(LOpcode v, LInsp, LInsp);
|
||||
LIns* ins3(LOpcode v, LInsp, LInsp, LInsp);
|
||||
LIns* insLoad(LOpcode op, LInsp cond, int32_t d);
|
||||
LIns* insCall(const CallInfo *call, LInsp args[]);
|
||||
LIns* insGuard(LOpcode op, LInsp cond, LIns *x);
|
||||
@ -1124,7 +1077,6 @@ namespace nanojit
|
||||
LInsp ins0(LOpcode op);
|
||||
LInsp ins1(LOpcode op, LInsp o1);
|
||||
LInsp ins2(LOpcode op, LInsp o1, LInsp o2);
|
||||
LInsp ins3(LOpcode op, LInsp o1, LInsp o2, LInsp o3);
|
||||
LInsp insParam(int32_t i, int32_t kind);
|
||||
LInsp insImm(int32_t imm);
|
||||
LInsp insImmq(uint64_t imm);
|
||||
|
@ -107,7 +107,7 @@ OPDEF(ji, 23,-1, None) // indirect jump (currently not implemented)
|
||||
*/
|
||||
|
||||
OPDEF(int, 24, 0, I) // constant 32-bit integer
|
||||
OPDEF(cmov, 25, 3, Op3) // conditional move
|
||||
OPDEF(cmov, 25, 2, Op2) // conditional move (op1=cond, op2=LIR_2(iftrue,iffalse))
|
||||
#if defined(NANOJIT_64BIT)
|
||||
OPDEF(callh, 26,-1, None) // unused on 64-bit machines
|
||||
#else
|
||||
@ -179,8 +179,7 @@ OPDEF(ugt, 61, 2, Op2) // unsigned integer greater-than (0x3D
|
||||
OPDEF(ule, 62, 2, Op2) // unsigned integer less-than-or-equal (0x3E 0011 1110)
|
||||
OPDEF(uge, 63, 2, Op2) // unsigned integer greater-than-or-equal (0x3F 0011 1111)
|
||||
|
||||
OPDEF64(unused0_64, 0,-1, None)
|
||||
|
||||
OPDEF64(2, 0, 2, Op2) // wraps a pair of refs, for LIR_cmov or LIR_qcmov
|
||||
OPDEF64(file, 1, 2, Op1) // source filename for debug symbols
|
||||
OPDEF64(line, 2, 2, Op1) // source line number for debug symbols
|
||||
OPDEF64(xbarrier, 3, 1, Op2) // memory barrier; doesn't exit, but flushes all values to the stack
|
||||
@ -217,7 +216,7 @@ OPDEF64(unused23_64, 23,-1, None)
|
||||
// this marker are subject to CSE.
|
||||
|
||||
OPDEF64(quad, LIR_int, 0, I64) // 64-bit (quad) constant value
|
||||
OPDEF64(qcmov, LIR_cmov, 3, Op3) // 64-bit conditional move
|
||||
OPDEF64(qcmov, LIR_cmov, 2, Op2) // 64-bit conditional move
|
||||
|
||||
OPDEF64(unused26_64, 26,-1, None)
|
||||
OPDEF64(unused27_64, 27,-1, None)
|
||||
|
@ -2219,10 +2219,14 @@ Assembler::asm_cmov(LInsp ins)
|
||||
{
|
||||
NanoAssert(ins->opcode() == LIR_cmov);
|
||||
LIns* condval = ins->oprnd1();
|
||||
LIns* iftrue = ins->oprnd2();
|
||||
LIns* iffalse = ins->oprnd3();
|
||||
|
||||
NanoAssert(condval->isCmp());
|
||||
|
||||
LIns* values = ins->oprnd2();
|
||||
|
||||
NanoAssert(values->opcode() == LIR_2);
|
||||
LIns* iftrue = values->oprnd1();
|
||||
LIns* iffalse = values->oprnd2();
|
||||
|
||||
NanoAssert(!iftrue->isQuad() && !iffalse->isQuad());
|
||||
|
||||
const Register rr = prepResultReg(ins, GpRegs);
|
||||
|
@ -764,10 +764,14 @@ namespace nanojit
|
||||
underrunProtect(4);
|
||||
LOpcode op = ins->opcode();
|
||||
LIns* condval = ins->oprnd1();
|
||||
LIns* iftrue = ins->oprnd2();
|
||||
LIns* iffalse = ins->oprnd3();
|
||||
|
||||
NanoAssert(condval->isCmp());
|
||||
|
||||
LIns* values = ins->oprnd2();
|
||||
|
||||
NanoAssert(values->opcode() == LIR_2);
|
||||
LIns* iftrue = values->oprnd1();
|
||||
LIns* iffalse = values->oprnd2();
|
||||
|
||||
NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad()));
|
||||
|
||||
const Register rr = prepResultReg(ins, GpRegs);
|
||||
|
@ -1059,10 +1059,14 @@ namespace nanojit
|
||||
{
|
||||
LOpcode op = ins->opcode();
|
||||
LIns* condval = ins->oprnd1();
|
||||
LIns* iftrue = ins->oprnd2();
|
||||
LIns* iffalse = ins->oprnd3();
|
||||
|
||||
NanoAssert(condval->isCmp());
|
||||
|
||||
LIns* values = ins->oprnd2();
|
||||
|
||||
NanoAssert(values->opcode() == LIR_2);
|
||||
LIns* iftrue = values->oprnd1();
|
||||
LIns* iffalse = values->oprnd2();
|
||||
|
||||
NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad()));
|
||||
|
||||
const Register rr = prepResultReg(ins, GpRegs);
|
||||
|
@ -11792,6 +11792,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run()
|
||||
// this is hard-coded to handle only menu popup frames
|
||||
nsIFrame* frame = mPresShell->GetPrimaryFrameFor(mContent);
|
||||
if (frame && frame->GetType() == nsGkAtoms::menuPopupFrame) {
|
||||
nsWeakFrame weakFrame(frame);
|
||||
#ifdef MOZ_XUL
|
||||
// it is possible that the frame is different than the one that requested
|
||||
// the lazy generation, but as long as it's a popup frame that hasn't
|
||||
@ -11827,7 +11828,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run()
|
||||
fc->EndUpdate();
|
||||
}
|
||||
|
||||
if (mCallback)
|
||||
if (mCallback && weakFrame.IsAlive())
|
||||
mCallback(mContent, frame, mArg);
|
||||
|
||||
// call XBL constructors after the frames are created
|
||||
|
@ -46,7 +46,6 @@
|
||||
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
@ -63,7 +62,6 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSColorUtils.h"
|
||||
#include "nsITheme.h"
|
||||
@ -321,7 +319,7 @@ static void DrawBorderImage(nsPresContext* aPresContext,
|
||||
|
||||
static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||
nsIFrame* aForFrame,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aFill,
|
||||
const nsIntRect& aSrc,
|
||||
@ -1687,27 +1685,9 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
drawBackgroundColor) {
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
bottomImage->GetImage(getter_AddRefs(image));
|
||||
// If the image is completely opaque, we may not need to paint
|
||||
// the background color.
|
||||
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
|
||||
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
|
||||
if (gfxImgFrame) {
|
||||
gfxImgFrame->GetNeedsBackground(&drawBackgroundColor);
|
||||
if (!drawBackgroundColor) {
|
||||
// If the current frame is smaller than its container, we
|
||||
// need to paint the background color even if the frame
|
||||
// itself is opaque.
|
||||
nsIntSize iSize;
|
||||
image->GetWidth(&iSize.width);
|
||||
image->GetHeight(&iSize.height);
|
||||
nsIntRect iframeRect;
|
||||
gfxImgFrame->GetRect(iframeRect);
|
||||
if (iSize.width != iframeRect.width ||
|
||||
iSize.height != iframeRect.height) {
|
||||
drawBackgroundColor = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
PRBool isOpaque;
|
||||
if (NS_SUCCEEDED(image->GetCurrentFrameIsOpaque(&isOpaque)) && isOpaque)
|
||||
drawBackgroundColor = PR_FALSE;
|
||||
}
|
||||
|
||||
// The background color is rendered over the entire dirty area,
|
||||
@ -1938,18 +1918,6 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
imgContainer->GetWidth(&imageSize.width);
|
||||
imgContainer->GetHeight(&imageSize.height);
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
// The inner rectangle should precisely enclose the image pixels for
|
||||
// this frame.
|
||||
NS_ASSERTION(innerRect.width == img->GetWidth(), "img inner width off");
|
||||
NS_ASSERTION(innerRect.height == img->GetHeight(), "img inner height off");
|
||||
|
||||
// Convert percentages and clamp values to the image size.
|
||||
nsIntMargin split;
|
||||
NS_FOR_CSS_SIDES(s) {
|
||||
@ -1983,7 +1951,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
// These helper tables recharacterize the 'split' and 'border' margins
|
||||
// in a more convenient form: they are the x/y/width/height coords
|
||||
// required for various bands of the border, and they have been transformed
|
||||
// to be relative to the innerRect (for 'split') or the page (for 'border').
|
||||
// to be relative to the image (for 'split') or the page (for 'border').
|
||||
enum {
|
||||
LEFT, MIDDLE, RIGHT,
|
||||
TOP = LEFT, BOTTOM = RIGHT
|
||||
@ -2010,14 +1978,14 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
};
|
||||
|
||||
const PRInt32 splitX[3] = {
|
||||
-innerRect.x + 0,
|
||||
-innerRect.x + split.left,
|
||||
-innerRect.x + imageSize.width - split.right,
|
||||
0,
|
||||
split.left,
|
||||
imageSize.width - split.right,
|
||||
};
|
||||
const PRInt32 splitY[3] = {
|
||||
-innerRect.y + 0,
|
||||
-innerRect.y + split.top,
|
||||
-innerRect.y + imageSize.height - split.bottom,
|
||||
0,
|
||||
split.top,
|
||||
imageSize.height - split.bottom,
|
||||
};
|
||||
const PRInt32 splitWidth[3] = {
|
||||
split.left,
|
||||
@ -2108,7 +2076,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
DrawBorderImageComponent(aRenderingContext, aForFrame,
|
||||
img, aDirtyRect,
|
||||
imgContainer, aDirtyRect,
|
||||
destArea, subArea,
|
||||
fillStyleH, fillStyleV, unitSize);
|
||||
}
|
||||
@ -2118,7 +2086,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
static void
|
||||
DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||
nsIFrame* aForFrame,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aFill,
|
||||
const nsIntRect& aSrc,
|
||||
@ -2129,8 +2097,8 @@ DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||
if (aFill.IsEmpty() || aSrc.IsEmpty())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIImage> subImage;
|
||||
if (NS_FAILED(aImage->Extract(aSrc, getter_AddRefs(subImage))))
|
||||
nsCOMPtr<imgIContainer> subImage;
|
||||
if (NS_FAILED(aImage->ExtractCurrentFrame(aSrc, getter_AddRefs(subImage))))
|
||||
return;
|
||||
|
||||
gfxPattern::GraphicsFilter graphicsFilter =
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
@ -56,7 +55,6 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSColorUtils.h"
|
||||
#include "nsITheme.h"
|
||||
|
@ -58,9 +58,7 @@
|
||||
#endif
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
PRBool aIsForEvents, PRBool aBuildCaret)
|
||||
@ -555,18 +553,12 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
bottomLayer.mImage->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
PRUint32 nframes;
|
||||
container->GetNumFrames(&nframes);
|
||||
if (nframes == 1) {
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
container->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (imgFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
|
||||
PRBool hasMask = img->GetHasAlphaMask();
|
||||
|
||||
return !hasMask;
|
||||
}
|
||||
PRBool animated;
|
||||
container->GetAnimated(&animated);
|
||||
if (!animated) {
|
||||
PRBool isOpaque;
|
||||
if (NS_SUCCEEDED(container->GetCurrentFrameIsOpaque(&isOpaque)))
|
||||
return isOpaque;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ NS_IMETHODIMP nsImageLoader::OnStartContainer(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -182,7 +182,6 @@ NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame);
|
||||
// Do not override OnDataAvailable since background images are not
|
||||
// displayed incrementally; they are displayed after the entire image
|
||||
// has been loaded.
|
||||
@ -78,8 +78,7 @@ public:
|
||||
// incrementally in nsImageFrame.cpp.
|
||||
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
void Destroy();
|
||||
|
||||
|
@ -61,12 +61,10 @@
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxFont.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -2732,14 +2730,13 @@ MapToFloatUserPixels(const gfxSize& aSize,
|
||||
|
||||
static nsresult
|
||||
DrawImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aDest.IsEmpty() || aFill.IsEmpty())
|
||||
return NS_OK;
|
||||
@ -2839,22 +2836,18 @@ DrawImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
if (finalFillRect.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsIntMargin padding(aInnerRect.x, aInnerRect.y,
|
||||
imageSize.width - aInnerRect.XMost(),
|
||||
imageSize.height - aInnerRect.YMost());
|
||||
aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, padding, intSubimage);
|
||||
aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, intSubimage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Workhorse for DrawSingleUnscaledImage. */
|
||||
static nsresult
|
||||
DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsPoint& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aImageSize.width == 0 || aImageSize.height == 0)
|
||||
return NS_OK;
|
||||
@ -2877,19 +2870,18 @@ DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
// translation but we don't want to actually tile the image.
|
||||
fill.IntersectRect(fill, dest);
|
||||
return DrawImageInternal(aRenderingContext, aImage, gfxPattern::FILTER_NEAREST,
|
||||
dest, fill, aDest, aDirty, aImageSize, aInnerRect);
|
||||
dest, fill, aDest, aDirty, aImageSize);
|
||||
}
|
||||
|
||||
/* Workhorse for DrawSingleImage. */
|
||||
static nsresult
|
||||
DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aImageSize.width == 0 || aImageSize.height == 0)
|
||||
return NS_OK;
|
||||
@ -2911,7 +2903,7 @@ DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsRect fill;
|
||||
fill.IntersectRect(aDest, dest);
|
||||
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter, dest, fill,
|
||||
fill.TopLeft(), aDirty, aImageSize, aInnerRect);
|
||||
fill.TopLeft(), aDirty, aImageSize);
|
||||
}
|
||||
|
||||
/* The exposed Draw*Image functions just do interface conversion and call the
|
||||
@ -2926,38 +2918,13 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawImageInternal(aRenderingContext, img, aGraphicsFilter,
|
||||
aDest, aFill, aAnchor, aDirty,
|
||||
imageSize, innerRect);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty)
|
||||
{
|
||||
nsIntSize imageSize(aImage->GetWidth(), aImage->GetHeight());
|
||||
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter,
|
||||
aDest, aFill, aAnchor, aDirty,
|
||||
imageSize, nsIntRect(nsIntPoint(0,0), imageSize));
|
||||
imageSize);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
@ -2967,23 +2934,13 @@ nsLayoutUtils::DrawSingleUnscaledImage(nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawSingleUnscaledImageInternal(aRenderingContext, img,
|
||||
return DrawSingleUnscaledImageInternal(aRenderingContext, aImage,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize, innerRect);
|
||||
imageSize);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
@ -2994,41 +2951,15 @@ nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawSingleImageInternal(aRenderingContext, img, aGraphicsFilter,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize, innerRect);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsIntSize imageSize(aImage->GetWidth(), aImage->GetHeight());
|
||||
return DrawSingleImageInternal(aRenderingContext, aImage, aGraphicsFilter,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize,
|
||||
nsIntRect(nsIntPoint(0, 0), imageSize));
|
||||
imageSize);
|
||||
}
|
||||
|
||||
|
||||
/* static */ nsRect
|
||||
nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
|
||||
const nsRect& aImageSourceArea,
|
||||
@ -3386,7 +3317,6 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
||||
#endif
|
||||
|
||||
// Finally, check if it's a normal image
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aElement);
|
||||
|
||||
if (!imageLoader)
|
||||
@ -3425,34 +3355,28 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
||||
return result;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
if (NS_FAILED(rv) || !imgContainer)
|
||||
return result;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
|
||||
nsRefPtr<gfxASurface> framesurf;
|
||||
rv = imgContainer->GetCurrentFrame(getter_AddRefs(framesurf));
|
||||
if (NS_FAILED(rv))
|
||||
return result;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
|
||||
if (!img)
|
||||
return result;
|
||||
|
||||
PRInt32 imgWidth, imgHeight;
|
||||
rv = frame->GetWidth(&imgWidth);
|
||||
rv |= frame->GetHeight(&imgHeight);
|
||||
rv = imgContainer->GetWidth(&imgWidth);
|
||||
rv |= imgContainer->GetHeight(&imgHeight);
|
||||
if (NS_FAILED(rv))
|
||||
return result;
|
||||
|
||||
nsRefPtr<gfxPattern> gfxpattern;
|
||||
img->GetPattern(getter_AddRefs(gfxpattern));
|
||||
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
|
||||
|
||||
if (wantImageSurface && gfxsurf->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
if (wantImageSurface && framesurf->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
forceCopy = PR_TRUE;
|
||||
}
|
||||
|
||||
if (forceCopy || !gfxsurf) {
|
||||
nsRefPtr<gfxASurface> gfxsurf = framesurf;
|
||||
if (forceCopy) {
|
||||
if (wantImageSurface) {
|
||||
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
|
||||
} else {
|
||||
@ -3463,7 +3387,7 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
|
||||
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetPattern(gfxpattern);
|
||||
ctx->SetSource(framesurf);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
|
@ -862,14 +862,6 @@ public:
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty);
|
||||
|
||||
static nsresult DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty);
|
||||
|
||||
/**
|
||||
* Draw a whole image without scaling or tiling.
|
||||
*
|
||||
@ -911,13 +903,6 @@ public:
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea = nsnull);
|
||||
|
||||
static nsresult DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea = nsnull);
|
||||
|
||||
/**
|
||||
* Given a source area of an image (in appunits) and a destination area
|
||||
* that we want to map that source area too, computes the area that
|
||||
|
@ -84,7 +84,6 @@ class nsIContent;
|
||||
class nsIFontMetrics;
|
||||
class nsIFrame;
|
||||
class nsFrameManager;
|
||||
class nsIImage;
|
||||
class nsILinkHandler;
|
||||
class nsStyleContext;
|
||||
class nsIAtom;
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsFormControlFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
@ -71,13 +71,12 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
|
||||
|
||||
@ -1458,7 +1457,7 @@ NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
// The image has changed.
|
||||
@ -1489,7 +1488,6 @@ NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewFrame,
|
||||
nsIntRect *aDirtyRect)
|
||||
{
|
||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||
@ -1547,13 +1545,13 @@ NS_IMETHODIMP nsBulletListener::OnStartContainer(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->OnDataAvailable(aRequest, aFrame, aRect);
|
||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
|
||||
@ -1567,11 +1565,10 @@ NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(aContainer, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(aContainer, dirtyRect);
|
||||
}
|
||||
|
@ -45,7 +45,6 @@
|
||||
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
class gfxIImageFrame;
|
||||
|
||||
/**
|
||||
* A simple class that manages the layout and rendering of html bullets.
|
||||
@ -81,13 +80,12 @@ public:
|
||||
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusArg);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewframe,
|
||||
nsIntRect *aDirtyRect);
|
||||
|
||||
/* get list item text, without '.' */
|
||||
|
@ -109,7 +109,6 @@
|
||||
#include "nsIServiceManager.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINodeInfo.h"
|
||||
@ -93,7 +92,6 @@
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIDOMRange.h"
|
||||
|
||||
#include "nsIContentPolicy.h"
|
||||
@ -523,7 +521,7 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
||||
|
||||
nsresult
|
||||
nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
// XXX do we need to make sure that the reflow from the
|
||||
@ -555,16 +553,8 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
|
||||
// Don't invalidate if the current visible frame isn't the one the data is
|
||||
// from
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
aRequest->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
container->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
if (aFrame != currentFrame) {
|
||||
// just bail
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
if (!aCurrentFrame)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef DEBUG_decode
|
||||
printf("Source rect (%d,%d,%d,%d) -> invalidate dest rect (%d,%d,%d,%d)\n",
|
||||
@ -634,9 +624,7 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageFrame::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewFrame,
|
||||
nsIntRect *aDirtyRect)
|
||||
nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect)
|
||||
{
|
||||
if (!GetStyleVisibility()->IsVisible()) {
|
||||
return NS_OK;
|
||||
@ -1833,13 +1821,13 @@ NS_IMETHODIMP nsImageListener::OnStartContainer(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->OnDataAvailable(aRequest, aFrame, aRect);
|
||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
|
||||
@ -1853,13 +1841,12 @@ NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect * dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(aContainer, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(aContainer, dirtyRect);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
|
@ -73,13 +73,12 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect * dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
|
||||
|
||||
void SetFrame(nsImageFrame *frame) { mFrame = frame; }
|
||||
|
||||
@ -218,15 +217,12 @@ protected:
|
||||
protected:
|
||||
friend class nsImageListener;
|
||||
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
nsresult OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
nsresult OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *rect);
|
||||
nsresult OnStopDecode(imgIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusArg);
|
||||
nsresult FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewframe,
|
||||
nsIntRect *aDirtyRect);
|
||||
nsresult FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect);
|
||||
|
||||
private:
|
||||
// random helpers
|
||||
|
@ -1159,8 +1159,100 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
window.clipRect.bottom = 0; window.clipRect.top = 0;
|
||||
window.clipRect.left = 0; window.clipRect.right = 0;
|
||||
|
||||
// XXX platform specific printing code
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
// platform specific printing code
|
||||
#if defined(XP_MACOSX)
|
||||
window.x = 0;
|
||||
window.y = 0;
|
||||
window.width = presContext->AppUnitsToDevPixels(mRect.width);
|
||||
window.height = presContext->AppUnitsToDevPixels(mRect.height);
|
||||
|
||||
gfxContext *ctx = aRenderingContext.ThebesContext();
|
||||
if (!ctx)
|
||||
return;
|
||||
gfxContextAutoSaveRestore save(ctx);
|
||||
|
||||
ctx->NewPath();
|
||||
|
||||
gfxRect rect(window.x, window.y, window.width, window.height);
|
||||
|
||||
ctx->Rectangle(rect);
|
||||
ctx->Clip();
|
||||
|
||||
gfxQuartzNativeDrawing nativeDraw(ctx, rect);
|
||||
CGContextRef cgContext = nativeDraw.BeginNativeDrawing();
|
||||
if (!cgContext) {
|
||||
nativeDraw.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
|
||||
window.clipRect.right = window.width;
|
||||
window.clipRect.bottom = window.height;
|
||||
window.type = nsPluginWindowType_Drawable;
|
||||
|
||||
Rect gwBounds;
|
||||
::SetRect(&gwBounds, 0, 0, window.width, window.height);
|
||||
|
||||
nsTArray<char> buffer(window.width * window.height * 4);
|
||||
CGColorSpaceRef cspace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
if (!cspace) {
|
||||
nativeDraw.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
CGContextRef cgBuffer =
|
||||
::CGBitmapContextCreate(buffer.Elements(),
|
||||
window.width, window.height, 8, window.width * 4,
|
||||
cspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedFirst);
|
||||
::CGColorSpaceRelease(cspace);
|
||||
if (!cgBuffer) {
|
||||
nativeDraw.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
GWorldPtr gWorld;
|
||||
if (::NewGWorldFromPtr(&gWorld, k32ARGBPixelFormat, &gwBounds, NULL, NULL, 0,
|
||||
buffer.Elements(), window.width * 4) != noErr) {
|
||||
::CGContextRelease(cgBuffer);
|
||||
nativeDraw.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
|
||||
window.clipRect.right = window.width;
|
||||
window.clipRect.bottom = window.height;
|
||||
window.type = nsPluginWindowType_Drawable;
|
||||
// Setting nsPluginPrint/NPPrint.print.embedPrint.window.window to
|
||||
// &GWorldPtr and nsPluginPrint/NPPrint.print.embedPrint.platformPrint to
|
||||
// GWorldPtr isn't any kind of standard (it's not documented anywhere).
|
||||
// But that's what WebKit does. And it's what the Flash plugin (apparently
|
||||
// the only NPAPI plugin on OS X to support printing) seems to expect. So
|
||||
// we do the same. The Flash plugin uses the CoreGraphics drawing mode.
|
||||
// But a GWorldPtr should be usable in either CoreGraphics or QuickDraw
|
||||
// drawing mode. See bug 191046.
|
||||
window.window = reinterpret_cast<nsPluginPort *>(&gWorld);
|
||||
npprint.print.embedPrint.platformPrint = gWorld;
|
||||
npprint.print.embedPrint.window = window;
|
||||
nsresult rv = pi->Print(&npprint);
|
||||
|
||||
::CGContextSaveGState(cgContext);
|
||||
::CGContextTranslateCTM(cgContext, 0.0f, float(window.height));
|
||||
::CGContextScaleCTM(cgContext, 1.0f, -1.0f);
|
||||
CGImageRef image = ::CGBitmapContextCreateImage(cgBuffer);
|
||||
if (!image) {
|
||||
::CGContextRestoreGState(cgContext);
|
||||
::CGContextRelease(cgBuffer);
|
||||
::DisposeGWorld(gWorld);
|
||||
nativeDraw.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
::CGContextDrawImage(cgContext,
|
||||
::CGRectMake(0, 0, window.width, window.height),
|
||||
image);
|
||||
::CGImageRelease(image);
|
||||
::CGContextRestoreGState(cgContext);
|
||||
::CGContextRelease(cgBuffer);
|
||||
|
||||
::DisposeGWorld(gWorld);
|
||||
|
||||
nativeDraw.EndNativeDrawing();
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
/* XXX this just flat-out doesn't work in a thebes world --
|
||||
* RenderEPS is a no-op. So don't bother to do any work here.
|
||||
|
@ -21,6 +21,6 @@
|
||||
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<rect width="183" height="183" fill="red"/>
|
||||
<image width="183" height="183" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABGdBTUEAALGPC%2FxhBQAAAAxJREFUGFdjYPjPAAACAgEA0dNGRAAAAABJRU5ErkJggg%3D%3D"/>
|
||||
<image style="image-rendering: -moz-crisp-edges" width="183" height="183" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABGdBTUEAALGPC%2FxhBQAAAAxJREFUGFdjYPjPAAACAgEA0dNGRAAAAABJRU5ErkJggg%3D%3D"/>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
@ -37,7 +37,6 @@
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "nsIDOMSVGImageElement.h"
|
||||
@ -47,7 +46,6 @@
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
class nsSVGImageFrame;
|
||||
|
||||
@ -61,8 +59,7 @@ public:
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsRect * dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer);
|
||||
@ -243,16 +240,15 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
||||
currentRequest->GetImage(getter_AddRefs(mImageContainer));
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
nsRefPtr<gfxASurface> currentFrame;
|
||||
if (mImageContainer)
|
||||
mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
// We need to wrap the surface in a pattern to have somewhere to set the
|
||||
// graphics filter.
|
||||
nsRefPtr<gfxPattern> thebesPattern;
|
||||
if (currentFrame)
|
||||
thebesPattern = new gfxPattern(currentFrame);
|
||||
|
||||
if (thebesPattern) {
|
||||
|
||||
@ -279,8 +275,8 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
||||
}
|
||||
|
||||
PRInt32 nativeWidth, nativeHeight;
|
||||
currentFrame->GetWidth(&nativeWidth);
|
||||
currentFrame->GetHeight(&nativeHeight);
|
||||
mImageContainer->GetWidth(&nativeWidth);
|
||||
mImageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, nativeWidth, nativeHeight, opacity);
|
||||
|
||||
@ -384,8 +380,7 @@ NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsRect * dirtyRect)
|
||||
nsIntRect * dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsStyleConsts.h"
|
||||
@ -543,7 +542,6 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
nsBoxLayoutState state(PresContext());
|
||||
@ -591,12 +589,11 @@ NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(container, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(container, dirtyRect);
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,7 @@ public:
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
|
||||
|
||||
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
|
||||
|
||||
@ -121,9 +120,7 @@ public:
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *request,
|
||||
nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
|
||||
|
||||
virtual ~nsImageBoxFrame();
|
||||
|
||||
|
@ -238,6 +238,7 @@ nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis)
|
||||
{
|
||||
nsAutoString accesskey;
|
||||
nsCOMPtr<nsIDOMXULLabelElement> labelElement = do_QueryInterface(mContent);
|
||||
NS_ENSURE_TRUE(aWeakThis.IsAlive(), PR_FALSE);
|
||||
if (labelElement) {
|
||||
// Accesskey may be stored on control.
|
||||
// Because this method is called by the reflow callback, current context
|
||||
|
@ -2173,11 +2173,11 @@ nsTreeBodyFrame::GetImage(PRInt32 aRowIndex, nsTreeColumn* aCol, PRBool aUseCont
|
||||
imgIRequest *imgReq = entry.request;
|
||||
imgReq->GetImageStatus(&status);
|
||||
imgReq->GetImage(aResult); // We hand back the image here. The GetImage call addrefs *aResult.
|
||||
PRUint32 numFrames = 1;
|
||||
PRBool animated = PR_FALSE;
|
||||
if (*aResult)
|
||||
(*aResult)->GetNumFrames(&numFrames);
|
||||
(*aResult)->GetAnimated(&animated);
|
||||
|
||||
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || numFrames > 1) {
|
||||
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || animated) {
|
||||
// We either aren't done loading, or we're animating. Add our row as a listener for invalidations.
|
||||
nsCOMPtr<imgIDecoderObserver> obs;
|
||||
imgReq->GetDecoderObserver(getter_AddRefs(obs));
|
||||
|
@ -64,7 +64,7 @@ NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
Invalidate();
|
||||
@ -72,7 +72,6 @@ NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
Invalidate();
|
||||
|
@ -72,11 +72,10 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol);
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#define IMG_BUILD_xbm 1
|
||||
#endif
|
||||
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsICategoryManager.h"
|
||||
@ -206,7 +207,7 @@ static const nsModuleComponentInfo components[] =
|
||||
imgLoaderConstructor, },
|
||||
{ "image container",
|
||||
NS_IMGCONTAINER_CID,
|
||||
"@mozilla.org/image/container;1",
|
||||
"@mozilla.org/image/container;2",
|
||||
imgContainerConstructor, },
|
||||
{ "image loader",
|
||||
NS_IMGLOADER_CID,
|
||||
@ -313,6 +314,12 @@ static const nsModuleComponentInfo components[] =
|
||||
static nsresult
|
||||
imglib_Initialize(nsIModule* aSelf)
|
||||
{
|
||||
// Hack: We need the gfx module to be initialized because we use gfxPlatform
|
||||
// in imgFrame. Request something from the gfx module to ensure that
|
||||
// everything's set up for us.
|
||||
nsCOMPtr<nsIDeviceContext> devctx =
|
||||
do_CreateInstance("@mozilla.org/gfx/devicecontext;1");
|
||||
|
||||
imgLoader::InitCache();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "imgILoad.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
@ -89,11 +88,7 @@ NS_IMETHODIMP nsBMPDecoder::Init(imgILoad *aLoad)
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
nsresult rv;
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2", &rv);
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -106,13 +101,12 @@ NS_IMETHODIMP nsBMPDecoder::Close()
|
||||
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
mObserver = nsnull;
|
||||
}
|
||||
mImage = nsnull;
|
||||
mFrame = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -266,8 +260,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mOldLine = mCurLine = real_height;
|
||||
|
||||
PRUint32 imageLength;
|
||||
if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) {
|
||||
rv = mFrame->Init(0, 0, mBIH.width, real_height, RLE_GFXFORMAT_ALPHA, 24);
|
||||
rv = mImage->AppendFrame(0, 0, mBIH.width, real_height, gfxASurface::ImageFormatARGB32,
|
||||
(PRUint8**)&mImageData, &imageLength);
|
||||
} else {
|
||||
// mRow is not used for RLE encoded images
|
||||
mRow = (PRUint8*)malloc((mBIH.width * mBIH.bpp)/8 + 4);
|
||||
@ -277,12 +273,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
||||
if (!mRow) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = mFrame->Init(0, 0, mBIH.width, real_height, BMP_GFXFORMAT, 24);
|
||||
rv = mImage->AppendFrame(0, 0, mBIH.width, real_height, gfxASurface::ImageFormatRGB24,
|
||||
(PRUint8**)&mImageData, &imageLength);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 imageLength;
|
||||
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength);
|
||||
if (!mImageData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -297,9 +291,7 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
||||
memset(mImageData, 0, imageLength);
|
||||
}
|
||||
|
||||
rv = mImage->AppendFrame(mFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
PRUint8 bpc; // bytes per color
|
||||
@ -603,14 +595,11 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
||||
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
||||
mBIH.width, rows);
|
||||
|
||||
// Tell the image that it's data has been updated
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame, &rv));
|
||||
// Tell the image that its data has been updated
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
mOldLine = mCurLine;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
#define NS_BMPDECODER_CID \
|
||||
@ -118,9 +117,6 @@ struct bitFields {
|
||||
#endif
|
||||
|
||||
#define USE_RGB
|
||||
#define BMP_GFXFORMAT gfxIFormats::RGB
|
||||
#define RLE_GFXFORMAT_ALPHA gfxIFormats::RGB_A1
|
||||
#define GFXBYTESPERPIXEL 4
|
||||
|
||||
// BMPINFOHEADER.compression defines
|
||||
#define BI_RLE8 1
|
||||
@ -173,7 +169,6 @@ private:
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
PRUint32 mPos;
|
||||
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "imgILoad.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsIProperties.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
@ -93,39 +92,30 @@ NS_IMETHODIMP nsICODecoder::Init(imgILoad *aLoad)
|
||||
{
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return aLoad->SetImage(mImage);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsICODecoder::Close()
|
||||
{
|
||||
// Tell the image that it's data has been updated
|
||||
// This should be a mFrame function, so that we don't have to query for interface...
|
||||
nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
nsresult rv = NS_OK;
|
||||
if (img)
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
nsresult rv = mImage->FrameUpdated(0, r);
|
||||
|
||||
mImage->DecodingComplete();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, 0);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
mObserver = nsnull;
|
||||
}
|
||||
|
||||
mImage = nsnull;
|
||||
mFrame = nsnull;
|
||||
|
||||
mPos = 0;
|
||||
|
||||
@ -304,15 +294,13 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
||||
if (!mRow)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA8, 24);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mImage->AppendFrame(mFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
PRUint32 imageLength;
|
||||
rv = mImage->AppendFrame(0, 0, mDirEntry.mWidth, mDirEntry.mHeight,
|
||||
gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 imageLength;
|
||||
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) &&
|
||||
|
@ -44,20 +44,12 @@
|
||||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsBMPDecoder.h"
|
||||
|
||||
// {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1}
|
||||
#define NS_ICODECODER_CID \
|
||||
{ 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } }
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
#define GFXFORMATALPHA8 gfxIFormats::BGR_A8
|
||||
#else
|
||||
#define USE_RGBA1
|
||||
#define GFXFORMATALPHA8 gfxIFormats::RGB_A8
|
||||
#endif
|
||||
|
||||
struct IconDirEntry
|
||||
{
|
||||
PRUint8 mWidth;
|
||||
@ -103,7 +95,6 @@ private:
|
||||
private:
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
PRUint32 mPos;
|
||||
PRUint16 mNumIcons;
|
||||
|
@ -74,7 +74,6 @@ mailing address.
|
||||
#include <stddef.h>
|
||||
#include "prmem.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "nsGIFDecoder2.h"
|
||||
@ -142,7 +141,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
|
||||
{
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
mImageContainer = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImageContainer = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
aLoad->SetImage(mImageContainer);
|
||||
|
||||
// Start with the version (GIF89a|GIF87a)
|
||||
@ -161,8 +160,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
|
||||
/* void close (); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Close()
|
||||
{
|
||||
if (mImageFrame)
|
||||
EndImageFrame();
|
||||
EndImageFrame();
|
||||
EndGIF();
|
||||
|
||||
PR_FREEIF(mGIFStruct.local_colormap);
|
||||
@ -205,8 +203,7 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
|
||||
nsIntRect r(0, fromRow, mGIFStruct.width, rows);
|
||||
|
||||
// Update image
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
||||
nsresult rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -214,8 +211,10 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
|
||||
// Offset to the frame position
|
||||
// Only notify observer(s) for first frame
|
||||
if (!mGIFStruct.images_decoded && mObserver) {
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
r.y += mGIFStruct.y_offset;
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -251,7 +250,7 @@ nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint3
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Flushing is only needed for first frame
|
||||
if (!mGIFStruct.images_decoded && mImageFrame) {
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
rv = FlushImageData();
|
||||
mLastFlushedRow = mCurrentRow;
|
||||
mLastFlushedPass = mCurrentPass;
|
||||
@ -324,8 +323,6 @@ void nsGIFDecoder2::EndGIF()
|
||||
//******************************************************************************
|
||||
void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
|
||||
{
|
||||
mImageFrame = nsnull; // clear out our current frame reference
|
||||
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
// Send a onetime OnDataAvailable (Display Refresh) for the first frame
|
||||
// if it has a y-axis offset. Otherwise, the area may never be refreshed
|
||||
@ -333,41 +330,46 @@ void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
|
||||
if (mGIFStruct.y_offset > 0) {
|
||||
PRInt32 imgWidth;
|
||||
mImageContainer->GetWidth(&imgWidth);
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset);
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 imageDataLength;
|
||||
nsresult rv;
|
||||
gfxASurface::gfxImageFormat format;
|
||||
if (mGIFStruct.is_transparent)
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
else
|
||||
format = gfxASurface::ImageFormatRGB24;
|
||||
|
||||
// Use correct format, RGB for first frame, PAL for following frames
|
||||
// and include transparency to allow for optimization of opaque images
|
||||
gfx_format format;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Image data is stored with original depth and palette
|
||||
format = mGIFStruct.is_transparent ? gfxIFormats::PAL_A1 : gfxIFormats::PAL;
|
||||
rv = mImageContainer->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height,
|
||||
format, aDepth, &mImageData, &imageDataLength,
|
||||
&mColormap, &mColormapSize);
|
||||
|
||||
|
||||
} else {
|
||||
// Regardless of depth of input, image is decoded into 24bit RGB
|
||||
format = mGIFStruct.is_transparent ? gfxIFormats::RGB_A1 : gfxIFormats::RGB;
|
||||
aDepth = 24;
|
||||
rv = mImageContainer->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height,
|
||||
format, &mImageData, &imageDataLength);
|
||||
}
|
||||
|
||||
// initialize the frame and append it to the container
|
||||
mImageFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mImageFrame || NS_FAILED(mImageFrame->Init(
|
||||
mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height, format, aDepth))) {
|
||||
mImageFrame = 0;
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
}
|
||||
|
||||
mImageFrame->SetFrameDisposalMethod(mGIFStruct.disposal_method);
|
||||
if (!mGIFStruct.images_decoded)
|
||||
mImageContainer->AppendFrame(mImageFrame);
|
||||
mImageContainer->SetFrameDisposalMethod(mGIFStruct.images_decoded,
|
||||
mGIFStruct.disposal_method);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mImageFrame);
|
||||
|
||||
PRUint32 imageDataLength;
|
||||
mImageFrame->GetImageData(&mImageData, &imageDataLength);
|
||||
mObserver->OnStartFrame(nsnull, mGIFStruct.images_decoded);
|
||||
}
|
||||
|
||||
|
||||
@ -384,20 +386,23 @@ void nsGIFDecoder2::EndImageFrame()
|
||||
// This will clear the remaining bits of the placeholder. (Bug 37589)
|
||||
const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset;
|
||||
if (realFrameHeight < mGIFStruct.screen_height) {
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
nsIntRect r(0, realFrameHeight,
|
||||
mGIFStruct.screen_width,
|
||||
mGIFStruct.screen_height - realFrameHeight);
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
// This transparency check is only valid for first frame
|
||||
if (mGIFStruct.is_transparent && !mSawTransparency) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
||||
img->SetHasNoAlpha();
|
||||
mImageContainer->SetFrameHasNoAlpha(mGIFStruct.images_decoded);
|
||||
}
|
||||
}
|
||||
mCurrentRow = mLastFlushedRow = -1;
|
||||
mCurrentPass = mLastFlushedPass = 0;
|
||||
|
||||
PRUint32 curframe = mGIFStruct.images_decoded;
|
||||
|
||||
// Only add frame if we have any rows at all
|
||||
if (mGIFStruct.rows_remaining != mGIFStruct.height) {
|
||||
if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) {
|
||||
@ -410,18 +415,14 @@ void nsGIFDecoder2::EndImageFrame()
|
||||
// image data, at least according to the spec, but we delay in setting the
|
||||
// timeout for the image until here to help ensure that we have the whole
|
||||
// image frame decoded before we go off and try to display another frame.
|
||||
mImageFrame->SetTimeout(mGIFStruct.delay_time);
|
||||
if (mGIFStruct.images_decoded)
|
||||
mImageContainer->AppendFrame(mImageFrame);
|
||||
mImageContainer->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
|
||||
mImageContainer->EndFrameDecode(mGIFStruct.images_decoded);
|
||||
mGIFStruct.images_decoded++;
|
||||
|
||||
mGIFStruct.images_decoded++;
|
||||
}
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStopFrame(nsnull, mImageFrame);
|
||||
|
||||
// Release reference to this frame
|
||||
mImageFrame = nsnull;
|
||||
mObserver->OnStopFrame(nsnull, curframe);
|
||||
|
||||
// Reset the transparent pixel
|
||||
if (mOldColor) {
|
||||
@ -497,7 +498,7 @@ PRUint32 nsGIFDecoder2::OutputRow()
|
||||
if (drow_end > drow_start) {
|
||||
// irow is the current row filled
|
||||
for (int r = drow_start; r <= drow_end; r++) {
|
||||
if (r != mGIFStruct.irow) {
|
||||
if (r != int(mGIFStruct.irow)) {
|
||||
memcpy(mImageData + (r * bpr), rowp, bpr);
|
||||
}
|
||||
}
|
||||
@ -1060,7 +1061,7 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
||||
BeginImageFrame(realDepth);
|
||||
|
||||
// handle allocation error
|
||||
if (!mImageFrame) {
|
||||
if (!mImageData) {
|
||||
mGIFStruct.state = gif_error;
|
||||
break;
|
||||
}
|
||||
@ -1086,17 +1087,12 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
||||
if (q[8] & 0x80) /* has a local colormap? */
|
||||
{
|
||||
mGIFStruct.local_colormap_size = 1 << depth;
|
||||
PRUint32 paletteSize;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Copy directly into the palette of current frame,
|
||||
// by pointing mColormap to that palette.
|
||||
mImageFrame->GetPaletteData(&mColormap, &paletteSize);
|
||||
} else {
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
// First frame has local colormap, allocate space for it
|
||||
// as the image frame doesn't have its own palette
|
||||
paletteSize = sizeof(PRUint32) << realDepth;
|
||||
mColormapSize = sizeof(PRUint32) << realDepth;
|
||||
if (!mGIFStruct.local_colormap) {
|
||||
mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(paletteSize);
|
||||
mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(mColormapSize);
|
||||
if (!mGIFStruct.local_colormap) {
|
||||
mGIFStruct.state = gif_oom;
|
||||
break;
|
||||
@ -1105,9 +1101,9 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
||||
mColormap = mGIFStruct.local_colormap;
|
||||
}
|
||||
const PRUint32 size = 3 << depth;
|
||||
if (paletteSize > size) {
|
||||
if (mColormapSize > size) {
|
||||
// Clear the notfilled part of the colormap
|
||||
memset(((PRUint8*)mColormap) + size, 0, paletteSize - size);
|
||||
memset(((PRUint8*)mColormap) + size, 0, mColormapSize - size);
|
||||
}
|
||||
if (len < size) {
|
||||
// Use 'hold' pattern to get the image colormap
|
||||
@ -1122,12 +1118,11 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
||||
break;
|
||||
} else {
|
||||
/* Switch back to the global palette */
|
||||
mColormap = mGIFStruct.global_colormap;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Copy global colormap into the palette of current frame
|
||||
PRUint32 size;
|
||||
mImageFrame->GetPaletteData(&mColormap, &size);
|
||||
memcpy(mColormap, mGIFStruct.global_colormap, size);
|
||||
memcpy(mColormap, mGIFStruct.global_colormap, mColormapSize);
|
||||
} else {
|
||||
mColormap = mGIFStruct.global_colormap;
|
||||
}
|
||||
}
|
||||
GETN(1, gif_lzw_start);
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "GIF2.h"
|
||||
|
||||
@ -88,13 +87,13 @@ private:
|
||||
inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
|
||||
|
||||
nsCOMPtr<imgIContainer> mImageContainer;
|
||||
nsCOMPtr<gfxIImageFrame> mImageFrame;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
PRInt32 mCurrentRow;
|
||||
PRInt32 mLastFlushedRow;
|
||||
|
||||
PRUint8 *mImageData; // Pointer to image data in either Cairo or 8bit format
|
||||
PRUint32 *mColormap; // Current colormap to be used in Cairo format
|
||||
PRUint32 mColormapSize;
|
||||
PRUint32 mOldColor; // The old value of the transparent pixel
|
||||
PRUint8 mCurrentPass;
|
||||
PRUint8 mLastFlushedPass;
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nsRect.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder)
|
||||
@ -71,14 +70,11 @@ NS_IMETHODIMP nsIconDecoder::Init(imgILoad *aLoad)
|
||||
{
|
||||
mObserver = do_QueryInterface(aLoad); // we're holding 2 strong refs to the request.
|
||||
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
aLoad->SetImage(mImage);
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -88,7 +84,7 @@ NS_IMETHODIMP nsIconDecoder::Close()
|
||||
|
||||
if (mObserver)
|
||||
{
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
@ -120,17 +116,15 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
||||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
rv = mFrame->Init(0, 0, w, h, gfxIFormats::BGRA, 24);
|
||||
PRUint32 imageLen;
|
||||
PRUint8 *imageData;
|
||||
|
||||
rv = mImage->AppendFrame(0, 0, w, h, gfxASurface::ImageFormatARGB32, &imageData, &imageLen);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
PRUint32 imageLen;
|
||||
PRUint8 *imageData;
|
||||
mFrame->GetImageData(&imageData, &imageLen);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
|
||||
// Ensure that there enough in the inputStream
|
||||
NS_ENSURE_TRUE(count >= imageLen, NS_ERROR_UNEXPECTED);
|
||||
@ -142,12 +136,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
||||
|
||||
// Notify the image...
|
||||
nsIntRect r(0, 0, w, h);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -46,7 +46,6 @@
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#define NS_ICONDECODER_CID \
|
||||
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \
|
||||
@ -87,7 +86,6 @@ public:
|
||||
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
};
|
||||
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "nspr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "ImageLogging.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
@ -101,6 +100,7 @@ nsJPEGDecoder::nsJPEGDecoder()
|
||||
mState = JPEG_HEADER;
|
||||
mReading = PR_TRUE;
|
||||
mError = NS_OK;
|
||||
mImageData = nsnull;
|
||||
|
||||
mBytesToSkip = 0;
|
||||
memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
|
||||
@ -187,7 +187,7 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad)
|
||||
mImageLoad->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
if (!mImage) {
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -473,49 +473,23 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
|
||||
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
mImage->GetFrameAt(0, getter_AddRefs(mFrame));
|
||||
|
||||
if (mFrame) {
|
||||
PRInt32 width, height;
|
||||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
|
||||
if ((width != (PRInt32)mInfo.image_width) ||
|
||||
(height != (PRInt32)mInfo.image_height)) {
|
||||
// Can't reuse frame, create a new one with correct size
|
||||
mFrame = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFrame) {
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (could not create image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
gfx_format format = gfxIFormats::RGB;
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
format = gfxIFormats::BGR;
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format, 24))) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (could not initialize image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
|
||||
// Use EnsureCleanFrame so we don't create a new frame if we're being
|
||||
// reused for e.g. multipart/x-replace
|
||||
PRUint32 imagelength;
|
||||
if (NS_FAILED(mImage->EnsureCleanFrame(0, 0, 0, mInfo.image_width, mInfo.image_height,
|
||||
gfxASurface::ImageFormatRGB24,
|
||||
&mImageData, &imagelength))) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels",
|
||||
mInfo.image_width, mInfo.image_height));
|
||||
("} (could not initialize image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels",
|
||||
mInfo.image_width, mInfo.image_height));
|
||||
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
mState = JPEG_START_DECOMPRESS;
|
||||
}
|
||||
|
||||
@ -699,16 +673,9 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
|
||||
const PRUint32 top = mInfo.output_scanline;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mFrame->LockImageData();
|
||||
|
||||
// we're thebes. we can write stuff directly to the data
|
||||
PRUint8 *imageData;
|
||||
PRUint32 imageDataLength;
|
||||
mFrame->GetImageData(&imageData, &imageDataLength);
|
||||
|
||||
while ((mInfo.output_scanline < mInfo.output_height)) {
|
||||
/* Use the Cairo image buffer as scanline buffer */
|
||||
PRUint32 *imageRow = ((PRUint32*)imageData) +
|
||||
PRUint32 *imageRow = ((PRUint32*)mImageData) +
|
||||
(mInfo.output_scanline * mInfo.output_width);
|
||||
|
||||
if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
|
||||
@ -791,13 +758,10 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
|
||||
|
||||
if (top != mInfo.output_scanline) {
|
||||
nsIntRect r(0, top, mInfo.output_width, mInfo.output_scanline-top);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
}
|
||||
|
||||
mFrame->UnlockImageData();
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1013,15 +977,16 @@ term_source (j_decompress_ptr jd)
|
||||
nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data);
|
||||
|
||||
if (decoder->mObserver) {
|
||||
decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame);
|
||||
decoder->mObserver->OnStopFrame(nsnull, 0);
|
||||
decoder->mObserver->OnStopContainer(nsnull, decoder->mImage);
|
||||
decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
PRBool isMutable = PR_FALSE;
|
||||
PRBool multipart = PR_FALSE;
|
||||
if (decoder->mImageLoad)
|
||||
decoder->mImageLoad->GetIsMultiPartChannel(&isMutable);
|
||||
decoder->mFrame->SetMutable(isMutable);
|
||||
decoder->mImageLoad->GetIsMultiPartChannel(&multipart);
|
||||
if (!multipart)
|
||||
decoder->mImage->DecodingComplete();
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgILoad.h"
|
||||
#include "nsIInputStream.h"
|
||||
@ -99,9 +98,9 @@ protected:
|
||||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<imgILoad> mImageLoad;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
PRUint8 *mImageData;
|
||||
|
||||
struct jpeg_decompress_struct mInfo;
|
||||
struct jpeg_source_mgr mSourceMgr;
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "gfxColor.h"
|
||||
@ -99,25 +98,29 @@ nsPNGDecoder::~nsPNGDecoder()
|
||||
|
||||
// CreateFrame() is used for both simple and animated images
|
||||
void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
PRInt32 width, PRInt32 height, gfx_format format)
|
||||
PRInt32 width, PRInt32 height,
|
||||
gfxASurface::gfxImageFormat format)
|
||||
{
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame)
|
||||
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
nsresult rv = mFrame->Init(x_offset, y_offset, width, height, format, 24);
|
||||
PRUint32 imageDataLength;
|
||||
nsresult rv = mImage->AppendFrame(x_offset, y_offset, width, height, format,
|
||||
&mImageData, &imageDataLength);
|
||||
if (NS_FAILED(rv))
|
||||
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
mFrameRect.x = x_offset;
|
||||
mFrameRect.y = y_offset;
|
||||
mFrameRect.width = width;
|
||||
mFrameRect.height = height;
|
||||
|
||||
if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL))
|
||||
SetAnimFrameInfo();
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
|
||||
PRUint32 numFrames = 0;
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, numFrames - 1);
|
||||
|
||||
PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p",
|
||||
width, height,
|
||||
@ -141,7 +144,7 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
||||
blend_op = png_get_next_frame_blend_op(mPNG, mInfo);
|
||||
|
||||
if (delay_num == 0) {
|
||||
timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum
|
||||
timeout = 0; // SetFrameTimeout() will set to a minimum
|
||||
} else {
|
||||
if (delay_den == 0)
|
||||
delay_den = 100; // so says the APNG spec
|
||||
@ -151,54 +154,49 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
||||
timeout = static_cast<PRInt32>
|
||||
(static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
|
||||
}
|
||||
mFrame->SetTimeout(timeout);
|
||||
|
||||
PRUint32 numFrames = 0;
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
mImage->SetFrameTimeout(numFrames - 1, timeout);
|
||||
|
||||
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeRestorePrevious);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeRestorePrevious);
|
||||
else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeClear);
|
||||
else
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeKeep);
|
||||
|
||||
if (blend_op == PNG_BLEND_OP_SOURCE)
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendSource);
|
||||
/*else // 'over' is the default for a gfxImageFrame
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendOver); */
|
||||
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
|
||||
/*else // 'over' is the default
|
||||
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
|
||||
}
|
||||
|
||||
// set timeout and frame disposal method for the current frame
|
||||
void nsPNGDecoder::EndImageFrame()
|
||||
{
|
||||
if (mFrameHasNoAlpha) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
img->SetHasNoAlpha();
|
||||
}
|
||||
|
||||
// First tell the container that this frame is complete
|
||||
PRInt32 timeout = 100;
|
||||
PRUint32 numFrames = 0;
|
||||
mFrame->GetTimeout(&timeout);
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
// We can't use mPNG->num_frames_read as it may be one ahead.
|
||||
if (numFrames > 1) {
|
||||
// Tell the image renderer that the frame is complete
|
||||
PRInt32 width, height;
|
||||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
if (mFrameHasNoAlpha)
|
||||
mImage->SetFrameHasNoAlpha(numFrames - 1);
|
||||
|
||||
nsIntRect r(0, 0, width, height);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
|
||||
if (NS_FAILED(mImage->FrameUpdated(numFrames - 1, mFrameRect))) {
|
||||
mError = PR_TRUE;
|
||||
// allow the call out to the observers.
|
||||
}
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
PRUint32 curFrame;
|
||||
mImage->GetCurrentFrameIndex(&curFrame);
|
||||
mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &mFrameRect);
|
||||
}
|
||||
|
||||
mImage->EndFrameDecode(numFrames);
|
||||
mImage->EndFrameDecode(numFrames - 1);
|
||||
if (mObserver)
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, numFrames - 1);
|
||||
}
|
||||
|
||||
|
||||
@ -265,7 +263,7 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgILoad *aLoad)
|
||||
*/
|
||||
mImageLoad->GetImage(getter_AddRefs(mImage));
|
||||
if (!mImage) {
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -556,12 +554,11 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
|
||||
color_type, &inType, &pIntent);
|
||||
/* If we're not mandating an intent, use the one from the image. */
|
||||
if (intent == -1)
|
||||
if (intent == PRUint32(-1))
|
||||
intent = pIntent;
|
||||
}
|
||||
if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) {
|
||||
qcms_data_type outType;
|
||||
PRUint32 dwFlags = 0;
|
||||
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
|
||||
outType = QCMS_DATA_RGBA_8;
|
||||
@ -631,22 +628,17 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
if (containerWidth == 0 && containerHeight == 0) {
|
||||
// the image hasn't been inited yet
|
||||
decoder->mImage->Init(width, height, decoder->mObserver);
|
||||
} else if (containerWidth != width || containerHeight != height) {
|
||||
} else if (containerWidth != PRInt32(width) || containerHeight != PRInt32(height)) {
|
||||
longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_UNEXPECTED
|
||||
}
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartContainer(nsnull, decoder->mImage);
|
||||
|
||||
if (channels == 1 || channels == 3) {
|
||||
decoder->format = gfxIFormats::RGB;
|
||||
} else if (channels == 2 || channels == 4) {
|
||||
if (alpha_bits == 8) {
|
||||
decoder->format = gfxIFormats::RGB_A8;
|
||||
} else if (alpha_bits == 1) {
|
||||
decoder->format = gfxIFormats::RGB_A1;
|
||||
}
|
||||
}
|
||||
if (channels == 1 || channels == 3)
|
||||
decoder->format = gfxASurface::ImageFormatRGB24;
|
||||
else if (channels == 2 || channels == 4)
|
||||
decoder->format = gfxASurface::ImageFormatARGB32;
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
|
||||
png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL);
|
||||
@ -674,9 +666,6 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
if (png_get_first_frame_is_hidden(png_ptr, info_ptr))
|
||||
decoder->mFrame = nsnull;
|
||||
|
||||
/* Reject any ancillary chunk after IDAT with a bad CRC (bug #397593).
|
||||
* It would be better to show the default frame (if one has already been
|
||||
* successfully decoded) before bailing, but it's simpler to just bail
|
||||
@ -725,9 +714,8 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
return;
|
||||
|
||||
if (new_row) {
|
||||
PRInt32 width;
|
||||
decoder->mFrame->GetWidth(&width);
|
||||
PRUint32 iwidth = width;
|
||||
PRInt32 width = decoder->mFrameRect.width;
|
||||
PRUint32 iwidth = decoder->mFrameRect.width;
|
||||
|
||||
png_bytep line = new_row;
|
||||
if (decoder->interlacebuf) {
|
||||
@ -735,11 +723,8 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_progressive_combine_row(png_ptr, line, new_row);
|
||||
}
|
||||
|
||||
// we're thebes. we can write stuff directly to the data
|
||||
PRUint8 *imageData;
|
||||
PRUint32 imageDataLength, bpr = width * sizeof(PRUint32);
|
||||
decoder->mFrame->GetImageData(&imageData, &imageDataLength);
|
||||
PRUint32 *cptr32 = (PRUint32*)(imageData + (row_num*bpr));
|
||||
PRUint32 bpr = width * sizeof(PRUint32);
|
||||
PRUint32 *cptr32 = (PRUint32*)(decoder->mImageData + (row_num*bpr));
|
||||
PRBool rowHasNoAlpha = PR_TRUE;
|
||||
|
||||
if (decoder->mTransform) {
|
||||
@ -758,7 +743,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
}
|
||||
|
||||
switch (decoder->format) {
|
||||
case gfxIFormats::RGB:
|
||||
case gfxASurface::ImageFormatRGB24:
|
||||
{
|
||||
// counter for while() loops below
|
||||
PRUint32 idx = iwidth;
|
||||
@ -785,17 +770,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
{
|
||||
for (PRUint32 x=iwidth; x>0; --x) {
|
||||
*cptr32++ = GFX_PACKED_PIXEL(line[3]?0xFF:0x00, line[0], line[1], line[2]);
|
||||
if (line[3] == 0)
|
||||
rowHasNoAlpha = PR_FALSE;
|
||||
line += 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A8:
|
||||
case gfxASurface::ImageFormatARGB32:
|
||||
{
|
||||
for (PRUint32 x=width; x>0; --x) {
|
||||
*cptr32++ = GFX_PACKED_PIXEL(line[3], line[0], line[1], line[2]);
|
||||
@ -805,6 +780,10 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown PNG format!");
|
||||
NS_ABORT();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rowHasNoAlpha)
|
||||
@ -815,12 +794,13 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
if (numFrames <= 1) {
|
||||
// Only do incremental image display for the first frame
|
||||
nsIntRect r(0, row_num, width, 1);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(decoder->mFrame));
|
||||
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
|
||||
if (NS_FAILED(decoder->mImage->FrameUpdated(numFrames - 1, r))) {
|
||||
decoder->mError = PR_TRUE; /* bail */
|
||||
return;
|
||||
}
|
||||
decoder->mObserver->OnDataAvailable(nsnull, decoder->mFrame, &r);
|
||||
PRUint32 curFrame;
|
||||
decoder->mImage->GetCurrentFrameIndex(&curFrame);
|
||||
decoder->mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,8 @@
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgILoad.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
@ -72,25 +71,27 @@ public:
|
||||
virtual ~nsPNGDecoder();
|
||||
|
||||
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
PRInt32 width, PRInt32 height, gfx_format format);
|
||||
PRInt32 width, PRInt32 height,
|
||||
gfxASurface::gfxImageFormat format);
|
||||
void SetAnimFrameInfo();
|
||||
|
||||
void EndImageFrame();
|
||||
|
||||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgILoad> mImageLoad;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
png_structp mPNG;
|
||||
png_infop mInfo;
|
||||
nsIntRect mFrameRect;
|
||||
PRUint8 *mCMSLine;
|
||||
PRUint8 *interlacebuf;
|
||||
PRUint8 *mImageData;
|
||||
qcms_profile *mInProfile;
|
||||
qcms_transform *mTransform;
|
||||
|
||||
gfx_format format;
|
||||
gfxASurface::gfxImageFormat format;
|
||||
PRUint8 mChannels;
|
||||
PRPackedBool mError;
|
||||
PRPackedBool mFrameHasNoAlpha;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user