Merge places to mozilla-central.

This commit is contained in:
Shawn Wilsher 2009-07-21 09:34:00 -07:00
Родитель 39d40f70b0 625269fe92
Коммит 099fb925dc
154 изменённых файлов: 3944 добавлений и 4288 удалений

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

@ -115,9 +115,9 @@ nsHTMLImageAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
imageRequest->GetImage(getter_AddRefs(imgContainer)); imageRequest->GetImage(getter_AddRefs(imgContainer));
if (imgContainer) { if (imgContainer) {
PRUint32 numFrames; PRBool animated;
imgContainer->GetNumFrames(&numFrames); imgContainer->GetAnimated(&animated);
if (numFrames > 1) if (animated)
*aState |= nsIAccessibleStates::STATE_ANIMATED; *aState |= nsIAccessibleStates::STATE_ANIMATED;
} }

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

@ -358,7 +358,8 @@ pref("browser.tabs.closeButtons", 1);
// false return to the adjacent tab (old default) // false return to the adjacent tab (old default)
pref("browser.tabs.selectOwnerOnClose", true); 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); pref("browser.ctrlTab.recentlyUsedLimit", 7);
// Default bookmark sorting // Default bookmark sorting

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

@ -441,6 +441,12 @@
type="checkbox" type="checkbox"
command="View:FullScreen"/> command="View:FullScreen"/>
#endif #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"/> <menuseparator hidden="true" id="documentDirection-separator"/>
<menuitem id="documentDirection-swap" <menuitem id="documentDirection-swap"
hidden="true" hidden="true"

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

@ -115,6 +115,7 @@
</command> </command>
<command id="Browser:NextTab" oncommand="gBrowser.mTabContainer.advanceSelectedTab(1, true);"/> <command id="Browser:NextTab" oncommand="gBrowser.mTabContainer.advanceSelectedTab(1, true);"/>
<command id="Browser:PrevTab" 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_fullZoomReduce" oncommand="FullZoom.reduce()"/>
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/> <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/> <command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
@ -317,7 +318,9 @@
<key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/> <key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/> <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
<key key="&fullZoomResetCmd.commandkey2;" 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_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />
<key id="key_privatebrowsing" command="Tools:PrivateBrowsing" key="&privateBrowsingCmd.commandkey;" modifiers="accel,shift"/> <key id="key_privatebrowsing" command="Tools:PrivateBrowsing" key="&privateBrowsingCmd.commandkey;" modifiers="accel,shift"/>

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

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

@ -41,21 +41,49 @@
xmlns="http://www.mozilla.org/xbl" xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl"> xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="ctrlTab-thumbnail"> <binding id="ctrlTab-preview" extends="chrome://global/content/bindings/button.xml#button-base">
<content align="center"> <content pack="center">
<children/> <xul:stack>
<xul:label xbl:inherits="value=label,crop"/> <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> </content>
<handlers> <handlers>
<handler event="click" button="0" action="ctrlTab.selectThumbnail(this);"/> <handler event="mouseover" action="ctrlTab._mouseOverFocus(this);"/>
<handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/> <handler event="command" action="ctrlTab.pick(this);"/>
<handler event="click" button="1" action="ctrlTab.remove(this);"/>
#ifdef XP_MACOSX #ifdef XP_MACOSX
# Control+click is a right click on OS X # Control+click is a right click on OS X
<handler event="click" button="2"><![CDATA[ <handler event="click" button="2" action="ctrlTab.pick(this);"/>
if (!ctrlTab.sticky)
ctrlTab.selectThumbnail(this);
]]></handler>
#endif #endif
</handlers> </handlers>
</binding> </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> </bindings>

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

@ -123,24 +123,46 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
display: -moz-box; display: -moz-box;
} }
/* Tab Previews */ /* ::::: Keyboard UI Panel ::::: */
#ctrlTab-panel { .KUI-panel-closebutton {
-moz-user-focus: normal; -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
} }
.ctrlTab-thumbnail { .ctrlTab-preview > html|canvas,
-moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#ctrlTab-thumbnail"); .allTabs-preview > html|canvas {
min-width: inherit;
max-width: inherit;
min-height: inherit;
max-height: inherit;
} }
.ctrlTab-thumbnail:not([valid]) { .ctrlTab-favicon-container,
visibility: hidden; .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; display: block;
text-align: center;
}
.ctrlTab-pagePointer {
display: inline-block;
} }

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

@ -1058,6 +1058,8 @@ function BrowserStartup() {
gURLBar.setAttribute("enablehistory", "false"); gURLBar.setAttribute("enablehistory", "false");
} }
allTabs.readPref();
setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar); setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar);
} }
@ -1318,7 +1320,9 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
gBrowser.addEventListener("command", BrowserOnCommand, false); gBrowser.addEventListener("command", BrowserOnCommand, false);
tabPreviews.init(); 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 // Initialize the microsummary service by retrieving it, prompting its factory
// to create its singleton, whose constructor initializes the service. // to create its singleton, whose constructor initializes the service.
@ -1371,6 +1375,7 @@ function BrowserShutdown()
{ {
tabPreviews.uninit(); tabPreviews.uninit();
ctrlTab.uninit(); ctrlTab.uninit();
allTabs.uninit();
gGestureSupport.init(false); gGestureSupport.init(false);

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

@ -242,30 +242,44 @@
<label crop="center" flex="1" class="tooltip-label"/> <label crop="center" flex="1" class="tooltip-label"/>
</tooltip> </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"> <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" type="search"
emptytext="&ctrlTab.search.emptyText;" oncommand="allTabs.filter();"/>
oncommand="ctrlTab.search();" <spacer flex="1"/>
onfocus="ctrlTab.sticky = true;"/> <toolbarbutton class="KUI-panel-closebutton"
oncommand="allTabs.close()"
tooltiptext="&closeCmd.label;"/>
</hbox> </hbox>
<hbox class="ctrlTab-row"> <stack id="allTabs-stack">
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox> <box id="allTabs-container"/>
<vbox class="ctrlTab-thumbnail"/> <toolbarbutton id="allTabs-tab-close-button"
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox> class="tab-close-button"
</hbox> oncommand="allTabs.closeTab(event);"
<hbox class="ctrlTab-row"> tooltiptext="&closeCmd.label;"
<hbox flex="1" pack="center"><vbox class="ctrlTab-thumbnail"/></hbox> style="visibility:hidden"/>
<vbox class="ctrlTab-thumbnail"/> </stack>
<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"/>
</panel> </panel>
</popupset> </popupset>

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

@ -2879,8 +2879,11 @@
<xul:stack align="center" pack="end" chromedir="&locale.dir;"> <xul:stack align="center" pack="end" chromedir="&locale.dir;">
<xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/> <xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
<xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button" <xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
tooltiptext="&listAllTabs.label;" type="menu"
oncommand="ctrlTab.open(true);"/> tooltiptext="&listAllTabs.label;">
<xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
position="after_end"/>
</xul:toolbarbutton>
</xul:stack> </xul:stack>
<xul:toolbarbutton anonid="tabs-closebutton" <xul:toolbarbutton anonid="tabs-closebutton"
class="close-button tabs-closebutton" chromedir="&locale.dir;"/> class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
@ -3293,25 +3296,6 @@
<binding id="tabbrowser-alltabs-popup" <binding id="tabbrowser-alltabs-popup"
extends="chrome://global/content/bindings/popup.xml#popup"> extends="chrome://global/content/bindings/popup.xml#popup">
<implementation implements="nsIDOMEventListener"> <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"> <method name="_menuItemOnCommand">
<parameter name="aEvent"/> <parameter name="aEvent"/>
@ -3471,9 +3455,6 @@
<handler event="DOMMenuItemActive"> <handler event="DOMMenuItemActive">
<![CDATA[ <![CDATA[
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow)
return;
var tab = event.target.tab; var tab = event.target.tab;
if (tab) { if (tab) {
var statusText = tab.linkedBrowser.currentURI.spec; var statusText = tab.linkedBrowser.currentURI.spec;
@ -3484,16 +3465,13 @@
statusText = " "; statusText = " ";
} }
this._xulWindow.XULBrowserWindow.setOverLink(statusText, null); XULBrowserWindow.setOverLink(statusText, null);
} }
]]></handler> ]]></handler>
<handler event="DOMMenuItemInactive"> <handler event="DOMMenuItemInactive">
<![CDATA[ <![CDATA[
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow) XULBrowserWindow.setOverLink("", null);
return;
this._xulWindow.XULBrowserWindow.setOverLink("", null);
]]></handler> ]]></handler>
</handlers> </handlers>

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

@ -1,5 +1,5 @@
function test() { function test() {
waitForExplicitFinish(); gPrefService.setBoolPref("browser.ctrlTab.previews", true);
gBrowser.addTab(); gBrowser.addTab();
gBrowser.addTab(); gBrowser.addTab();
@ -9,7 +9,7 @@ function test() {
ctrlTabTest([2] , 1, 0); ctrlTabTest([2] , 1, 0);
ctrlTabTest([2, 3, 1], 2, 2); ctrlTabTest([2, 3, 1], 2, 2);
ctrlTabTest([] , 4, 2); ctrlTabTest([] , 5, 2);
{ {
let selectedIndex = gBrowser.tabContainer.selectedIndex; let selectedIndex = gBrowser.tabContainer.selectedIndex;
@ -27,9 +27,12 @@ function test() {
is(gBrowser.mTabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab"); is(gBrowser.mTabs.length, tabs - 1, "Ctrl+Tab -> Ctrl+W removes one tab");
releaseCtrl(); 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 { // test for bug 445369
selectTabs([1, 2, 0]); selectTabs([1, 2, 0]);
@ -49,12 +52,12 @@ function test() {
ok(gBrowser.selectedTab == selectedTab, ok(gBrowser.selectedTab == selectedTab,
"Ctrl+Tab*2 -> Ctrl+W -> Ctrl+Shift+Tab*2 keeps the selected tab"); "Ctrl+Tab*2 -> Ctrl+W -> Ctrl+Shift+Tab*2 keeps the selected tab");
} }
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
assertTabs(2); assertTabs(2);
ctrlTabTest([1], 1, 0); ctrlTabTest([1], 1, 0);
gBrowser.removeTab(gBrowser.tabContainer.lastChild); gBrowser.removeTab(gBrowser.tabContainer.lastChild);
assertTabs(1); assertTabs(1);
{ // test for bug 445768 { // test for bug 445768
@ -71,65 +74,8 @@ function test() {
"Ctrl+Tab doesn't change focus if one tab is open"); "Ctrl+Tab doesn't change focus if one tab is open");
} }
gBrowser.addTab(); // cleanup
gBrowser.addTab(); gPrefService.clearUserPref("browser.ctrlTab.previews");
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();
}
/* private utility functions */ /* private utility functions */
@ -140,7 +86,7 @@ function test() {
EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" }); EventUtils.synthesizeKey("VK_CONTROL", { type: "keyup" });
function isOpen() function isOpen()
ctrlTab.panel.state == "showing" || ctrlTab.panel.state == "open"; ctrlTab.isOpen;
function assertTabs(aTabs) { function assertTabs(aTabs) {
var tabs = gBrowser.mTabs.length; var tabs = gBrowser.mTabs.length;

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

@ -91,4 +91,12 @@ EXTRA_DSO_LDOPTS += \
$(NULL) $(NULL)
endif 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 include $(topsrcdir)/config/rules.mk

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

@ -47,7 +47,6 @@
#include "nsIGConfService.h" #include "nsIGConfService.h"
#include "nsIGnomeVFSService.h" #include "nsIGnomeVFSService.h"
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "gfxIImageFrame.h"
#include "nsIOutputStream.h" #include "nsIOutputStream.h"
#include "nsIProcess.h" #include "nsIProcess.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
@ -55,7 +54,6 @@
#include "nsIImageLoadingContent.h" #include "nsIImageLoadingContent.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "nsIImage.h"
#include "prprf.h" #include "prprf.h"
#ifdef MOZ_WIDGET_GTK2 #ifdef MOZ_WIDGET_GTK2
#include "nsIImageToPixbuf.h" #include "nsIImageToPixbuf.h"
@ -349,12 +347,8 @@ nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
} }
static nsresult 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 #ifndef MOZ_WIDGET_GTK2
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
#else #else
@ -363,7 +357,7 @@ WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
if (!imgToPixbuf) if (!imgToPixbuf)
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(img); GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage);
if (!pixbuf) if (!pixbuf)
return NS_ERROR_NOT_AVAILABLE; return NS_ERROR_NOT_AVAILABLE;
@ -379,8 +373,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
PRInt32 aPosition) PRInt32 aPosition)
{ {
nsresult rv; nsresult rv;
nsCOMPtr<gfxIImageFrame> gfxFrame;
nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv); nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
if (!imageContent) return rv; if (!imageContent) return rv;
@ -393,12 +385,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
rv = request->GetImage(getter_AddRefs(container)); rv = request->GetImage(getter_AddRefs(container));
if (!container) return rv; 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. // Write the background file to the home directory.
nsCAutoString filePath(PR_GetEnv("HOME")); nsCAutoString filePath(PR_GetEnv("HOME"));
@ -423,7 +409,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
filePath.Append("_wallpaper.png"); filePath.Append("_wallpaper.png");
// write the image to a file in the home dir // 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 // if the file was written successfully, set it as the system wallpaper
nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);

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

@ -41,7 +41,6 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "gfxIImageFrame.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
@ -519,23 +518,18 @@ nsWindowsShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
} }
static nsresult static nsresult
WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage) WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
{ {
PRInt32 width, height; nsRefPtr<gfxImageSurface> image;
aImage->GetWidth(&width); nsresult rv = aImage->CopyCurrentFrame(getter_AddRefs(image));
aImage->GetHeight(&height); NS_ENSURE_SUCCESS(rv, rv);
PRUint8* bits; PRInt32 width = image->Width();
PRUint32 length; PRInt32 height = image->Height();
aImage->LockImageData();
aImage->GetImageData(&bits, &length);
if (!bits) {
aImage->UnlockImageData();
return NS_ERROR_FAILURE;
}
PRUint32 bpr; PRUint8* bits = image->Data();
aImage->GetImageBytesPerRow(&bpr); PRUint32 length = image->GetDataSize();
PRUint32 bpr = PRUint32(image->Stride());
PRInt32 bitCount = bpr/width; PRInt32 bitCount = bpr/width;
// initialize these bitmap structs which we will later // initialize these bitmap structs which we will later
@ -562,7 +556,7 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
// get a file output stream // get a file output stream
nsCOMPtr<nsIOutputStream> stream; nsCOMPtr<nsIOutputStream> stream;
nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile); rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// write the bitmap headers and rgb pixel data to the file // write the bitmap headers and rgb pixel data to the file
@ -592,7 +586,6 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
stream->Close(); stream->Close();
} }
aImage->UnlockImageData();
return rv; return rv;
} }
@ -602,8 +595,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
{ {
nsresult rv; nsresult rv;
nsCOMPtr<gfxIImageFrame> gfxFrame; nsCOMPtr<imgIContainer> container;
nsCOMPtr<nsIDOMHTMLImageElement> imgElement(do_QueryInterface(aElement)); nsCOMPtr<nsIDOMHTMLImageElement> imgElement(do_QueryInterface(aElement));
if (!imgElement) { if (!imgElement) {
// XXX write background loading stuff! // XXX write background loading stuff!
@ -620,18 +612,11 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
getter_AddRefs(request)); getter_AddRefs(request));
if (!request) if (!request)
return rv; return rv;
nsCOMPtr<imgIContainer> container;
rv = request->GetImage(getter_AddRefs(container)); rv = request->GetImage(getter_AddRefs(container));
if (!container) if (!container)
return NS_ERROR_FAILURE; 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 // get the file name from localized strings
nsCOMPtr<nsIStringBundleService> nsCOMPtr<nsIStringBundleService>
bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv)); bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
@ -664,7 +649,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// write the bitmap to a file in the profile directory // 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 the file was written successfully, set it as the system wallpaper
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {

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

@ -50,6 +50,8 @@
<!ENTITY pageInfoCmd.commandkey "i"> <!ENTITY pageInfoCmd.commandkey "i">
<!ENTITY fullScreenCmd.label "Full Screen"> <!ENTITY fullScreenCmd.label "Full Screen">
<!ENTITY fullScreenCmd.accesskey "F"> <!ENTITY fullScreenCmd.accesskey "F">
<!ENTITY showAllTabsCmd.label "Show All Tabs">
<!ENTITY showAllTabsCmd.accesskey "A">
<!ENTITY fullScreenMinimize.tooltip "Minimize"> <!ENTITY fullScreenMinimize.tooltip "Minimize">
<!ENTITY fullScreenRestore.tooltip "Restore"> <!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 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 privateBrowsingNoTitle=&Cancel
privateBrowsingNeverAsk=&Do not show this message again 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 # 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. # Used as the bookmark name when saving a keyword for a search field.
addKeywordTitleAutoFill=Search %S addKeywordTitleAutoFill=Search %S

Двоичные данные
browser/themes/gnomestripe/browser/KUI-close.png Normal file

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

После

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

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

@ -1377,42 +1377,91 @@ toolbar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
-moz-image-region: rect(0px 16px 16px 0px); -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 { #ctrlTab-panel {
padding-top: 15px; padding: 10px;
} }
#ctrlTab-search { .ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
margin: 0 0 15px; margin-bottom: 2px;
} }
.ctrlTab-thumbnail { #ctrlTab-showAll {
margin-bottom: 15px; -moz-appearance: button;
cursor: pointer; color: ButtonText;
padding: 0 3px;
margin-top: 10px;
} }
.ctrlTab-thumbnail > html|canvas { /* All Tabs */
border: 1px solid ThreeDShadow;
margin: -1px; #allTabs-panel {
/* compensate for the widget border and padding to center the panel correctly */
margin-left: -13px;
} }
.ctrlTab-thumbnail[selected="true"] , #allTabs-tab-close-button {
.ctrlTab-thumbnail:hover { /*XXX without this, the closebutton can cause the panel to expand horizontally */
background: Highlight; margin-right: -16px;
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;
} }
.ctrlTab-pagePointer[selected="true"] { #allTabs-meta {
background: ThreeDDarkShadow; padding: 5px;
cursor: default; }
#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/Go-arrow.png
skin/classic/browser/identity.png skin/classic/browser/identity.png
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/KUI-close.png
skin/classic/browser/monitor.png skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png skin/classic/browser/monitor_16-10.png
* skin/classic/browser/pageInfo.css * skin/classic/browser/pageInfo.css

Двоичные данные
browser/themes/pinstripe/browser/KUI-close.png Normal file

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

После

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

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

@ -924,8 +924,9 @@ statusbarpanel#statusbar-display {
.ac-result-type-keyword, .ac-result-type-keyword,
.autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) { .autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
list-style-image: url(chrome://global/skin/icons/search-textbox.png); list-style-image: url(chrome://global/skin/icons/search-textbox.png);
width: 16px; margin: 2px;
height: 16px; width: 12px;
height: 12px;
} }
richlistitem[selected="true"][current="true"] > hbox > .ac-result-type-bookmark, richlistitem[selected="true"][current="true"] > hbox > .ac-result-type-bookmark,
@ -1515,7 +1516,7 @@ tabbrowser > tabbox {
opacity: .6; opacity: .6;
} }
.tab-text { .tabbrowser-tab > .tab-text {
margin-top: 3px; margin-top: 3px;
margin-bottom: 0; margin-bottom: 0;
font: message-box; font: message-box;
@ -2124,63 +2125,143 @@ tabpanels.plain {
} }
/* ::::: Keyboard UI Panel ::::: */ /* ::::: Keyboard UI Panel ::::: */
.KUI-panel { .KUI-panel {
-moz-appearance: none; -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; color: white;
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid rgba(100%,100%,100%,.15);
-moz-border-radius: 10px; -moz-border-radius: 20px;
margin-top: -1px;
margin-left: -1px;
} }
.KUI-panel[level="top"] , .KUI-panel[level="top"] {
#ctrlTab-panel:not([sticky]) { background-color: rgba(27%,27%,27%,.65);
background-color: rgba(68, 68, 68, .5); border-style: none;
-moz-window-shadow: 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 { #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; font-size: 1.2em;
text-shadow: 0 0 3px black, 0 0 3px black;
} }
#ctrlTab-search { #ctrlTab-showAll:focus {
margin: 0 0 20px; -moz-box-shadow: 0 0 8px white;
-moz-border-radius: 100%;
} }
.ctrlTab-thumbnail { /* All Tabs */
margin-bottom: 20px;
cursor: pointer; #allTabs-panel {
font-weight: bold; padding: 10px;
margin-left: -10px;
} }
.ctrlTab-thumbnail > html|canvas { #allTabs-panel:not(.KUI-panel) {
border: 2px solid white; -moz-appearance: none;
margin: -2px; background: rgb(27%,27%,27%) url(KUI-background.png) repeat-x;
border: none;
color: white;
} }
.ctrlTab-thumbnail[selected="true"] , #allTabs-meta {
.ctrlTab-thumbnail:hover { margin-bottom: 10px;
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-pagePointer { #allTabs-filter {
margin: 0 1em 1em; -moz-margin-start: 24px;
width: 1.5em; -moz-margin-end: 0;
height: 1.5em;
-moz-border-radius: .75em;
background: rgba(0, 0, 0, .5);
border: 1px solid rgba(255, 255, 255, .3);
cursor: pointer;
} }
.ctrlTab-pagePointer[selected="true"] { #allTabs-tab-close-button {
background: rgba(255, 255, 255, .6); /*XXX without this, the closebutton can cause the panel to expand horizontally */
cursor: default; 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/identity.png
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/KUI-background.png skin/classic/browser/KUI-background.png
skin/classic/browser/KUI-close.png
skin/classic/browser/menu-back.png skin/classic/browser/menu-back.png
skin/classic/browser/menu-forward.png skin/classic/browser/menu-forward.png
skin/classic/browser/page-livemarks.png skin/classic/browser/page-livemarks.png

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

@ -160,8 +160,9 @@ tabpanels {
} }
caption { caption {
border-bottom: 1px solid #ECECEC; -moz-padding-start: 5px;
padding: 4px 4px 0px 0px !important; padding-top: 4px;
padding-bottom: 2px;
} }
#paneMain description, #paneMain description,

Двоичные данные
browser/themes/winstripe/browser/KUI-close.png Normal file

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

После

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

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

@ -63,17 +63,29 @@
z-index: 10; 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) { #ctrlTab-panel:-moz-system-metric(windows-compositor) {
background: transparent; background: transparent;
-moz-appearance: -moz-win-glass; -moz-appearance: -moz-win-glass;
-moz-border-radius: 0; -moz-border-radius: 0;
border: none; border: none;
font: "Segoe UI", window; font: normal 1.2em "Segoe UI";
font-weight: normal;
color: black; color: black;
text-shadow: white -1px -1px .5em, white -1px 1px .5em, white 1px 1px .5em, white 1px -1px .5em; 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 ::::: */ /* ::::: fullscreen window controls ::::: */
#window-controls { #window-controls {

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

@ -1390,7 +1390,7 @@ tabpanels {
} }
/* tabbrowser-tab focus ring */ /* tabbrowser-tab focus ring */
.tab-text { .tabbrowser-tab > .tab-text {
border: 1px dotted transparent; border: 1px dotted transparent;
} }
@ -2022,63 +2022,138 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
} }
/* ::::: Keyboard UI Panel ::::: */ /* ::::: Keyboard UI Panel ::::: */
.KUI-panel { .KUI-panel {
-moz-appearance: none; -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; color: white;
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid rgba(100%,100%,100%,.15);
-moz-border-radius: 10px; -moz-border-radius: 20px;
margin-top: -1px;
margin-left: -1px;
} }
.KUI-panel[level="top"] , .KUI-panel[level="top"] {
#ctrlTab-panel:not([sticky]) { background-color: rgba(27%,27%,27%,.65);
background-color: rgba(68, 68, 68, .5); 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[src],
.allTabs-favicon[src] {
background-color: white;
width: 24px;
height: 24px;
padding: 2px;
opacity: .7;
}
/* Ctrl-Tab */
#ctrlTab-panel { #ctrlTab-panel {
padding-top: 20px; padding: 20px 10px 15px;
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;
font-weight: bold; font-weight: bold;
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 3px rgb(27%,27%,27%);
} }
.ctrlTab-thumbnail > html|canvas { .ctrlTab-preview:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
border: 2px solid white; padding-bottom: 2px;
margin: -2px;
} }
.ctrlTab-thumbnail[selected="true"] , .ctrlTab-preview:not(#ctrlTab-showAll) .tabPreview-canvas {
.ctrlTab-thumbnail:hover { margin-bottom: 2px;
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-pagePointer { .ctrlTab-preview:focus:not(#ctrlTab-showAll) .ctrlTab-preview-inner {
margin: 0 1em 1em; background-color: #ccc;
width: 1.5em; color: black;
height: 1.5em; text-shadow: 0 0 1px white;
-moz-border-radius: .75em; -moz-box-shadow: 0 0 0 1px rgba(255,255,255,.5), 0 0 5px 1px Highlight, 0 0 8px white;
background: rgba(0, 0, 0, .5); padding: 2px;
border: 1px solid rgba(255, 255, 255, .3); margin: -2px -2px 0;
cursor: pointer;
} }
.ctrlTab-pagePointer[selected="true"] { .ctrlTab-preview:focus .tabPreview-canvas {
background: rgba(255, 255, 255, .6); -moz-box-shadow: none;
cursor: default; }
#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/Info.png (Info.png)
skin/classic/browser/identity.png (identity.png) skin/classic/browser/identity.png (identity.png)
skin/classic/browser/KUI-background.png skin/classic/browser/KUI-background.png
skin/classic/browser/KUI-close.png
skin/classic/browser/mainwindow-dropdown-arrow.png skin/classic/browser/mainwindow-dropdown-arrow.png
skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png (pageInfo.png) 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/Info.png (Info-aero.png)
skin/classic/aero/browser/identity.png (identity-aero.png) skin/classic/aero/browser/identity.png (identity-aero.png)
skin/classic/aero/browser/KUI-background.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/mainwindow-dropdown-arrow.png (mainwindow-dropdown-arrow-aero.png)
skin/classic/aero/browser/pageInfo.css skin/classic/aero/browser/pageInfo.css
skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png) skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png)

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

@ -49,7 +49,6 @@ int mainReturn = 0;
BOOL b16 = FALSE; BOOL b16 = FALSE;
BOOL bSimple = FALSE; BOOL bSimple = FALSE;
// freopen won't work on stdout in win16
FILE *pAltFile = stdout; FILE *pAltFile = stdout;
CStringArray includeDirectories; CStringArray includeDirectories;

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

@ -78,12 +78,12 @@ class nsIThreadJSContextStack;
class nsIParserService; class nsIParserService;
class nsIIOService; class nsIIOService;
class nsIURI; class nsIURI;
class imgIContainer;
class imgIDecoderObserver; class imgIDecoderObserver;
class imgIRequest; class imgIRequest;
class imgILoader; class imgILoader;
class imgICache; class imgICache;
class nsIPrefBranch; class nsIPrefBranch;
class nsIImage;
class nsIImageLoadingContent; class nsIImageLoadingContent;
class nsIDOMHTMLFormElement; class nsIDOMHTMLFormElement;
class nsIDOMDocument; class nsIDOMDocument;
@ -654,13 +654,13 @@ public:
static PRBool IsImageInCache(nsIURI* aURI); 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 aContent The image loading content. Must not be null.
* @param aRequest The image request [out] * @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 * Method that decides whether a content node is draggable

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

@ -80,7 +80,6 @@
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsIImage.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
@ -93,6 +92,7 @@
#include "nsEscape.h" #include "nsEscape.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIMIMEService.h" #include "nsIMIMEService.h"
#include "imgIContainer.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "nsContentCID.h" #include "nsContentCID.h"
#include "nsDOMDataTransfer.h" #include "nsDOMDataTransfer.h"
@ -171,7 +171,7 @@ private:
nsString mInfoString; nsString mInfoString;
PRBool mIsAnchor; PRBool mIsAnchor;
nsCOMPtr<nsIImage> mImage; nsCOMPtr<imgIContainer> mImage;
}; };
@ -972,7 +972,7 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer,
nsCOMPtr<imgIRequest> imgRequest; nsCOMPtr<imgIRequest> imgRequest;
// grab the image data, and its request. // grab the image data, and its request.
nsCOMPtr<nsIImage> img = nsCOMPtr<imgIContainer> img =
nsContentUtils::GetImageFromContent(image, nsContentUtils::GetImageFromContent(image,
getter_AddRefs(imgRequest)); getter_AddRefs(imgRequest));

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

@ -53,7 +53,6 @@ class nsIDOMDocument;
class nsIDOMDragEvent; class nsIDOMDragEvent;
class nsISelection; class nsISelection;
class nsITransferable; class nsITransferable;
class nsIImage;
class nsIPresShell; class nsIPresShell;
class nsPresContext; class nsPresContext;
class nsIContent; class nsIContent;

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

@ -98,8 +98,6 @@
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgILoader.h" #include "imgILoader.h"
#include "nsIImage.h"
#include "gfxIImageFrame.h"
#include "nsIImageLoadingContent.h" #include "nsIImageLoadingContent.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
@ -2446,7 +2444,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
} }
// static // static
already_AddRefed<nsIImage> already_AddRefed<imgIContainer>
nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent, nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
imgIRequest **aRequest) imgIRequest **aRequest)
{ {
@ -2470,26 +2468,11 @@ nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
return nsnull; 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) { if (aRequest) {
imgRequest.swap(*aRequest); imgRequest.swap(*aRequest);
} }
nsIImage* image = nsnull; return imgContainer.forget();
CallGetInterface(ir.get(), &image);
return image;
} }
// static // static

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

@ -49,6 +49,7 @@
#include "nsXPCOM.h" #include "nsXPCOM.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsIDOMRange.h" #include "nsIDOMRange.h"
#include "imgIContainer.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIContentViewerEdit.h" #include "nsIContentViewerEdit.h"
@ -65,7 +66,6 @@
// image copy stuff // image copy stuff
#include "nsIImageLoadingContent.h" #include "nsIImageLoadingContent.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsContentCID.h" #include "nsContentCID.h"
@ -463,7 +463,7 @@ nsCopySupport::ImageCopy(nsIImageLoadingContent* aImageElement,
if (aCopyFlags & nsIContentViewerEdit::COPY_IMAGE_DATA) { if (aCopyFlags & nsIContentViewerEdit::COPY_IMAGE_DATA) {
// get the image data from the element // get the image data from the element
nsCOMPtr<nsIImage> image = nsCOMPtr<imgIContainer> image =
nsContentUtils::GetImageFromContent(aImageElement); nsContentUtils::GetImageFromContent(aImageElement);
NS_ENSURE_TRUE(image, NS_ERROR_FAILURE); NS_ENSURE_TRUE(image, NS_ERROR_FAILURE);

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

@ -55,7 +55,6 @@
#include "nsIURI.h" #include "nsIURI.h"
#include "nsILoadGroup.h" #include "nsILoadGroup.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "imgILoader.h" #include "imgILoader.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
@ -158,10 +157,9 @@ nsImageLoadingContent::~nsImageLoadingContent()
*/ */
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::FrameChanged(imgIContainer* aContainer, nsImageLoadingContent::FrameChanged(imgIContainer* aContainer,
gfxIImageFrame* aFrame,
nsIntRect* aDirtyRect) nsIntRect* aDirtyRect)
{ {
LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aFrame, aDirtyRect)); LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aDirtyRect));
return NS_OK; return NS_OK;
} }
@ -196,7 +194,7 @@ nsImageLoadingContent::OnStartContainer(imgIRequest* aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest, nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
gfxIImageFrame* aFrame) PRUint32 aFrame)
{ {
LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame)); LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame));
return NS_OK; return NS_OK;
@ -204,16 +202,16 @@ nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest, nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest,
gfxIImageFrame* aFrame, PRBool aCurrentFrame,
const nsIntRect* aRect) const nsIntRect* aRect)
{ {
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aFrame, aRect)); LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aCurrentFrame, aRect));
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest, nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
gfxIImageFrame* aFrame) PRUint32 aFrame)
{ {
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame)); LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
return NS_OK; return NS_OK;

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

@ -58,14 +58,14 @@ nsStubImageDecoderObserver::OnStartContainer(imgIRequest *aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsStubImageDecoderObserver::OnStartFrame(imgIRequest *aRequest, nsStubImageDecoderObserver::OnStartFrame(imgIRequest *aRequest,
gfxIImageFrame *aFrame) PRUint32 aFrame)
{ {
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest, nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect * aRect) const nsIntRect * aRect)
{ {
return NS_OK; return NS_OK;
@ -73,7 +73,7 @@ nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsStubImageDecoderObserver::OnStopFrame(imgIRequest *aRequest, nsStubImageDecoderObserver::OnStopFrame(imgIRequest *aRequest,
gfxIImageFrame *aFrame) PRUint32 aFrame)
{ {
return NS_OK; return NS_OK;
} }
@ -102,7 +102,6 @@ nsStubImageDecoderObserver::OnStopRequest(imgIRequest *aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer, nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *aFrame,
nsIntRect * aDirtyRect) nsIntRect * aDirtyRect)
{ {
return NS_OK; return NS_OK;

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

@ -61,8 +61,6 @@
#include "nsIDOMSVGURIReference.h" #include "nsIDOMSVGURIReference.h"
#include "nsImageLoadingContent.h" #include "nsImageLoadingContent.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIImage.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsSVGPreserveAspectRatio.h" #include "nsSVGPreserveAspectRatio.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
@ -5191,8 +5189,7 @@ public:
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver // imgIContainerObserver
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
nsIntRect *dirtyRect);
// imgIContainerObserver // imgIContainerObserver
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
imgIContainer *aContainer); imgIContainer *aContainer);
@ -5378,31 +5375,27 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance,
if (currentRequest) if (currentRequest)
currentRequest->GetImage(getter_AddRefs(imageContainer)); currentRequest->GetImage(getter_AddRefs(imageContainer));
nsCOMPtr<gfxIImageFrame> currentFrame; nsRefPtr<gfxASurface> currentFrame;
if (imageContainer) if (imageContainer)
imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame)); imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
nsRefPtr<gfxPattern> thebesPattern = nsnull; // We need to wrap the surface in a pattern to have somewhere to set the
if (currentFrame) { // graphics filter.
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame)); nsRefPtr<gfxPattern> thebesPattern;
if (currentFrame)
img->GetPattern(getter_AddRefs(thebesPattern)); thebesPattern = new gfxPattern(currentFrame);
}
if (thebesPattern) { if (thebesPattern) {
thebesPattern->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame)); thebesPattern->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
PRInt32 x, y, nativeWidth, nativeHeight; PRInt32 nativeWidth, nativeHeight;
currentFrame->GetX(&x); imageContainer->GetWidth(&nativeWidth);
currentFrame->GetY(&y); imageContainer->GetHeight(&nativeHeight);
currentFrame->GetWidth(&nativeWidth);
currentFrame->GetHeight(&nativeHeight);
nsCOMPtr<nsIDOMSVGMatrix> trans; nsCOMPtr<nsIDOMSVGMatrix> trans;
const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion; const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(), trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
x, y, 0, 0, nativeWidth, nativeHeight,
nativeWidth, nativeHeight,
mPreserveAspectRatio); mPreserveAspectRatio);
nsCOMPtr<nsIDOMSVGMatrix> xy, fini; nsCOMPtr<nsIDOMSVGMatrix> xy, fini;
NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.X(), filterSubregion.Y()); NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.X(), filterSubregion.Y());
@ -5457,11 +5450,10 @@ nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest,
NS_IMETHODIMP NS_IMETHODIMP
nsSVGFEImageElement::FrameChanged(imgIContainer *aContainer, nsSVGFEImageElement::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
nsresult rv = nsresult rv =
nsImageLoadingContent::FrameChanged(aContainer, newframe, dirtyRect); nsImageLoadingContent::FrameChanged(aContainer, dirtyRect);
Invalidate(); Invalidate();
return rv; return rv;
} }

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

@ -85,7 +85,6 @@
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIParser.h" #include "nsIParser.h"
#include "nsParserCIID.h" #include "nsParserCIID.h"
#include "nsIImage.h"
#include "nsXPCOM.h" #include "nsXPCOM.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "nsLinebreakConverter.h" #include "nsLinebreakConverter.h"

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

@ -93,7 +93,6 @@
#include "nsIDOMDocumentFragment.h" #include "nsIDOMDocumentFragment.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIImage.h"
#include "nsXPCOM.h" #include "nsXPCOM.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#include "SetDocTitleTxn.h" #include "SetDocTitleTxn.h"

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

@ -181,12 +181,13 @@ nsContentBlocker::ShouldLoad(PRUint32 aContentType,
rv = TestPermission(aContentLocation, aRequestingLocation, aContentType, rv = TestPermission(aContentLocation, aRequestingLocation, aContentType,
&shouldLoad, &fromPrefs); &shouldLoad, &fromPrefs);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (!shouldLoad) if (!shouldLoad) {
if (fromPrefs) if (fromPrefs) {
*aDecision = nsIContentPolicy::REJECT_TYPE; *aDecision = nsIContentPolicy::REJECT_TYPE;
else } else {
*aDecision = nsIContentPolicy::REJECT_SERVER; *aDecision = nsIContentPolicy::REJECT_SERVER;
}
}
if (aContentType != nsIContentPolicy::TYPE_OBJECT || aMimeGuess.IsEmpty()) if (aContentType != nsIContentPolicy::TYPE_OBJECT || aMimeGuess.IsEmpty())
return NS_OK; return NS_OK;

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

@ -50,7 +50,6 @@ XPIDLSRCS = \
nsIFontEnumerator.idl \ nsIFontEnumerator.idl \
nsIScriptableRegion.idl \ nsIScriptableRegion.idl \
gfxIFormats.idl \ gfxIFormats.idl \
gfxIImageFrame.idl \
gfxidltypes.idl \ gfxidltypes.idl \
$(NULL) $(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 \ nsIRenderingContext.h \
nsIFontMetrics.h \ nsIFontMetrics.h \
nsIDeviceContext.h \ nsIDeviceContext.h \
nsIImage.h \
nsGfxCIID.h \ nsGfxCIID.h \
nsIRegion.h \ nsIRegion.h \
nsITheme.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 \ xpconnect \
$(NULL) $(NULL)
DIRS = shared thebes DIRS = thebes
ifdef MOZ_ENABLE_POSTSCRIPT ifdef MOZ_ENABLE_POSTSCRIPT
DIRS += psshared 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 = \ CPPSRCS = \
nsThebesDeviceContext.cpp \ nsThebesDeviceContext.cpp \
nsThebesImage.cpp \
nsThebesRegion.cpp \ nsThebesRegion.cpp \
nsThebesGfxFactory.cpp \ nsThebesGfxFactory.cpp \
nsThebesRenderingContext.cpp \ nsThebesRenderingContext.cpp \
@ -128,7 +127,6 @@ LOCAL_INCLUDES = \
$(NULL) $(NULL)
EXTRA_DSO_LDOPTS += \ EXTRA_DSO_LDOPTS += \
../shared/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX) \
$(LIBS_DIR) \ $(LIBS_DIR) \
$(EXTRA_DSO_LIBS) \ $(EXTRA_DSO_LIBS) \
$(DEPTH)/modules/libutil/src/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \ $(DEPTH)/modules/libutil/src/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \

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

@ -42,21 +42,17 @@
#include "nsGfxCIID.h" #include "nsGfxCIID.h"
#include "nsScriptableRegion.h" #include "nsScriptableRegion.h"
#include "gfxImageFrame.h"
#include "nsThebesDeviceContext.h" #include "nsThebesDeviceContext.h"
#include "nsThebesRenderingContext.h" #include "nsThebesRenderingContext.h"
#include "nsThebesImage.h"
#include "nsThebesRegion.h" #include "nsThebesRegion.h"
#include "nsThebesFontMetrics.h" #include "nsThebesFontMetrics.h"
#include "nsThebesFontEnumerator.h" #include "nsThebesFontEnumerator.h"
#include "gfxPlatform.h" #include "gfxPlatform.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontMetrics) NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontMetrics)
NS_GENERIC_FACTORY_CONSTRUCTOR(gfxImageFrame)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesDeviceContext) NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesDeviceContext)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRenderingContext) NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRenderingContext)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesImage)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRegion) NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRegion)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontEnumerator) NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontEnumerator)
@ -119,10 +115,6 @@ static const nsModuleComponentInfo components[] =
NS_RENDERING_CONTEXT_CID, NS_RENDERING_CONTEXT_CID,
"@mozilla.org/gfx/renderingcontext;1", "@mozilla.org/gfx/renderingcontext;1",
nsThebesRenderingContextConstructor }, nsThebesRenderingContextConstructor },
{ "Thebes nsImage",
NS_IMAGE_CID,
"@mozilla.org/gfx/image;1",
nsThebesImageConstructor },
{ "Thebes Region", { "Thebes Region",
NS_REGION_CID, NS_REGION_CID,
"@mozilla.org/gfx/region/nsThebes;1", "@mozilla.org/gfx/region/nsThebes;1",
@ -131,10 +123,6 @@ static const nsModuleComponentInfo components[] =
NS_SCRIPTABLE_REGION_CID, NS_SCRIPTABLE_REGION_CID,
"@mozilla.org/gfx/region;1", "@mozilla.org/gfx/region;1",
nsScriptableRegionConstructor }, nsScriptableRegionConstructor },
{ "image frame",
GFX_IMAGEFRAME_CID,
"@mozilla.org/gfx/image/frame;2",
gfxImageFrameConstructor },
}; };
static nsresult 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 "nsIInterfaceRequestorUtils.h"
#include "nsGfxCIID.h" #include "nsGfxCIID.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIImage.h"
#include "nsThebesRegion.h" #include "nsThebesRegion.h"
#include "nsThebesImage.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>

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

@ -54,8 +54,6 @@
#include "nsIThebesFontMetrics.h" #include "nsIThebesFontMetrics.h"
#include "gfxContext.h" #include "gfxContext.h"
class nsIImage;
class nsThebesRenderingContext : public nsIRenderingContext class nsThebesRenderingContext : public nsIRenderingContext
{ {
public: public:

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

@ -3044,7 +3044,7 @@ class RegExpNativeCompiler {
exit->re_flags = re->flags; exit->re_flags = re->flags;
exit->re_length = re_length; exit->re_length = re_length;
memcpy(exit->re_chars, re_chars, re_length * sizeof(jschar)); 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; return guard;
} }

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

@ -3607,7 +3607,7 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote)
} }
if (!stable) { 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 * 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 { } else {
exit->target = fragment->root; 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); compile(tm);
@ -3766,7 +3766,7 @@ TraceRecorder::endLoop(JSTraceMonitor* tm)
} }
fragment->lastIns = fragment->lastIns =
lir->insGuard(LIR_x, NULL, createGuardRecord(snapshot(LOOP_EXIT))); lir->insGuard(LIR_x, lir->insImm(1), createGuardRecord(snapshot(LOOP_EXIT)));
compile(tm); compile(tm);
if (tm->fragmento->assm()->error() != nanojit::None) 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", "%s: %s %s -> pc=%p imacpc=%p sp%+ld rp%+ld",
formatRef(i), formatRef(i),
lirNames[i->opcode()], lirNames[i->opcode()],
i->oprnd1() ? formatRef(i->oprnd1()) : "", i->oprnd1()->isCond() ? formatRef(i->oprnd1()) : "",
(void *)x->pc, (void *)x->pc,
(void *)x->imacpc, (void *)x->imacpc,
(long int)x->sp_adj, (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. // Tell nanojit not to discard or defer stack writes before this call.
LIns* guardRec = createGuardRecord(exit); LIns* guardRec = createGuardRecord(exit);
lir->insGuard(LIR_xbarrier, NULL, guardRec); lir->insGuard(LIR_xbarrier, guardRec, guardRec);
} }
LIns* res_ins = lir->insCall(known->builtin, args); LIns* res_ins = lir->insCall(known->builtin, args);
@ -10263,7 +10263,7 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
dslots_ins, dslots_ins,
-(int)sizeof(jsval))), -(int)sizeof(jsval))),
NULL); NULL);
lir->insGuard(LIR_x, NULL, createGuardRecord(exit)); lir->insGuard(LIR_x, lir->insImm(1), createGuardRecord(exit));
LIns* label = lir->ins0(LIR_label); LIns* label = lir->ins0(LIR_label);
if (br1) if (br1)
br1->setTarget(label); br1->setTarget(label);

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

@ -638,7 +638,7 @@ LirasmAssembler::endFragment()
memset(exit, 0, sizeof(SideExit)); memset(exit, 0, sizeof(SideExit));
exit->guards = NULL; exit->guards = NULL;
exit->from = exit->target = mFragment; 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); ::compile(mParent->mFragmento->assm(), mFragment);

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

@ -270,14 +270,6 @@ namespace nanojit
return ins; 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) LInsp LirBufWriter::insLoad(LOpcode op, LInsp base, int32_t d)
{ {
LInsLd* insLd = (LInsLd*)_buf->makeRoom(sizeof(LInsLd)); LInsLd* insLd = (LInsLd*)_buf->makeRoom(sizeof(LInsLd));
@ -413,7 +405,7 @@ namespace nanojit
} }
iop = ((LInsp)i)->opcode(); iop = ((LInsp)i)->opcode();
} }
while (LIR_skip == iop); while (iop==LIR_skip || iop==LIR_2);
_i = (LInsp)i; _i = (LInsp)i;
return cur; return cur;
} }
@ -449,11 +441,6 @@ namespace nanojit
return LRK_Op2 == repKinds[opcode()]; return LRK_Op2 == repKinds[opcode()];
} }
bool LIns::isLInsOp3() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Op3 == repKinds[opcode()];
}
bool LIns::isLInsLd() const { bool LIns::isLInsLd() const {
NanoAssert(LRK_None != repKinds[opcode()]); NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Ld == repKinds[opcode()]; return LRK_Ld == repKinds[opcode()];
@ -660,6 +647,16 @@ namespace nanojit
LIns* ExprFilter::ins2(LOpcode v, LIns* oprnd1, LIns* oprnd2) LIns* ExprFilter::ins2(LOpcode v, LIns* oprnd1, LIns* oprnd2)
{ {
NanoAssert(oprnd1 && 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) if (oprnd1 == oprnd2)
{ {
switch (v) { switch (v) {
@ -893,22 +890,6 @@ namespace nanojit
return out->ins2(v, oprnd1, oprnd2); 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) LIns* ExprFilter::insGuard(LOpcode v, LInsp c, LInsp x)
{ {
if (v == LIR_xt || v == LIR_xf) { if (v == LIR_xt || v == LIR_xf) {
@ -925,7 +906,7 @@ namespace nanojit
// so assert in debug builds. // so assert in debug builds.
NanoAssertMsg(0, "Constantly false guard detected"); NanoAssertMsg(0, "Constantly false guard detected");
#endif #endif
return out->insGuard(LIR_x, NULL, x); return out->insGuard(LIR_x, out->insImm(1), x);
} }
} }
else { else {
@ -995,7 +976,7 @@ namespace nanojit
} }
if (avmplus::AvmCore::use_cmov()) 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 LInsp ncond = ins1(LIR_neg, cond); // cond ? -1 : 0
return ins2(LIR_or, return ins2(LIR_or,
@ -1193,9 +1174,7 @@ namespace nanojit
return hashLoad(op, i->oprnd1(), i->disp()); return hashLoad(op, i->oprnd1(), i->disp());
default: default:
if (operandCount[op] == 3) if (operandCount[op] == 2)
return hash3(op, i->oprnd1(), i->oprnd2(), i->oprnd3());
else if (operandCount[op] == 2)
return hash2(op, i->oprnd1(), i->oprnd2()); return hash2(op, i->oprnd1(), i->oprnd2());
else else
return hash1(op, i->oprnd1()); return hash1(op, i->oprnd1());
@ -1248,8 +1227,7 @@ namespace nanojit
{ {
const uint32_t count = operandCount[op]; const uint32_t count = operandCount[op];
if ((count >= 1 && a->oprnd1() != b->oprnd1()) || if ((count >= 1 && a->oprnd1() != b->oprnd1()) ||
(count >= 2 && a->oprnd2() != b->oprnd2()) || (count >= 2 && a->oprnd2() != b->oprnd2()))
(count >= 3 && a->oprnd3() != b->oprnd3()))
return false; return false;
return true; return true;
} }
@ -1335,13 +1313,6 @@ namespace nanojit
return _hashfinish(_hashptr(hash, b)); 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 LInsHashSet::hashLoad(LOpcode op, LInsp a, int32_t d) {
uint32_t hash = _hash8(0,uint8_t(op)); uint32_t hash = _hash8(0,uint8_t(op));
hash = _hashptr(hash, a); hash = _hashptr(hash, a);
@ -1423,23 +1394,6 @@ namespace nanojit
return k; 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) LInsp LInsHashSet::findLoad(LOpcode op, LInsp a, int32_t d, uint32_t &i)
{ {
uint32_t cap = m_cap; uint32_t cap = m_cap;
@ -1960,17 +1914,6 @@ namespace nanojit
return out->ins2(v,a,b); 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) LIns* CseFilter::insLoad(LOpcode v, LInsp base, int32_t disp)
{ {
if (isCseOpcode(v)) { if (isCseOpcode(v)) {

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

@ -280,7 +280,6 @@ namespace nanojit
LRK_Op0, LRK_Op0,
LRK_Op1, LRK_Op1,
LRK_Op2, LRK_Op2,
LRK_Op3,
LRK_Ld, LRK_Ld,
LRK_Sti, LRK_Sti,
LRK_Sk, LRK_Sk,
@ -335,24 +334,6 @@ namespace nanojit
LIns* getLIns() { return (LIns*)&ins; }; 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. // Used for all loads.
class LInsLd class LInsLd
{ {
@ -479,7 +460,6 @@ namespace nanojit
LInsOp0* toLInsOp0() const { return (LInsOp0*)( uintptr_t(this+1) - sizeof(LInsOp0) ); } LInsOp0* toLInsOp0() const { return (LInsOp0*)( uintptr_t(this+1) - sizeof(LInsOp0) ); }
LInsOp1* toLInsOp1() const { return (LInsOp1*)( uintptr_t(this+1) - sizeof(LInsOp1) ); } LInsOp1* toLInsOp1() const { return (LInsOp1*)( uintptr_t(this+1) - sizeof(LInsOp1) ); }
LInsOp2* toLInsOp2() const { return (LInsOp2*)( uintptr_t(this+1) - sizeof(LInsOp2) ); } 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 ) ); } LInsLd* toLInsLd() const { return (LInsLd* )( uintptr_t(this+1) - sizeof(LInsLd ) ); }
LInsSti* toLInsSti() const { return (LInsSti*)( uintptr_t(this+1) - sizeof(LInsSti) ); } LInsSti* toLInsSti() const { return (LInsSti*)( uintptr_t(this+1) - sizeof(LInsSti) ); }
LInsSk* toLInsSk() const { return (LInsSk* )( uintptr_t(this+1) - sizeof(LInsSk ) ); } 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(LInsOp0) == 1*sizeof(void*));
NanoStaticAssert(sizeof(LInsOp1) == 2*sizeof(void*)); NanoStaticAssert(sizeof(LInsOp1) == 2*sizeof(void*));
NanoStaticAssert(sizeof(LInsOp2) == 3*sizeof(void*)); NanoStaticAssert(sizeof(LInsOp2) == 3*sizeof(void*));
NanoStaticAssert(sizeof(LInsOp3) == 4*sizeof(void*));
NanoStaticAssert(sizeof(LInsLd) == 3*sizeof(void*)); NanoStaticAssert(sizeof(LInsLd) == 3*sizeof(void*));
NanoStaticAssert(sizeof(LInsSti) == 4*sizeof(void*)); NanoStaticAssert(sizeof(LInsSti) == 4*sizeof(void*));
NanoStaticAssert(sizeof(LInsSk) == 2*sizeof(void*)); NanoStaticAssert(sizeof(LInsSk) == 2*sizeof(void*));
@ -512,22 +491,18 @@ namespace nanojit
NanoStaticAssert(sizeof(LInsI64) == 3*sizeof(void*)); NanoStaticAssert(sizeof(LInsI64) == 3*sizeof(void*));
#endif #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. // because oprnd1() is used for all of them.
NanoStaticAssert( (offsetof(LInsOp1, ins) - offsetof(LInsOp1, oprnd_1)) == NanoStaticAssert( (offsetof(LInsOp1, ins) - offsetof(LInsOp1, oprnd_1)) ==
(offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_1)) ); (offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_1)) );
NanoStaticAssert( (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)) ); (offsetof(LInsLd, ins) - offsetof(LInsLd, oprnd_1)) );
NanoStaticAssert( (offsetof(LInsLd, ins) - offsetof(LInsLd, oprnd_1)) == NanoStaticAssert( (offsetof(LInsLd, ins) - offsetof(LInsLd, oprnd_1)) ==
(offsetof(LInsSti, ins) - offsetof(LInsSti, 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. // because oprnd2() is used for both of them.
NanoStaticAssert( (offsetof(LInsOp2, ins) - offsetof(LInsOp2, oprnd_2)) == 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)) ); (offsetof(LInsSti, ins) - offsetof(LInsSti, oprnd_2)) );
} }
@ -550,14 +525,6 @@ namespace nanojit
toLInsOp2()->oprnd_2 = oprnd2; toLInsOp2()->oprnd_2 = oprnd2;
NanoAssert(isLInsOp2()); 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) { void initLInsLd(LOpcode opcode, LIns* val, int32_t d) {
lastWord.clear(); lastWord.clear();
lastWord.opcode = opcode; lastWord.opcode = opcode;
@ -612,17 +579,13 @@ namespace nanojit
} }
LIns* oprnd1() const { LIns* oprnd1() const {
NanoAssert(isLInsOp1() || isLInsOp2() || isLInsOp3() || isLInsLd() || isLInsSti()); NanoAssert(isLInsOp1() || isLInsOp2() || isLInsLd() || isLInsSti());
return toLInsOp2()->oprnd_1; return toLInsOp2()->oprnd_1;
} }
LIns* oprnd2() const { LIns* oprnd2() const {
NanoAssert(isLInsOp2() || isLInsOp3() || isLInsSti()); NanoAssert(isLInsOp2() || isLInsSti());
return toLInsOp2()->oprnd_2; return toLInsOp2()->oprnd_2;
} }
LIns* oprnd3() const {
NanoAssert(isLInsOp3());
return toLInsOp3()->oprnd_3;
}
LIns* prevLIns() const { LIns* prevLIns() const {
NanoAssert(isLInsSk()); NanoAssert(isLInsSk());
@ -678,7 +641,6 @@ namespace nanojit
bool isLInsOp0() const; bool isLInsOp0() const;
bool isLInsOp1() const; bool isLInsOp1() const;
bool isLInsOp2() const; bool isLInsOp2() const;
bool isLInsOp3() const;
bool isLInsSti() const; bool isLInsSti() const;
bool isLInsLd() const; bool isLInsLd() const;
bool isLInsSk() const; bool isLInsSk() const;
@ -773,9 +735,6 @@ namespace nanojit
virtual LInsp ins2(LOpcode v, LIns* a, LIns* b) { virtual LInsp ins2(LOpcode v, LIns* a, LIns* b) {
return out->ins2(v, a, 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) { virtual LInsp insGuard(LOpcode v, LIns *c, LIns *x) {
return out->insGuard(v, c, 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)); return isRetOpcode(v) ? add_flush(out->ins1(v, a)) : add(out->ins1(v, a));
} }
LIns* ins2(LOpcode v, LInsp a, LInsp b) { LIns* ins2(LOpcode v, LInsp a, LInsp b) {
return add(out->ins2(v, a, b)); return v == LIR_2 ? out->ins2(v,a,b) : add(out->ins2(v, a, b));
}
LIns* ins3(LOpcode v, LInsp a, LInsp b, LInsp c) {
return add(out->ins3(v, a, b, c));
} }
LIns* insCall(const CallInfo *call, LInsp args[]) { LIns* insCall(const CallInfo *call, LInsp args[]) {
return add_flush(out->insCall(call, args)); return add_flush(out->insCall(call, args));
@ -1009,7 +965,6 @@ namespace nanojit
ExprFilter(LirWriter *out) : LirWriter(out) {} ExprFilter(LirWriter *out) : LirWriter(out) {}
LIns* ins1(LOpcode v, LIns* a); LIns* ins1(LOpcode v, LIns* a);
LIns* ins2(LOpcode v, LIns* a, LIns* b); 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* insGuard(LOpcode, LIns *cond, LIns *);
LIns* insBranch(LOpcode, LIns *cond, LIns *target); LIns* insBranch(LOpcode, LIns *cond, LIns *target);
}; };
@ -1032,13 +987,13 @@ namespace nanojit
void FASTCALL grow(); void FASTCALL grow();
public: public:
LInsHashSet(GC* gc); LInsHashSet(GC* gc);
~LInsHashSet(); ~LInsHashSet();
LInsp find32(int32_t a, uint32_t &i); LInsp find32(int32_t a, uint32_t &i);
LInsp find64(uint64_t a, uint32_t &i); LInsp find64(uint64_t a, uint32_t &i);
LInsp find1(LOpcode v, LInsp 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 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 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 findcall(const CallInfo *call, uint32_t argc, LInsp args[], uint32_t &i);
LInsp add(LInsp i, uint32_t k); LInsp add(LInsp i, uint32_t k);
@ -1049,7 +1004,6 @@ namespace nanojit
static uint32_t FASTCALL hashimmq(uint64_t); static uint32_t FASTCALL hashimmq(uint64_t);
static uint32_t FASTCALL hash1(LOpcode v, LInsp); static uint32_t FASTCALL hash1(LOpcode v, LInsp);
static uint32_t FASTCALL hash2(LOpcode v, LInsp, 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 hashLoad(LOpcode v, LInsp, int32_t);
static uint32_t FASTCALL hashcall(const CallInfo *call, uint32_t argc, LInsp args[]); static uint32_t FASTCALL hashcall(const CallInfo *call, uint32_t argc, LInsp args[]);
}; };
@ -1064,7 +1018,6 @@ namespace nanojit
LIns* ins0(LOpcode v); LIns* ins0(LOpcode v);
LIns* ins1(LOpcode v, LInsp); LIns* ins1(LOpcode v, LInsp);
LIns* ins2(LOpcode v, LInsp, LInsp); LIns* ins2(LOpcode v, LInsp, LInsp);
LIns* ins3(LOpcode v, LInsp, LInsp, LInsp);
LIns* insLoad(LOpcode op, LInsp cond, int32_t d); LIns* insLoad(LOpcode op, LInsp cond, int32_t d);
LIns* insCall(const CallInfo *call, LInsp args[]); LIns* insCall(const CallInfo *call, LInsp args[]);
LIns* insGuard(LOpcode op, LInsp cond, LIns *x); LIns* insGuard(LOpcode op, LInsp cond, LIns *x);
@ -1124,7 +1077,6 @@ namespace nanojit
LInsp ins0(LOpcode op); LInsp ins0(LOpcode op);
LInsp ins1(LOpcode op, LInsp o1); LInsp ins1(LOpcode op, LInsp o1);
LInsp ins2(LOpcode op, LInsp o1, LInsp o2); 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 insParam(int32_t i, int32_t kind);
LInsp insImm(int32_t imm); LInsp insImm(int32_t imm);
LInsp insImmq(uint64_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(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) #if defined(NANOJIT_64BIT)
OPDEF(callh, 26,-1, None) // unused on 64-bit machines OPDEF(callh, 26,-1, None) // unused on 64-bit machines
#else #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(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) 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(file, 1, 2, Op1) // source filename for debug symbols
OPDEF64(line, 2, 2, Op1) // source line number 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 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. // this marker are subject to CSE.
OPDEF64(quad, LIR_int, 0, I64) // 64-bit (quad) constant value 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(unused26_64, 26,-1, None)
OPDEF64(unused27_64, 27,-1, None) OPDEF64(unused27_64, 27,-1, None)

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

@ -2219,10 +2219,14 @@ Assembler::asm_cmov(LInsp ins)
{ {
NanoAssert(ins->opcode() == LIR_cmov); NanoAssert(ins->opcode() == LIR_cmov);
LIns* condval = ins->oprnd1(); LIns* condval = ins->oprnd1();
LIns* iftrue = ins->oprnd2();
LIns* iffalse = ins->oprnd3();
NanoAssert(condval->isCmp()); 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()); NanoAssert(!iftrue->isQuad() && !iffalse->isQuad());
const Register rr = prepResultReg(ins, GpRegs); const Register rr = prepResultReg(ins, GpRegs);

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

@ -764,10 +764,14 @@ namespace nanojit
underrunProtect(4); underrunProtect(4);
LOpcode op = ins->opcode(); LOpcode op = ins->opcode();
LIns* condval = ins->oprnd1(); LIns* condval = ins->oprnd1();
LIns* iftrue = ins->oprnd2();
LIns* iffalse = ins->oprnd3();
NanoAssert(condval->isCmp()); 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())); NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad()));
const Register rr = prepResultReg(ins, GpRegs); const Register rr = prepResultReg(ins, GpRegs);

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

@ -1059,10 +1059,14 @@ namespace nanojit
{ {
LOpcode op = ins->opcode(); LOpcode op = ins->opcode();
LIns* condval = ins->oprnd1(); LIns* condval = ins->oprnd1();
LIns* iftrue = ins->oprnd2();
LIns* iffalse = ins->oprnd3();
NanoAssert(condval->isCmp()); 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())); NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad()));
const Register rr = prepResultReg(ins, GpRegs); const Register rr = prepResultReg(ins, GpRegs);

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

@ -11792,6 +11792,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run()
// this is hard-coded to handle only menu popup frames // this is hard-coded to handle only menu popup frames
nsIFrame* frame = mPresShell->GetPrimaryFrameFor(mContent); nsIFrame* frame = mPresShell->GetPrimaryFrameFor(mContent);
if (frame && frame->GetType() == nsGkAtoms::menuPopupFrame) { if (frame && frame->GetType() == nsGkAtoms::menuPopupFrame) {
nsWeakFrame weakFrame(frame);
#ifdef MOZ_XUL #ifdef MOZ_XUL
// it is possible that the frame is different than the one that requested // 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 // the lazy generation, but as long as it's a popup frame that hasn't
@ -11827,7 +11828,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run()
fc->EndUpdate(); fc->EndUpdate();
} }
if (mCallback) if (mCallback && weakFrame.IsAlive())
mCallback(mContent, frame, mArg); mCallback(mContent, frame, mArg);
// call XBL constructors after the frames are created // call XBL constructors after the frames are created

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

@ -46,7 +46,6 @@
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIImage.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsPoint.h" #include "nsPoint.h"
#include "nsRect.h" #include "nsRect.h"
@ -63,7 +62,6 @@
#include "nsIScrollableFrame.h" #include "nsIScrollableFrame.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsCSSRendering.h" #include "nsCSSRendering.h"
#include "nsCSSColorUtils.h" #include "nsCSSColorUtils.h"
#include "nsITheme.h" #include "nsITheme.h"
@ -321,7 +319,7 @@ static void DrawBorderImage(nsPresContext* aPresContext,
static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext, static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
nsIFrame* aForFrame, nsIFrame* aForFrame,
nsIImage* aImage, imgIContainer* aImage,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsRect& aFill, const nsRect& aFill,
const nsIntRect& aSrc, const nsIntRect& aSrc,
@ -1687,27 +1685,9 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
drawBackgroundColor) { drawBackgroundColor) {
nsCOMPtr<imgIContainer> image; nsCOMPtr<imgIContainer> image;
bottomImage->GetImage(getter_AddRefs(image)); bottomImage->GetImage(getter_AddRefs(image));
// If the image is completely opaque, we may not need to paint PRBool isOpaque;
// the background color. if (NS_SUCCEEDED(image->GetCurrentFrameIsOpaque(&isOpaque)) && isOpaque)
nsCOMPtr<gfxIImageFrame> gfxImgFrame; drawBackgroundColor = PR_FALSE;
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;
}
}
}
} }
// The background color is rendered over the entire dirty area, // The background color is rendered over the entire dirty area,
@ -1938,18 +1918,6 @@ DrawBorderImage(nsPresContext* aPresContext,
imgContainer->GetWidth(&imageSize.width); imgContainer->GetWidth(&imageSize.width);
imgContainer->GetHeight(&imageSize.height); 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. // Convert percentages and clamp values to the image size.
nsIntMargin split; nsIntMargin split;
NS_FOR_CSS_SIDES(s) { NS_FOR_CSS_SIDES(s) {
@ -1983,7 +1951,7 @@ DrawBorderImage(nsPresContext* aPresContext,
// These helper tables recharacterize the 'split' and 'border' margins // These helper tables recharacterize the 'split' and 'border' margins
// in a more convenient form: they are the x/y/width/height coords // 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 // 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 { enum {
LEFT, MIDDLE, RIGHT, LEFT, MIDDLE, RIGHT,
TOP = LEFT, BOTTOM = RIGHT TOP = LEFT, BOTTOM = RIGHT
@ -2010,14 +1978,14 @@ DrawBorderImage(nsPresContext* aPresContext,
}; };
const PRInt32 splitX[3] = { const PRInt32 splitX[3] = {
-innerRect.x + 0, 0,
-innerRect.x + split.left, split.left,
-innerRect.x + imageSize.width - split.right, imageSize.width - split.right,
}; };
const PRInt32 splitY[3] = { const PRInt32 splitY[3] = {
-innerRect.y + 0, 0,
-innerRect.y + split.top, split.top,
-innerRect.y + imageSize.height - split.bottom, imageSize.height - split.bottom,
}; };
const PRInt32 splitWidth[3] = { const PRInt32 splitWidth[3] = {
split.left, split.left,
@ -2108,7 +2076,7 @@ DrawBorderImage(nsPresContext* aPresContext,
} }
DrawBorderImageComponent(aRenderingContext, aForFrame, DrawBorderImageComponent(aRenderingContext, aForFrame,
img, aDirtyRect, imgContainer, aDirtyRect,
destArea, subArea, destArea, subArea,
fillStyleH, fillStyleV, unitSize); fillStyleH, fillStyleV, unitSize);
} }
@ -2118,7 +2086,7 @@ DrawBorderImage(nsPresContext* aPresContext,
static void static void
DrawBorderImageComponent(nsIRenderingContext& aRenderingContext, DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
nsIFrame* aForFrame, nsIFrame* aForFrame,
nsIImage* aImage, imgIContainer* aImage,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsRect& aFill, const nsRect& aFill,
const nsIntRect& aSrc, const nsIntRect& aSrc,
@ -2129,8 +2097,8 @@ DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
if (aFill.IsEmpty() || aSrc.IsEmpty()) if (aFill.IsEmpty() || aSrc.IsEmpty())
return; return;
nsCOMPtr<nsIImage> subImage; nsCOMPtr<imgIContainer> subImage;
if (NS_FAILED(aImage->Extract(aSrc, getter_AddRefs(subImage)))) if (NS_FAILED(aImage->ExtractCurrentFrame(aSrc, getter_AddRefs(subImage))))
return; return;
gfxPattern::GraphicsFilter graphicsFilter = gfxPattern::GraphicsFilter graphicsFilter =

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

@ -39,7 +39,6 @@
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIImage.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsPoint.h" #include "nsPoint.h"
#include "nsRect.h" #include "nsRect.h"
@ -56,7 +55,6 @@
#include "nsIScrollableFrame.h" #include "nsIScrollableFrame.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsCSSRendering.h" #include "nsCSSRendering.h"
#include "nsCSSColorUtils.h" #include "nsCSSColorUtils.h"
#include "nsITheme.h" #include "nsITheme.h"

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

@ -58,9 +58,7 @@
#endif #endif
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
PRBool aIsForEvents, PRBool aBuildCaret) PRBool aIsForEvents, PRBool aBuildCaret)
@ -555,18 +553,12 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
nsCOMPtr<imgIContainer> container; nsCOMPtr<imgIContainer> container;
bottomLayer.mImage->GetImage(getter_AddRefs(container)); bottomLayer.mImage->GetImage(getter_AddRefs(container));
if (container) { if (container) {
PRUint32 nframes; PRBool animated;
container->GetNumFrames(&nframes); container->GetAnimated(&animated);
if (nframes == 1) { if (!animated) {
nsCOMPtr<gfxIImageFrame> imgFrame; PRBool isOpaque;
container->GetCurrentFrame(getter_AddRefs(imgFrame)); if (NS_SUCCEEDED(container->GetCurrentFrameIsOpaque(&isOpaque)))
if (imgFrame) { return isOpaque;
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
PRBool hasMask = img->GetHasAlphaMask();
return !hasMask;
}
} }
} }
} }

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

@ -154,7 +154,7 @@ NS_IMETHODIMP nsImageLoader::OnStartContainer(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest, NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
gfxIImageFrame *aFrame) PRUint32 aFrame)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -182,7 +182,6 @@ NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsImageLoader::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsImageLoader::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
if (!mFrame) if (!mFrame)

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

@ -70,7 +70,7 @@ public:
// imgIDecoderObserver (override nsStubImageDecoderObserver) // imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); 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 // Do not override OnDataAvailable since background images are not
// displayed incrementally; they are displayed after the entire image // displayed incrementally; they are displayed after the entire image
// has been loaded. // has been loaded.
@ -78,8 +78,7 @@ public:
// incrementally in nsImageFrame.cpp. // incrementally in nsImageFrame.cpp.
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
nsIntRect *dirtyRect);
void Destroy(); void Destroy();

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

@ -61,12 +61,10 @@
#include "nsFrameManager.h" #include "nsFrameManager.h"
#include "nsBlockFrame.h" #include "nsBlockFrame.h"
#include "nsBidiPresUtils.h" #include "nsBidiPresUtils.h"
#include "gfxIImageFrame.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxRect.h" #include "gfxRect.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxFont.h" #include "gfxFont.h"
#include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsCSSRendering.h" #include "nsCSSRendering.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
@ -2732,14 +2730,13 @@ MapToFloatUserPixels(const gfxSize& aSize,
static nsresult static nsresult
DrawImageInternal(nsIRenderingContext* aRenderingContext, DrawImageInternal(nsIRenderingContext* aRenderingContext,
nsIImage* aImage, imgIContainer* aImage,
gfxPattern::GraphicsFilter aGraphicsFilter, gfxPattern::GraphicsFilter aGraphicsFilter,
const nsRect& aDest, const nsRect& aDest,
const nsRect& aFill, const nsRect& aFill,
const nsPoint& aAnchor, const nsPoint& aAnchor,
const nsRect& aDirty, const nsRect& aDirty,
const nsIntSize& aImageSize, const nsIntSize& aImageSize)
const nsIntRect& aInnerRect)
{ {
if (aDest.IsEmpty() || aFill.IsEmpty()) if (aDest.IsEmpty() || aFill.IsEmpty())
return NS_OK; return NS_OK;
@ -2839,22 +2836,18 @@ DrawImageInternal(nsIRenderingContext* aRenderingContext,
if (finalFillRect.IsEmpty()) if (finalFillRect.IsEmpty())
return NS_OK; return NS_OK;
nsIntMargin padding(aInnerRect.x, aInnerRect.y, aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, intSubimage);
imageSize.width - aInnerRect.XMost(),
imageSize.height - aInnerRect.YMost());
aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, padding, intSubimage);
return NS_OK; return NS_OK;
} }
/* Workhorse for DrawSingleUnscaledImage. */ /* Workhorse for DrawSingleUnscaledImage. */
static nsresult static nsresult
DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext, DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
nsIImage* aImage, imgIContainer* aImage,
const nsPoint& aDest, const nsPoint& aDest,
const nsRect& aDirty, const nsRect& aDirty,
const nsRect* aSourceArea, const nsRect* aSourceArea,
const nsIntSize& aImageSize, const nsIntSize& aImageSize)
const nsIntRect& aInnerRect)
{ {
if (aImageSize.width == 0 || aImageSize.height == 0) if (aImageSize.width == 0 || aImageSize.height == 0)
return NS_OK; return NS_OK;
@ -2877,19 +2870,18 @@ DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
// translation but we don't want to actually tile the image. // translation but we don't want to actually tile the image.
fill.IntersectRect(fill, dest); fill.IntersectRect(fill, dest);
return DrawImageInternal(aRenderingContext, aImage, gfxPattern::FILTER_NEAREST, return DrawImageInternal(aRenderingContext, aImage, gfxPattern::FILTER_NEAREST,
dest, fill, aDest, aDirty, aImageSize, aInnerRect); dest, fill, aDest, aDirty, aImageSize);
} }
/* Workhorse for DrawSingleImage. */ /* Workhorse for DrawSingleImage. */
static nsresult static nsresult
DrawSingleImageInternal(nsIRenderingContext* aRenderingContext, DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
nsIImage* aImage, imgIContainer* aImage,
gfxPattern::GraphicsFilter aGraphicsFilter, gfxPattern::GraphicsFilter aGraphicsFilter,
const nsRect& aDest, const nsRect& aDest,
const nsRect& aDirty, const nsRect& aDirty,
const nsRect* aSourceArea, const nsRect* aSourceArea,
const nsIntSize& aImageSize, const nsIntSize& aImageSize)
const nsIntRect& aInnerRect)
{ {
if (aImageSize.width == 0 || aImageSize.height == 0) if (aImageSize.width == 0 || aImageSize.height == 0)
return NS_OK; return NS_OK;
@ -2911,7 +2903,7 @@ DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
nsRect fill; nsRect fill;
fill.IntersectRect(aDest, dest); fill.IntersectRect(aDest, dest);
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter, dest, fill, 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 /* The exposed Draw*Image functions just do interface conversion and call the
@ -2926,38 +2918,13 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
const nsPoint& aAnchor, const nsPoint& aAnchor,
const nsRect& aDirty) 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; nsIntSize imageSize;
aImage->GetWidth(&imageSize.width); aImage->GetWidth(&imageSize.width);
aImage->GetHeight(&imageSize.height); 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, return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter,
aDest, aFill, aAnchor, aDirty, aDest, aFill, aAnchor, aDirty,
imageSize, nsIntRect(nsIntPoint(0,0), imageSize)); imageSize);
} }
/* static */ nsresult /* static */ nsresult
@ -2967,23 +2934,13 @@ nsLayoutUtils::DrawSingleUnscaledImage(nsIRenderingContext* aRenderingContext,
const nsRect& aDirty, const nsRect& aDirty,
const nsRect* aSourceArea) 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; nsIntSize imageSize;
aImage->GetWidth(&imageSize.width); aImage->GetWidth(&imageSize.width);
aImage->GetHeight(&imageSize.height); aImage->GetHeight(&imageSize.height);
return DrawSingleUnscaledImageInternal(aRenderingContext, img, return DrawSingleUnscaledImageInternal(aRenderingContext, aImage,
aDest, aDirty, aSourceArea, aDest, aDirty, aSourceArea,
imageSize, innerRect); imageSize);
} }
/* static */ nsresult /* static */ nsresult
@ -2994,41 +2951,15 @@ nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
const nsRect& aDirty, const nsRect& aDirty,
const nsRect* aSourceArea) 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; nsIntSize imageSize;
aImage->GetWidth(&imageSize.width); aImage->GetWidth(&imageSize.width);
aImage->GetHeight(&imageSize.height); 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, return DrawSingleImageInternal(aRenderingContext, aImage, aGraphicsFilter,
aDest, aDirty, aSourceArea, aDest, aDirty, aSourceArea,
imageSize, imageSize);
nsIntRect(nsIntPoint(0, 0), imageSize));
} }
/* static */ nsRect /* static */ nsRect
nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize, nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
const nsRect& aImageSourceArea, const nsRect& aImageSourceArea,
@ -3386,7 +3317,6 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
#endif #endif
// Finally, check if it's a normal image // Finally, check if it's a normal image
nsCOMPtr<imgIContainer> imgContainer;
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aElement); nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aElement);
if (!imageLoader) if (!imageLoader)
@ -3425,34 +3355,28 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
return result; return result;
} }
nsCOMPtr<imgIContainer> imgContainer;
rv = imgRequest->GetImage(getter_AddRefs(imgContainer)); rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
if (NS_FAILED(rv) || !imgContainer) if (NS_FAILED(rv) || !imgContainer)
return result; return result;
nsCOMPtr<gfxIImageFrame> frame; nsRefPtr<gfxASurface> framesurf;
rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame)); rv = imgContainer->GetCurrentFrame(getter_AddRefs(framesurf));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return result; return result;
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
if (!img)
return result;
PRInt32 imgWidth, imgHeight; PRInt32 imgWidth, imgHeight;
rv = frame->GetWidth(&imgWidth); rv = imgContainer->GetWidth(&imgWidth);
rv |= frame->GetHeight(&imgHeight); rv |= imgContainer->GetHeight(&imgHeight);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return result; return result;
nsRefPtr<gfxPattern> gfxpattern; if (wantImageSurface && framesurf->GetType() != gfxASurface::SurfaceTypeImage) {
img->GetPattern(getter_AddRefs(gfxpattern));
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
if (wantImageSurface && gfxsurf->GetType() != gfxASurface::SurfaceTypeImage) {
forceCopy = PR_TRUE; forceCopy = PR_TRUE;
} }
if (forceCopy || !gfxsurf) { nsRefPtr<gfxASurface> gfxsurf = framesurf;
if (forceCopy) {
if (wantImageSurface) { if (wantImageSurface) {
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32); gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
} else { } else {
@ -3463,7 +3387,7 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf); nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetPattern(gfxpattern); ctx->SetSource(framesurf);
ctx->Paint(); ctx->Paint();
} }

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

@ -862,14 +862,6 @@ public:
const nsPoint& aAnchor, const nsPoint& aAnchor,
const nsRect& aDirty); 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. * Draw a whole image without scaling or tiling.
* *
@ -911,13 +903,6 @@ public:
const nsRect& aDirty, const nsRect& aDirty,
const nsRect* aSourceArea = nsnull); 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 * 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 * that we want to map that source area too, computes the area that

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

@ -84,7 +84,6 @@ class nsIContent;
class nsIFontMetrics; class nsIFontMetrics;
class nsIFrame; class nsIFrame;
class nsFrameManager; class nsFrameManager;
class nsIImage;
class nsILinkHandler; class nsILinkHandler;
class nsStyleContext; class nsStyleContext;
class nsIAtom; class nsIAtom;

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

@ -52,7 +52,6 @@
#include "nsISupports.h" #include "nsISupports.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsCSSAnonBoxes.h" #include "nsCSSAnonBoxes.h"
#include "nsIImage.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsIComponentManager.h" #include "nsIComponentManager.h"
#include "nsIDocument.h" #include "nsIDocument.h"

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

@ -49,7 +49,6 @@
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsIDeviceContext.h" #include "nsIDeviceContext.h"
#include "nsIFontMetrics.h" #include "nsIFontMetrics.h"
#include "nsIImage.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsFormControlFrame.h" #include "nsFormControlFrame.h"
#include "nsGUIEvent.h" #include "nsGUIEvent.h"

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

@ -71,13 +71,12 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// imgIDecoderObserver (override nsStubImageDecoderObserver) // imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame, NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
const nsIntRect *aRect); const nsIntRect *aRect);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
nsIntRect *dirtyRect);
void SetFrame(nsBulletFrame *frame) { mFrame = frame; } void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
@ -1458,7 +1457,7 @@ NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest, NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect) const nsIntRect *aRect)
{ {
// The image has changed. // The image has changed.
@ -1489,7 +1488,6 @@ NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *aNewFrame,
nsIntRect *aDirtyRect) nsIntRect *aDirtyRect)
{ {
// Invalidate the entire content area. Maybe it's not optimal but it's simple and // 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, NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect) const nsIntRect *aRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return mFrame->OnDataAvailable(aRequest, aFrame, aRect); return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
} }
NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest, NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
@ -1567,11 +1565,10 @@ NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return mFrame->FrameChanged(aContainer, newframe, dirtyRect); return mFrame->FrameChanged(aContainer, dirtyRect);
} }

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

@ -45,7 +45,6 @@
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
class gfxIImageFrame;
/** /**
* A simple class that manages the layout and rendering of html bullets. * 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 OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect); const nsIntRect *aRect);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
nsresult aStatus, nsresult aStatus,
const PRUnichar *aStatusArg); const PRUnichar *aStatusArg);
NS_IMETHOD FrameChanged(imgIContainer *aContainer, NS_IMETHOD FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *aNewframe,
nsIntRect *aDirtyRect); nsIntRect *aDirtyRect);
/* get list item text, without '.' */ /* get list item text, without '.' */

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

@ -109,7 +109,6 @@
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "gfxIImageFrame.h"
#include "nsILookAndFeel.h" #include "nsILookAndFeel.h"
#include "nsLayoutCID.h" #include "nsLayoutCID.h"
#include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID #include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID

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

@ -47,7 +47,6 @@
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIImage.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsINodeInfo.h" #include "nsINodeInfo.h"
@ -93,7 +92,6 @@
#include "nsCSSFrameConstructor.h" #include "nsCSSFrameConstructor.h"
#include "nsIPrefBranch2.h" #include "nsIPrefBranch2.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "gfxIImageFrame.h"
#include "nsIDOMRange.h" #include "nsIDOMRange.h"
#include "nsIContentPolicy.h" #include "nsIContentPolicy.h"
@ -523,7 +521,7 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
nsresult nsresult
nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect) const nsIntRect *aRect)
{ {
// XXX do we need to make sure that the reflow from the // 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 // Don't invalidate if the current visible frame isn't the one the data is
// from // from
nsCOMPtr<imgIContainer> container; if (!aCurrentFrame)
aRequest->GetImage(getter_AddRefs(container)); return NS_OK;
if (container) {
nsCOMPtr<gfxIImageFrame> currentFrame;
container->GetCurrentFrame(getter_AddRefs(currentFrame));
if (aFrame != currentFrame) {
// just bail
return NS_OK;
}
}
#ifdef DEBUG_decode #ifdef DEBUG_decode
printf("Source rect (%d,%d,%d,%d) -> invalidate dest rect (%d,%d,%d,%d)\n", printf("Source rect (%d,%d,%d,%d) -> invalidate dest rect (%d,%d,%d,%d)\n",
@ -634,9 +624,7 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
} }
nsresult nsresult
nsImageFrame::FrameChanged(imgIContainer *aContainer, nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect)
gfxIImageFrame *aNewFrame,
nsIntRect *aDirtyRect)
{ {
if (!GetStyleVisibility()->IsVisible()) { if (!GetStyleVisibility()->IsVisible()) {
return NS_OK; return NS_OK;
@ -1833,13 +1821,13 @@ NS_IMETHODIMP nsImageListener::OnStartContainer(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest, NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect) const nsIntRect *aRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return mFrame->OnDataAvailable(aRequest, aFrame, aRect); return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
} }
NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest, NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
@ -1853,13 +1841,12 @@ NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsImageListener::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsImageListener::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe,
nsIntRect * dirtyRect) nsIntRect * dirtyRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return mFrame->FrameChanged(aContainer, newframe, dirtyRect); return mFrame->FrameChanged(aContainer, dirtyRect);
} }
static PRBool static PRBool

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

@ -73,13 +73,12 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// imgIDecoderObserver (override nsStubImageDecoderObserver) // imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame, NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
const nsIntRect *aRect); const nsIntRect *aRect);
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
nsIntRect * dirtyRect);
void SetFrame(nsImageFrame *frame) { mFrame = frame; } void SetFrame(nsImageFrame *frame) { mFrame = frame; }
@ -218,15 +217,12 @@ protected:
protected: protected:
friend class nsImageListener; friend class nsImageListener;
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
nsresult OnDataAvailable(imgIRequest *aRequest, nsresult OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
gfxIImageFrame *aFrame,
const nsIntRect *rect); const nsIntRect *rect);
nsresult OnStopDecode(imgIRequest *aRequest, nsresult OnStopDecode(imgIRequest *aRequest,
nsresult aStatus, nsresult aStatus,
const PRUnichar *aStatusArg); const PRUnichar *aStatusArg);
nsresult FrameChanged(imgIContainer *aContainer, nsresult FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect);
gfxIImageFrame *aNewframe,
nsIntRect *aDirtyRect);
private: private:
// random helpers // random helpers

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

@ -1159,8 +1159,100 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
window.clipRect.bottom = 0; window.clipRect.top = 0; window.clipRect.bottom = 0; window.clipRect.top = 0;
window.clipRect.left = 0; window.clipRect.right = 0; window.clipRect.left = 0; window.clipRect.right = 0;
// XXX platform specific printing code // platform specific printing code
#if defined(XP_UNIX) && !defined(XP_MACOSX) #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 -- /* 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. * 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="100%" height="100%" fill="lime"/>
<rect width="183" height="183" fill="red"/> <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> </svg>

До

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

После

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

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

@ -37,7 +37,6 @@
#include "nsSVGPathGeometryFrame.h" #include "nsSVGPathGeometryFrame.h"
#include "nsIDOMSVGMatrix.h" #include "nsIDOMSVGMatrix.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsStubImageDecoderObserver.h" #include "nsStubImageDecoderObserver.h"
#include "nsImageLoadingContent.h" #include "nsImageLoadingContent.h"
#include "nsIDOMSVGImageElement.h" #include "nsIDOMSVGImageElement.h"
@ -47,7 +46,6 @@
#include "nsSVGMatrix.h" #include "nsSVGMatrix.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
class nsSVGImageFrame; class nsSVGImageFrame;
@ -61,8 +59,7 @@ public:
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status, NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
nsRect * dirtyRect);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
imgIContainer *aContainer); imgIContainer *aContainer);
@ -243,16 +240,15 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
currentRequest->GetImage(getter_AddRefs(mImageContainer)); currentRequest->GetImage(getter_AddRefs(mImageContainer));
} }
nsCOMPtr<gfxIImageFrame> currentFrame; nsRefPtr<gfxASurface> currentFrame;
if (mImageContainer) if (mImageContainer)
mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame)); mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
nsRefPtr<gfxPattern> thebesPattern = nsnull; // We need to wrap the surface in a pattern to have somewhere to set the
if (currentFrame) { // graphics filter.
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame)); nsRefPtr<gfxPattern> thebesPattern;
if (currentFrame)
img->GetPattern(getter_AddRefs(thebesPattern)); thebesPattern = new gfxPattern(currentFrame);
}
if (thebesPattern) { if (thebesPattern) {
@ -279,8 +275,8 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
} }
PRInt32 nativeWidth, nativeHeight; PRInt32 nativeWidth, nativeHeight;
currentFrame->GetWidth(&nativeWidth); mImageContainer->GetWidth(&nativeWidth);
currentFrame->GetHeight(&nativeHeight); mImageContainer->GetHeight(&nativeHeight);
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, nativeWidth, nativeHeight, opacity); nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, nativeWidth, nativeHeight, opacity);
@ -384,8 +380,7 @@ NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe, nsIntRect * dirtyRect)
nsRect * dirtyRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

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

@ -58,7 +58,6 @@
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIImage.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIHTMLDocument.h" #include "nsIHTMLDocument.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
@ -543,7 +542,6 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
} }
NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container, NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
nsBoxLayoutState state(PresContext()); nsBoxLayoutState state(PresContext());
@ -591,12 +589,11 @@ NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
} }
NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container, NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; 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, NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *container, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
nsIntRect *dirtyRect);
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; } void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
@ -121,9 +120,7 @@ public:
NS_IMETHOD OnStopDecode(imgIRequest *request, NS_IMETHOD OnStopDecode(imgIRequest *request,
nsresult status, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
NS_IMETHOD FrameChanged(imgIContainer *container, NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
gfxIImageFrame *newframe,
nsIntRect *dirtyRect);
virtual ~nsImageBoxFrame(); virtual ~nsImageBoxFrame();

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

@ -238,6 +238,7 @@ nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis)
{ {
nsAutoString accesskey; nsAutoString accesskey;
nsCOMPtr<nsIDOMXULLabelElement> labelElement = do_QueryInterface(mContent); nsCOMPtr<nsIDOMXULLabelElement> labelElement = do_QueryInterface(mContent);
NS_ENSURE_TRUE(aWeakThis.IsAlive(), PR_FALSE);
if (labelElement) { if (labelElement) {
// Accesskey may be stored on control. // Accesskey may be stored on control.
// Because this method is called by the reflow callback, current context // 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; imgIRequest *imgReq = entry.request;
imgReq->GetImageStatus(&status); imgReq->GetImageStatus(&status);
imgReq->GetImage(aResult); // We hand back the image here. The GetImage call addrefs *aResult. imgReq->GetImage(aResult); // We hand back the image here. The GetImage call addrefs *aResult.
PRUint32 numFrames = 1; PRBool animated = PR_FALSE;
if (*aResult) 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. // We either aren't done loading, or we're animating. Add our row as a listener for invalidations.
nsCOMPtr<imgIDecoderObserver> obs; nsCOMPtr<imgIDecoderObserver> obs;
imgReq->GetDecoderObserver(getter_AddRefs(obs)); imgReq->GetDecoderObserver(getter_AddRefs(obs));

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

@ -64,7 +64,7 @@ NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest, NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
gfxIImageFrame *aFrame, PRBool aCurrentFrame,
const nsIntRect *aRect) const nsIntRect *aRect)
{ {
Invalidate(); Invalidate();
@ -72,7 +72,6 @@ NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
} }
NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIContainer *aContainer, NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIContainer *aContainer,
gfxIImageFrame *newframe,
nsIntRect *dirtyRect) nsIntRect *dirtyRect)
{ {
Invalidate(); Invalidate();

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

@ -72,11 +72,10 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// imgIDecoderObserver (override nsStubImageDecoderObserver) // imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage); NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame, NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
const nsIntRect *aRect); const nsIntRect *aRect);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe, NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
nsIntRect *dirtyRect);
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol); NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol);

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

@ -47,6 +47,7 @@
#define IMG_BUILD_xbm 1 #define IMG_BUILD_xbm 1
#endif #endif
#include "nsIDeviceContext.h"
#include "nsIGenericFactory.h" #include "nsIGenericFactory.h"
#include "nsIModule.h" #include "nsIModule.h"
#include "nsICategoryManager.h" #include "nsICategoryManager.h"
@ -206,7 +207,7 @@ static const nsModuleComponentInfo components[] =
imgLoaderConstructor, }, imgLoaderConstructor, },
{ "image container", { "image container",
NS_IMGCONTAINER_CID, NS_IMGCONTAINER_CID,
"@mozilla.org/image/container;1", "@mozilla.org/image/container;2",
imgContainerConstructor, }, imgContainerConstructor, },
{ "image loader", { "image loader",
NS_IMGLOADER_CID, NS_IMGLOADER_CID,
@ -313,6 +314,12 @@ static const nsModuleComponentInfo components[] =
static nsresult static nsresult
imglib_Initialize(nsIModule* aSelf) 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(); imgLoader::InitCache();
return NS_OK; return NS_OK;
} }

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

@ -51,7 +51,6 @@
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "imgILoad.h" #include "imgILoad.h"
#include "nsIImage.h"
#include "prlog.h" #include "prlog.h"
@ -89,11 +88,7 @@ NS_IMETHODIMP nsBMPDecoder::Init(imgILoad *aLoad)
mObserver = do_QueryInterface(aLoad); mObserver = do_QueryInterface(aLoad);
nsresult rv; nsresult rv;
mImage = do_CreateInstance("@mozilla.org/image/container;1", &rv); mImage = do_CreateInstance("@mozilla.org/image/container;2", &rv);
if (NS_FAILED(rv))
return rv;
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2", &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
@ -106,13 +101,12 @@ NS_IMETHODIMP nsBMPDecoder::Close()
mImage->DecodingComplete(); mImage->DecodingComplete();
if (mObserver) { if (mObserver) {
mObserver->OnStopFrame(nsnull, mFrame); mObserver->OnStopFrame(nsnull, 0);
mObserver->OnStopContainer(nsnull, mImage); mObserver->OnStopContainer(nsnull, mImage);
mObserver->OnStopDecode(nsnull, NS_OK, nsnull); mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
mObserver = nsnull; mObserver = nsnull;
} }
mImage = nsnull; mImage = nsnull;
mFrame = nsnull;
return NS_OK; return NS_OK;
} }
@ -266,8 +260,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
mOldLine = mCurLine = real_height; mOldLine = mCurLine = real_height;
PRUint32 imageLength;
if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) { 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 { } else {
// mRow is not used for RLE encoded images // mRow is not used for RLE encoded images
mRow = (PRUint8*)malloc((mBIH.width * mBIH.bpp)/8 + 4); mRow = (PRUint8*)malloc((mBIH.width * mBIH.bpp)/8 + 4);
@ -277,12 +273,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
if (!mRow) { if (!mRow) {
return NS_ERROR_OUT_OF_MEMORY; 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); NS_ENSURE_SUCCESS(rv, rv);
PRUint32 imageLength;
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength);
if (!mImageData) if (!mImageData)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -297,9 +291,7 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
memset(mImageData, 0, imageLength); memset(mImageData, 0, imageLength);
} }
rv = mImage->AppendFrame(mFrame); mObserver->OnStartFrame(nsnull, 0);
NS_ENSURE_SUCCESS(rv, rv);
mObserver->OnStartFrame(nsnull, mFrame);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
PRUint8 bpc; // bytes per color 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, nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
mBIH.width, rows); mBIH.width, rows);
// Tell the image that it's data has been updated // Tell the image that its data has been updated
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame, &rv)); rv = mImage->FrameUpdated(0, r);
NS_ENSURE_SUCCESS(rv, rv); 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; mOldLine = mCurLine;
} }

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

@ -43,7 +43,6 @@
#include "imgIDecoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "gfxColor.h" #include "gfxColor.h"
#define NS_BMPDECODER_CID \ #define NS_BMPDECODER_CID \
@ -118,9 +117,6 @@ struct bitFields {
#endif #endif
#define USE_RGB #define USE_RGB
#define BMP_GFXFORMAT gfxIFormats::RGB
#define RLE_GFXFORMAT_ALPHA gfxIFormats::RGB_A1
#define GFXBYTESPERPIXEL 4
// BMPINFOHEADER.compression defines // BMPINFOHEADER.compression defines
#define BI_RLE8 1 #define BI_RLE8 1
@ -173,7 +169,6 @@ private:
nsCOMPtr<imgIDecoderObserver> mObserver; nsCOMPtr<imgIDecoderObserver> mObserver;
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
PRUint32 mPos; PRUint32 mPos;

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

@ -51,7 +51,6 @@
#include "imgILoad.h" #include "imgILoad.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
#include "nsIProperties.h" #include "nsIProperties.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
@ -93,39 +92,30 @@ NS_IMETHODIMP nsICODecoder::Init(imgILoad *aLoad)
{ {
mObserver = do_QueryInterface(aLoad); mObserver = do_QueryInterface(aLoad);
mImage = do_CreateInstance("@mozilla.org/image/container;1"); mImage = do_CreateInstance("@mozilla.org/image/container;2");
if (!mImage) if (!mImage)
return NS_ERROR_OUT_OF_MEMORY; 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); return aLoad->SetImage(mImage);
} }
NS_IMETHODIMP nsICODecoder::Close() NS_IMETHODIMP nsICODecoder::Close()
{ {
// Tell the image that it's data has been updated // 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); nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight);
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame)); nsresult rv = mImage->FrameUpdated(0, r);
nsresult rv = NS_OK;
if (img)
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
mImage->DecodingComplete(); mImage->DecodingComplete();
if (mObserver) { if (mObserver) {
mObserver->OnDataAvailable(nsnull, mFrame, &r); mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
mObserver->OnStopFrame(nsnull, mFrame); mObserver->OnStopFrame(nsnull, 0);
mObserver->OnStopContainer(nsnull, mImage); mObserver->OnStopContainer(nsnull, 0);
mObserver->OnStopDecode(nsnull, NS_OK, nsnull); mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
mObserver = nsnull; mObserver = nsnull;
} }
mImage = nsnull; mImage = nsnull;
mFrame = nsnull;
mPos = 0; mPos = 0;
@ -304,15 +294,13 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
if (!mRow) if (!mRow)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA8, 24); PRUint32 imageLength;
NS_ENSURE_SUCCESS(rv, rv); rv = mImage->AppendFrame(0, 0, mDirEntry.mWidth, mDirEntry.mHeight,
rv = mImage->AppendFrame(mFrame); gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength);
NS_ENSURE_SUCCESS(rv, rv);
mObserver->OnStartFrame(nsnull, mFrame);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
PRUint32 imageLength; mObserver->OnStartFrame(nsnull, 0);
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength); NS_ENSURE_SUCCESS(rv, rv);
} }
if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) && if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) &&

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

@ -44,20 +44,12 @@
#include "imgIDecoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "nsBMPDecoder.h" #include "nsBMPDecoder.h"
// {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1} // {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1}
#define NS_ICODECODER_CID \ #define NS_ICODECODER_CID \
{ 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } } { 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 struct IconDirEntry
{ {
PRUint8 mWidth; PRUint8 mWidth;
@ -103,7 +95,6 @@ private:
private: private:
nsCOMPtr<imgIDecoderObserver> mObserver; nsCOMPtr<imgIDecoderObserver> mObserver;
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
PRUint32 mPos; PRUint32 mPos;
PRUint16 mNumIcons; PRUint16 mNumIcons;

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

@ -74,7 +74,6 @@ mailing address.
#include <stddef.h> #include <stddef.h>
#include "prmem.h" #include "prmem.h"
#include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsGIFDecoder2.h" #include "nsGIFDecoder2.h"
@ -142,7 +141,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
{ {
mObserver = do_QueryInterface(aLoad); mObserver = do_QueryInterface(aLoad);
mImageContainer = do_CreateInstance("@mozilla.org/image/container;1"); mImageContainer = do_CreateInstance("@mozilla.org/image/container;2");
aLoad->SetImage(mImageContainer); aLoad->SetImage(mImageContainer);
// Start with the version (GIF89a|GIF87a) // Start with the version (GIF89a|GIF87a)
@ -161,8 +160,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
/* void close (); */ /* void close (); */
NS_IMETHODIMP nsGIFDecoder2::Close() NS_IMETHODIMP nsGIFDecoder2::Close()
{ {
if (mImageFrame) EndImageFrame();
EndImageFrame();
EndGIF(); EndGIF();
PR_FREEIF(mGIFStruct.local_colormap); PR_FREEIF(mGIFStruct.local_colormap);
@ -205,8 +203,7 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
nsIntRect r(0, fromRow, mGIFStruct.width, rows); nsIntRect r(0, fromRow, mGIFStruct.width, rows);
// Update image // Update image
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame)); nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r);
nsresult rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
@ -214,8 +211,10 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
// Offset to the frame position // Offset to the frame position
// Only notify observer(s) for first frame // Only notify observer(s) for first frame
if (!mGIFStruct.images_decoded && mObserver) { if (!mGIFStruct.images_decoded && mObserver) {
PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
r.y += mGIFStruct.y_offset; r.y += mGIFStruct.y_offset;
mObserver->OnDataAvailable(nsnull, mImageFrame, &r); mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
} }
return NS_OK; return NS_OK;
} }
@ -251,7 +250,7 @@ nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint3
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Flushing is only needed for first frame // Flushing is only needed for first frame
if (!mGIFStruct.images_decoded && mImageFrame) { if (!mGIFStruct.images_decoded) {
rv = FlushImageData(); rv = FlushImageData();
mLastFlushedRow = mCurrentRow; mLastFlushedRow = mCurrentRow;
mLastFlushedPass = mCurrentPass; mLastFlushedPass = mCurrentPass;
@ -324,8 +323,6 @@ void nsGIFDecoder2::EndGIF()
//****************************************************************************** //******************************************************************************
void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth) void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
{ {
mImageFrame = nsnull; // clear out our current frame reference
if (!mGIFStruct.images_decoded) { if (!mGIFStruct.images_decoded) {
// Send a onetime OnDataAvailable (Display Refresh) for the first frame // Send a onetime OnDataAvailable (Display Refresh) for the first frame
// if it has a y-axis offset. Otherwise, the area may never be refreshed // 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) { if (mGIFStruct.y_offset > 0) {
PRInt32 imgWidth; PRInt32 imgWidth;
mImageContainer->GetWidth(&imgWidth); mImageContainer->GetWidth(&imgWidth);
PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset); 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 // Use correct format, RGB for first frame, PAL for following frames
// and include transparency to allow for optimization of opaque images // and include transparency to allow for optimization of opaque images
gfx_format format;
if (mGIFStruct.images_decoded) { if (mGIFStruct.images_decoded) {
// Image data is stored with original depth and palette // 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 { } else {
// Regardless of depth of input, image is decoded into 24bit RGB // Regardless of depth of input, image is decoded into 24bit RGB
format = mGIFStruct.is_transparent ? gfxIFormats::RGB_A1 : gfxIFormats::RGB; rv = mImageContainer->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
aDepth = 24; mGIFStruct.width, mGIFStruct.height,
format, &mImageData, &imageDataLength);
} }
// initialize the frame and append it to the container if (NS_FAILED(rv))
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;
return; return;
}
mImageFrame->SetFrameDisposalMethod(mGIFStruct.disposal_method); mImageContainer->SetFrameDisposalMethod(mGIFStruct.images_decoded,
if (!mGIFStruct.images_decoded) mGIFStruct.disposal_method);
mImageContainer->AppendFrame(mImageFrame);
if (mObserver) if (mObserver)
mObserver->OnStartFrame(nsnull, mImageFrame); mObserver->OnStartFrame(nsnull, mGIFStruct.images_decoded);
PRUint32 imageDataLength;
mImageFrame->GetImageData(&mImageData, &imageDataLength);
} }
@ -384,20 +386,23 @@ void nsGIFDecoder2::EndImageFrame()
// This will clear the remaining bits of the placeholder. (Bug 37589) // This will clear the remaining bits of the placeholder. (Bug 37589)
const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset; const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset;
if (realFrameHeight < mGIFStruct.screen_height) { if (realFrameHeight < mGIFStruct.screen_height) {
PRUint32 imgCurFrame;
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
nsIntRect r(0, realFrameHeight, nsIntRect r(0, realFrameHeight,
mGIFStruct.screen_width, mGIFStruct.screen_width,
mGIFStruct.screen_height - realFrameHeight); 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 // This transparency check is only valid for first frame
if (mGIFStruct.is_transparent && !mSawTransparency) { if (mGIFStruct.is_transparent && !mSawTransparency) {
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame)); mImageContainer->SetFrameHasNoAlpha(mGIFStruct.images_decoded);
img->SetHasNoAlpha();
} }
} }
mCurrentRow = mLastFlushedRow = -1; mCurrentRow = mLastFlushedRow = -1;
mCurrentPass = mLastFlushedPass = 0; mCurrentPass = mLastFlushedPass = 0;
PRUint32 curframe = mGIFStruct.images_decoded;
// Only add frame if we have any rows at all // Only add frame if we have any rows at all
if (mGIFStruct.rows_remaining != mGIFStruct.height) { if (mGIFStruct.rows_remaining != mGIFStruct.height) {
if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) { 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 // 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 // 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. // image frame decoded before we go off and try to display another frame.
mImageFrame->SetTimeout(mGIFStruct.delay_time); mImageContainer->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
if (mGIFStruct.images_decoded)
mImageContainer->AppendFrame(mImageFrame);
mImageContainer->EndFrameDecode(mGIFStruct.images_decoded); mImageContainer->EndFrameDecode(mGIFStruct.images_decoded);
mGIFStruct.images_decoded++;
mGIFStruct.images_decoded++;
} }
if (mObserver) if (mObserver)
mObserver->OnStopFrame(nsnull, mImageFrame); mObserver->OnStopFrame(nsnull, curframe);
// Release reference to this frame
mImageFrame = nsnull;
// Reset the transparent pixel // Reset the transparent pixel
if (mOldColor) { if (mOldColor) {
@ -497,7 +498,7 @@ PRUint32 nsGIFDecoder2::OutputRow()
if (drow_end > drow_start) { if (drow_end > drow_start) {
// irow is the current row filled // irow is the current row filled
for (int r = drow_start; r <= drow_end; r++) { for (int r = drow_start; r <= drow_end; r++) {
if (r != mGIFStruct.irow) { if (r != int(mGIFStruct.irow)) {
memcpy(mImageData + (r * bpr), rowp, bpr); memcpy(mImageData + (r * bpr), rowp, bpr);
} }
} }
@ -1060,7 +1061,7 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
BeginImageFrame(realDepth); BeginImageFrame(realDepth);
// handle allocation error // handle allocation error
if (!mImageFrame) { if (!mImageData) {
mGIFStruct.state = gif_error; mGIFStruct.state = gif_error;
break; break;
} }
@ -1086,17 +1087,12 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
if (q[8] & 0x80) /* has a local colormap? */ if (q[8] & 0x80) /* has a local colormap? */
{ {
mGIFStruct.local_colormap_size = 1 << depth; mGIFStruct.local_colormap_size = 1 << depth;
PRUint32 paletteSize; if (!mGIFStruct.images_decoded) {
if (mGIFStruct.images_decoded) {
// Copy directly into the palette of current frame,
// by pointing mColormap to that palette.
mImageFrame->GetPaletteData(&mColormap, &paletteSize);
} else {
// First frame has local colormap, allocate space for it // First frame has local colormap, allocate space for it
// as the image frame doesn't have its own palette // as the image frame doesn't have its own palette
paletteSize = sizeof(PRUint32) << realDepth; mColormapSize = sizeof(PRUint32) << realDepth;
if (!mGIFStruct.local_colormap) { if (!mGIFStruct.local_colormap) {
mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(paletteSize); mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(mColormapSize);
if (!mGIFStruct.local_colormap) { if (!mGIFStruct.local_colormap) {
mGIFStruct.state = gif_oom; mGIFStruct.state = gif_oom;
break; break;
@ -1105,9 +1101,9 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
mColormap = mGIFStruct.local_colormap; mColormap = mGIFStruct.local_colormap;
} }
const PRUint32 size = 3 << depth; const PRUint32 size = 3 << depth;
if (paletteSize > size) { if (mColormapSize > size) {
// Clear the notfilled part of the colormap // Clear the notfilled part of the colormap
memset(((PRUint8*)mColormap) + size, 0, paletteSize - size); memset(((PRUint8*)mColormap) + size, 0, mColormapSize - size);
} }
if (len < size) { if (len < size) {
// Use 'hold' pattern to get the image colormap // Use 'hold' pattern to get the image colormap
@ -1122,12 +1118,11 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
break; break;
} else { } else {
/* Switch back to the global palette */ /* Switch back to the global palette */
mColormap = mGIFStruct.global_colormap;
if (mGIFStruct.images_decoded) { if (mGIFStruct.images_decoded) {
// Copy global colormap into the palette of current frame // Copy global colormap into the palette of current frame
PRUint32 size; memcpy(mColormap, mGIFStruct.global_colormap, mColormapSize);
mImageFrame->GetPaletteData(&mColormap, &size); } else {
memcpy(mColormap, mGIFStruct.global_colormap, size); mColormap = mGIFStruct.global_colormap;
} }
} }
GETN(1, gif_lzw_start); GETN(1, gif_lzw_start);

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

@ -44,7 +44,6 @@
#include "imgIDecoder.h" #include "imgIDecoder.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "GIF2.h" #include "GIF2.h"
@ -88,13 +87,13 @@ private:
inline int ClearCode() const { return 1 << mGIFStruct.datasize; } inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
nsCOMPtr<imgIContainer> mImageContainer; nsCOMPtr<imgIContainer> mImageContainer;
nsCOMPtr<gfxIImageFrame> mImageFrame;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
PRInt32 mCurrentRow; PRInt32 mCurrentRow;
PRInt32 mLastFlushedRow; PRInt32 mLastFlushedRow;
PRUint8 *mImageData; // Pointer to image data in either Cairo or 8bit format PRUint8 *mImageData; // Pointer to image data in either Cairo or 8bit format
PRUint32 *mColormap; // Current colormap to be used in Cairo format PRUint32 *mColormap; // Current colormap to be used in Cairo format
PRUint32 mColormapSize;
PRUint32 mOldColor; // The old value of the transparent pixel PRUint32 mOldColor; // The old value of the transparent pixel
PRUint8 mCurrentPass; PRUint8 mCurrentPass;
PRUint8 mLastFlushedPass; PRUint8 mLastFlushedPass;

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

@ -47,7 +47,6 @@
#include "nsRect.h" #include "nsRect.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder) 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. 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; if (!mImage) return NS_ERROR_OUT_OF_MEMORY;
aLoad->SetImage(mImage); aLoad->SetImage(mImage);
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
if (!mFrame) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK; return NS_OK;
} }
@ -88,7 +84,7 @@ NS_IMETHODIMP nsIconDecoder::Close()
if (mObserver) if (mObserver)
{ {
mObserver->OnStopFrame(nsnull, mFrame); mObserver->OnStopFrame(nsnull, 0);
mObserver->OnStopContainer(nsnull, mImage); mObserver->OnStopContainer(nsnull, mImage);
mObserver->OnStopDecode(nsnull, NS_OK, nsnull); mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
} }
@ -120,17 +116,15 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
if (mObserver) if (mObserver)
mObserver->OnStartContainer(nsnull, mImage); 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)) if (NS_FAILED(rv))
return rv; return rv;
mImage->AppendFrame(mFrame);
if (mObserver) if (mObserver)
mObserver->OnStartFrame(nsnull, mFrame); mObserver->OnStartFrame(nsnull, 0);
PRUint32 imageLen;
PRUint8 *imageData;
mFrame->GetImageData(&imageData, &imageLen);
// Ensure that there enough in the inputStream // Ensure that there enough in the inputStream
NS_ENSURE_TRUE(count >= imageLen, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(count >= imageLen, NS_ERROR_UNEXPECTED);
@ -142,12 +136,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
// Notify the image... // Notify the image...
nsIntRect r(0, 0, w, h); nsIntRect r(0, 0, w, h);
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame)); rv = mImage->FrameUpdated(0, r);
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
mObserver->OnDataAvailable(nsnull, mFrame, &r); mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
return NS_OK; return NS_OK;
} }

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

@ -46,7 +46,6 @@
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#define NS_ICONDECODER_CID \ #define NS_ICONDECODER_CID \
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \ { /* FFC08380-256C-11d5-9905-001083010E9B */ \
@ -87,7 +86,6 @@ public:
private: private:
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
}; };

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

@ -48,7 +48,6 @@
#include "nspr.h" #include "nspr.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "ImageLogging.h" #include "ImageLogging.h"
#include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "gfxColor.h" #include "gfxColor.h"
@ -101,6 +100,7 @@ nsJPEGDecoder::nsJPEGDecoder()
mState = JPEG_HEADER; mState = JPEG_HEADER;
mReading = PR_TRUE; mReading = PR_TRUE;
mError = NS_OK; mError = NS_OK;
mImageData = nsnull;
mBytesToSkip = 0; mBytesToSkip = 0;
memset(&mInfo, 0, sizeof(jpeg_decompress_struct)); memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
@ -187,7 +187,7 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad)
mImageLoad->GetImage(getter_AddRefs(mImage)); mImageLoad->GetImage(getter_AddRefs(mImage));
if (!mImage) { if (!mImage) {
mImage = do_CreateInstance("@mozilla.org/image/container;1"); mImage = do_CreateInstance("@mozilla.org/image/container;2");
if (!mImage) if (!mImage)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -473,49 +473,23 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
mObserver->OnStartContainer(nsnull, mImage); mObserver->OnStartContainer(nsnull, mImage);
mImage->GetFrameAt(0, getter_AddRefs(mFrame)); // Use EnsureCleanFrame so we don't create a new frame if we're being
// reused for e.g. multipart/x-replace
if (mFrame) { PRUint32 imagelength;
PRInt32 width, height; if (NS_FAILED(mImage->EnsureCleanFrame(0, 0, 0, mInfo.image_width, mInfo.image_height,
mFrame->GetWidth(&width); gfxASurface::ImageFormatRGB24,
mFrame->GetHeight(&height); &mImageData, &imagelength))) {
mState = JPEG_ERROR;
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);
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels", ("} (could not initialize image frame)"));
mInfo.image_width, mInfo.image_height)); 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; mState = JPEG_START_DECOMPRESS;
} }
@ -699,16 +673,9 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
const PRUint32 top = mInfo.output_scanline; const PRUint32 top = mInfo.output_scanline;
nsresult rv = NS_OK; 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)) { while ((mInfo.output_scanline < mInfo.output_height)) {
/* Use the Cairo image buffer as scanline buffer */ /* Use the Cairo image buffer as scanline buffer */
PRUint32 *imageRow = ((PRUint32*)imageData) + PRUint32 *imageRow = ((PRUint32*)mImageData) +
(mInfo.output_scanline * mInfo.output_width); (mInfo.output_scanline * mInfo.output_width);
if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) { if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
@ -791,13 +758,10 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
if (top != mInfo.output_scanline) { if (top != mInfo.output_scanline) {
nsIntRect r(0, top, mInfo.output_width, mInfo.output_scanline-top); nsIntRect r(0, top, mInfo.output_width, mInfo.output_scanline-top);
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame)); rv = mImage->FrameUpdated(0, r);
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r); mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
mObserver->OnDataAvailable(nsnull, mFrame, &r);
} }
mFrame->UnlockImageData();
return rv; return rv;
} }
@ -1013,15 +977,16 @@ term_source (j_decompress_ptr jd)
nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data); nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data);
if (decoder->mObserver) { if (decoder->mObserver) {
decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame); decoder->mObserver->OnStopFrame(nsnull, 0);
decoder->mObserver->OnStopContainer(nsnull, decoder->mImage); decoder->mObserver->OnStopContainer(nsnull, decoder->mImage);
decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull); decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
} }
PRBool isMutable = PR_FALSE; PRBool multipart = PR_FALSE;
if (decoder->mImageLoad) if (decoder->mImageLoad)
decoder->mImageLoad->GetIsMultiPartChannel(&isMutable); decoder->mImageLoad->GetIsMultiPartChannel(&multipart);
decoder->mFrame->SetMutable(isMutable); if (!multipart)
decoder->mImage->DecodingComplete();
} }

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

@ -45,7 +45,6 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "imgILoad.h" #include "imgILoad.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
@ -99,9 +98,9 @@ protected:
public: public:
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<imgILoad> mImageLoad; nsCOMPtr<imgILoad> mImageLoad;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgIDecoderObserver> mObserver; nsCOMPtr<imgIDecoderObserver> mObserver;
PRUint8 *mImageData;
struct jpeg_decompress_struct mInfo; struct jpeg_decompress_struct mInfo;
struct jpeg_source_mgr mSourceMgr; struct jpeg_source_mgr mSourceMgr;

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

@ -48,7 +48,6 @@
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "imgIContainerObserver.h" #include "imgIContainerObserver.h"
#include "nsIImage.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "gfxColor.h" #include "gfxColor.h"
@ -99,25 +98,29 @@ nsPNGDecoder::~nsPNGDecoder()
// CreateFrame() is used for both simple and animated images // CreateFrame() is used for both simple and animated images
void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, 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"); PRUint32 imageDataLength;
if (!mFrame) nsresult rv = mImage->AppendFrame(x_offset, y_offset, width, height, format,
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY &mImageData, &imageDataLength);
nsresult rv = mFrame->Init(x_offset, y_offset, width, height, format, 24);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY 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)) if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL))
SetAnimFrameInfo(); 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, PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p", ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p",
width, height, width, height,
@ -141,7 +144,7 @@ void nsPNGDecoder::SetAnimFrameInfo()
blend_op = png_get_next_frame_blend_op(mPNG, mInfo); blend_op = png_get_next_frame_blend_op(mPNG, mInfo);
if (delay_num == 0) { if (delay_num == 0) {
timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum timeout = 0; // SetFrameTimeout() will set to a minimum
} else { } else {
if (delay_den == 0) if (delay_den == 0)
delay_den = 100; // so says the APNG spec delay_den = 100; // so says the APNG spec
@ -151,54 +154,49 @@ void nsPNGDecoder::SetAnimFrameInfo()
timeout = static_cast<PRInt32> timeout = static_cast<PRInt32>
(static_cast<PRFloat64>(delay_num) * 1000 / delay_den); (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) 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) else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear); mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeClear);
else else
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep); mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeKeep);
if (blend_op == PNG_BLEND_OP_SOURCE) if (blend_op == PNG_BLEND_OP_SOURCE)
mFrame->SetBlendMethod(imgIContainer::kBlendSource); mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
/*else // 'over' is the default for a gfxImageFrame /*else // 'over' is the default
mFrame->SetBlendMethod(imgIContainer::kBlendOver); */ mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
} }
// set timeout and frame disposal method for the current frame // set timeout and frame disposal method for the current frame
void nsPNGDecoder::EndImageFrame() 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; PRUint32 numFrames = 0;
mFrame->GetTimeout(&timeout);
mImage->GetNumFrames(&numFrames); mImage->GetNumFrames(&numFrames);
// We can't use mPNG->num_frames_read as it may be one ahead. // We can't use mPNG->num_frames_read as it may be one ahead.
if (numFrames > 1) { if (numFrames > 1) {
// Tell the image renderer that the frame is complete // Tell the image renderer that the frame is complete
PRInt32 width, height; if (mFrameHasNoAlpha)
mFrame->GetWidth(&width); mImage->SetFrameHasNoAlpha(numFrames - 1);
mFrame->GetHeight(&height);
nsIntRect r(0, 0, width, height); if (NS_FAILED(mImage->FrameUpdated(numFrames - 1, mFrameRect))) {
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
mError = PR_TRUE; mError = PR_TRUE;
// allow the call out to the observers. // 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) 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)); mImageLoad->GetImage(getter_AddRefs(mImage));
if (!mImage) { if (!mImage) {
mImage = do_CreateInstance("@mozilla.org/image/container;1"); mImage = do_CreateInstance("@mozilla.org/image/container;2");
if (!mImage) if (!mImage)
return NS_ERROR_OUT_OF_MEMORY; 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, decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
color_type, &inType, &pIntent); color_type, &inType, &pIntent);
/* If we're not mandating an intent, use the one from the image. */ /* If we're not mandating an intent, use the one from the image. */
if (intent == -1) if (intent == PRUint32(-1))
intent = pIntent; intent = pIntent;
} }
if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) { if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) {
qcms_data_type outType; qcms_data_type outType;
PRUint32 dwFlags = 0;
if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
outType = QCMS_DATA_RGBA_8; outType = QCMS_DATA_RGBA_8;
@ -631,22 +628,17 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
if (containerWidth == 0 && containerHeight == 0) { if (containerWidth == 0 && containerHeight == 0) {
// the image hasn't been inited yet // the image hasn't been inited yet
decoder->mImage->Init(width, height, decoder->mObserver); 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 longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_UNEXPECTED
} }
if (decoder->mObserver) if (decoder->mObserver)
decoder->mObserver->OnStartContainer(nsnull, decoder->mImage); decoder->mObserver->OnStartContainer(nsnull, decoder->mImage);
if (channels == 1 || channels == 3) { if (channels == 1 || channels == 3)
decoder->format = gfxIFormats::RGB; decoder->format = gfxASurface::ImageFormatRGB24;
} else if (channels == 2 || channels == 4) { else if (channels == 2 || channels == 4)
if (alpha_bits == 8) { decoder->format = gfxASurface::ImageFormatARGB32;
decoder->format = gfxIFormats::RGB_A8;
} else if (alpha_bits == 1) {
decoder->format = gfxIFormats::RGB_A1;
}
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL); 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). /* 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 * 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 * 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; return;
if (new_row) { if (new_row) {
PRInt32 width; PRInt32 width = decoder->mFrameRect.width;
decoder->mFrame->GetWidth(&width); PRUint32 iwidth = decoder->mFrameRect.width;
PRUint32 iwidth = width;
png_bytep line = new_row; png_bytep line = new_row;
if (decoder->interlacebuf) { 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); png_progressive_combine_row(png_ptr, line, new_row);
} }
// we're thebes. we can write stuff directly to the data PRUint32 bpr = width * sizeof(PRUint32);
PRUint8 *imageData; PRUint32 *cptr32 = (PRUint32*)(decoder->mImageData + (row_num*bpr));
PRUint32 imageDataLength, bpr = width * sizeof(PRUint32);
decoder->mFrame->GetImageData(&imageData, &imageDataLength);
PRUint32 *cptr32 = (PRUint32*)(imageData + (row_num*bpr));
PRBool rowHasNoAlpha = PR_TRUE; PRBool rowHasNoAlpha = PR_TRUE;
if (decoder->mTransform) { if (decoder->mTransform) {
@ -758,7 +743,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
} }
switch (decoder->format) { switch (decoder->format) {
case gfxIFormats::RGB: case gfxASurface::ImageFormatRGB24:
{ {
// counter for while() loops below // counter for while() loops below
PRUint32 idx = iwidth; PRUint32 idx = iwidth;
@ -785,17 +770,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
} }
} }
break; break;
case gfxIFormats::RGB_A1: case gfxASurface::ImageFormatARGB32:
{
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:
{ {
for (PRUint32 x=width; x>0; --x) { for (PRUint32 x=width; x>0; --x) {
*cptr32++ = GFX_PACKED_PIXEL(line[3], line[0], line[1], line[2]); *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; break;
default:
NS_ERROR("Unknown PNG format!");
NS_ABORT();
break;
} }
if (!rowHasNoAlpha) if (!rowHasNoAlpha)
@ -815,12 +794,13 @@ row_callback(png_structp png_ptr, png_bytep new_row,
if (numFrames <= 1) { if (numFrames <= 1) {
// Only do incremental image display for the first frame // Only do incremental image display for the first frame
nsIntRect r(0, row_num, width, 1); nsIntRect r(0, row_num, width, 1);
nsCOMPtr<nsIImage> img(do_GetInterface(decoder->mFrame)); if (NS_FAILED(decoder->mImage->FrameUpdated(numFrames - 1, r))) {
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
decoder->mError = PR_TRUE; /* bail */ decoder->mError = PR_TRUE; /* bail */
return; 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 "imgIContainer.h"
#include "imgIDecoderObserver.h" #include "imgIDecoderObserver.h"
#include "gfxIImageFrame.h"
#include "imgILoad.h" #include "imgILoad.h"
#include "gfxASurface.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -72,25 +71,27 @@ public:
virtual ~nsPNGDecoder(); virtual ~nsPNGDecoder();
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, 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 SetAnimFrameInfo();
void EndImageFrame(); void EndImageFrame();
public: public:
nsCOMPtr<imgIContainer> mImage; nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<gfxIImageFrame> mFrame;
nsCOMPtr<imgILoad> mImageLoad; nsCOMPtr<imgILoad> mImageLoad;
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
png_structp mPNG; png_structp mPNG;
png_infop mInfo; png_infop mInfo;
nsIntRect mFrameRect;
PRUint8 *mCMSLine; PRUint8 *mCMSLine;
PRUint8 *interlacebuf; PRUint8 *interlacebuf;
PRUint8 *mImageData;
qcms_profile *mInProfile; qcms_profile *mInProfile;
qcms_transform *mTransform; qcms_transform *mTransform;
gfx_format format; gfxASurface::gfxImageFormat format;
PRUint8 mChannels; PRUint8 mChannels;
PRPackedBool mError; PRPackedBool mError;
PRPackedBool mFrameHasNoAlpha; PRPackedBool mFrameHasNoAlpha;

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