mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Merging cedar with mozilla-central.
This commit is contained in:
commit
c2223f5860
@ -90,8 +90,8 @@ _TEST_FILES =\
|
||||
test_aria_roles.xul \
|
||||
test_aria_token_attrs.html \
|
||||
test_bug420863.html \
|
||||
$(warning test_childAtPoint.html temporarily disabled) \
|
||||
$(warning test_childAtPoint.xul temporarily disabled) \
|
||||
test_childAtPoint.html \
|
||||
test_childAtPoint.xul \
|
||||
test_descr.html \
|
||||
test_elm_landmarks.html \
|
||||
test_elm_listbox.xul \
|
||||
|
@ -25,19 +25,19 @@
|
||||
testChildAtPoint(list, 1, 1, true, image.firstChild);
|
||||
|
||||
// ::MustPrune case (in this case childAtPoint doesn't look inside a
|
||||
// button), point is inside of button.
|
||||
var btn = getAccessible("btn");
|
||||
testChildAtPoint(btn, 1, 1, false, btn);
|
||||
testChildAtPoint(btn, 1, 1, true, btn);
|
||||
// textbox), point is inside of textbox.
|
||||
var txt = getAccessible("txt");
|
||||
testChildAtPoint(txt, 1, 1, false, txt);
|
||||
testChildAtPoint(txt, 1, 1, true, txt);
|
||||
|
||||
// ::MustPrune case, point is outside of button accessible but is in
|
||||
// ::MustPrune case, point is outside of textbox accessible but is in
|
||||
// document.
|
||||
testChildAtPoint(btn, -1, 1, false, null);
|
||||
testChildAtPoint(btn, -1, 1, true, null);
|
||||
testChildAtPoint(txt, -1, 1, false, null);
|
||||
testChildAtPoint(txt, -1, 1, true, null);
|
||||
|
||||
// ::MustPrune case, point is outside of root accessible.
|
||||
testChildAtPoint(btn, -10000, 10000, false, null);
|
||||
testChildAtPoint(btn, -10000, 10000, true, null);
|
||||
testChildAtPoint(txt, -10000, 10000, false, null);
|
||||
testChildAtPoint(txt, -10000, 10000, true, null);
|
||||
|
||||
// Not specific case, point is inside of label accessible.
|
||||
var label = getAccessible("label");
|
||||
@ -82,7 +82,7 @@
|
||||
|
||||
<span role="label">label1</span><span role="label" id="label">label2</span>
|
||||
|
||||
<span role="button">btn1</span><span role="button" id="btn">btn2</span>
|
||||
<span role="textbox">textbox1</span><span role="textbox" id="txt">textbox2</span>
|
||||
|
||||
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
|
||||
</div>
|
||||
|
@ -24,8 +24,7 @@
|
||||
function doTest()
|
||||
{
|
||||
// Initialize the tree
|
||||
var view = new inTreeView();
|
||||
view.mRowCount = 5;
|
||||
var view = new nsTableTreeView(5);
|
||||
|
||||
var tree = getNode("tree");
|
||||
var treeBox = tree.treeBoxObject;
|
||||
|
@ -70,6 +70,7 @@ pref("extensions.blocklist.interval", 86400);
|
||||
pref("extensions.blocklist.level", 2);
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
|
||||
pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
|
||||
|
||||
pref("extensions.update.autoUpdateDefault", true);
|
||||
|
||||
|
@ -963,6 +963,10 @@
|
||||
// if the tab is a blank one.
|
||||
oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
|
||||
if (newBrowser._urlbarFocused && gURLBar) {
|
||||
|
||||
// Explicitly close the popup if the URL bar retains focus
|
||||
gURLBar.closePopup();
|
||||
|
||||
if (!window.fullScreen) {
|
||||
gURLBar.focus();
|
||||
break;
|
||||
|
@ -995,7 +995,8 @@ let UI = {
|
||||
#ifdef XP_MACOSX
|
||||
"preferencesCmdMac", "minimizeWindow",
|
||||
#endif
|
||||
"newNavigator", "newNavigatorTab", "find"
|
||||
"newNavigator", "newNavigatorTab", "undo", "cut", "copy", "paste",
|
||||
"selectAll", "find"
|
||||
].forEach(function(key) {
|
||||
let element = gWindow.document.getElementById("key_" + key);
|
||||
keys[key] = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0);
|
||||
@ -1004,7 +1005,7 @@ let UI = {
|
||||
// for key combinations with shift key, the charCode of upper case letters
|
||||
// are different to the lower case ones so need to handle them differently.
|
||||
["closeWindow", "tabview", "undoCloseTab", "undoCloseWindow",
|
||||
"privatebrowsing"].forEach(function(key) {
|
||||
"privatebrowsing", "redo"].forEach(function(key) {
|
||||
let element = gWindow.document.getElementById("key_" + key);
|
||||
keys[key] = element.getAttribute("key").toLocaleUpperCase().charCodeAt(0);
|
||||
});
|
||||
@ -1043,6 +1044,7 @@ let UI = {
|
||||
case self._browserKeys.undoCloseTab:
|
||||
case self._browserKeys.undoCloseWindow:
|
||||
case self._browserKeys.closeWindow:
|
||||
case self._browserKeys.redo:
|
||||
preventDefault = false;
|
||||
break;
|
||||
case self._browserKeys.tabview:
|
||||
@ -1056,6 +1058,11 @@ let UI = {
|
||||
break;
|
||||
case self._browserKeys.newNavigator:
|
||||
case self._browserKeys.newNavigatorTab:
|
||||
case self._browserKeys.undo:
|
||||
case self._browserKeys.cut:
|
||||
case self._browserKeys.copy:
|
||||
case self._browserKeys.paste:
|
||||
case self._browserKeys.selectAll:
|
||||
preventDefault = false;
|
||||
break;
|
||||
#ifdef XP_UNIX
|
||||
|
@ -171,6 +171,7 @@ _BROWSER_FILES = \
|
||||
browser_bug623893.js \
|
||||
browser_bug624734.js \
|
||||
browser_bug647886.js \
|
||||
browser_bug655584.js \
|
||||
browser_findbarClose.js \
|
||||
browser_contextSearchTabPosition.js \
|
||||
browser_ctrlTab.js \
|
||||
|
23
browser/base/content/test/browser_bug655584.js
Normal file
23
browser/base/content/test/browser_bug655584.js
Normal file
@ -0,0 +1,23 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Bug 655584 - awesomebar suggestions don't update after tab is closed
|
||||
|
||||
function test() {
|
||||
var tab1 = gBrowser.addTab();
|
||||
var tab2 = gBrowser.addTab();
|
||||
|
||||
// When urlbar in a new tab is focused, and a tab switch occurs,
|
||||
// the urlbar popup should be closed
|
||||
gBrowser.selectedTab = tab2;
|
||||
gURLBar.focus(); // focus the urlbar in the tab we will switch to
|
||||
gBrowser.selectedTab = tab1;
|
||||
gURLBar.openPopup();
|
||||
gBrowser.selectedTab = tab2;
|
||||
ok(!gURLBar.popupOpen, "urlbar focused in tab to switch to, close popup");
|
||||
|
||||
// cleanup
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
@ -54,6 +54,9 @@ function test() {
|
||||
|
||||
testVal("<http://sub.>mozilla.org<:666/file.ext>");
|
||||
|
||||
testVal("<http://>[fe80::222:19ff:fe11:8c76]</file.ext>");
|
||||
testVal("<http://user:pass@>[fe80::222:19ff:fe11:8c76]<:666/file.ext>");
|
||||
|
||||
testVal("mailto:admin@mozilla.org");
|
||||
testVal("gopher://mozilla.org/");
|
||||
testVal("about:config");
|
||||
|
@ -192,7 +192,7 @@
|
||||
|
||||
let textNode = this.editor.rootElement.firstChild;
|
||||
let value = textNode.textContent;
|
||||
let matchedURL = value.match(/^((?:http|https|ftp):\/\/(?:[^\/]+@)?)([^\/:]+)/);
|
||||
let matchedURL = value.match(/^((?:http|https|ftp):\/\/(?:[^\/]+@)?)(.+?)(?::\d+)?(?:\/|$)/);
|
||||
if (!matchedURL)
|
||||
return;
|
||||
|
||||
|
@ -265,7 +265,7 @@ let PermissionDefaults = {
|
||||
return this.DENY;
|
||||
},
|
||||
set password(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
let value = (aValue != this.DENY);
|
||||
Services.prefs.setBoolPref("signon.rememberSignons", value);
|
||||
},
|
||||
|
||||
@ -280,7 +280,7 @@ let PermissionDefaults = {
|
||||
return this.DENY;
|
||||
}
|
||||
|
||||
if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == this.COOKIE_DENY) {
|
||||
if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == this.COOKIE_SESSION) {
|
||||
return this.SESSION;
|
||||
}
|
||||
return this.ALLOW;
|
||||
@ -303,7 +303,7 @@ let PermissionDefaults = {
|
||||
return this.UNKNOWN;
|
||||
},
|
||||
set geo(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
let value = (aValue != this.DENY);
|
||||
Services.prefs.setBoolPref("geo.enabled", value);
|
||||
},
|
||||
|
||||
@ -316,7 +316,7 @@ let PermissionDefaults = {
|
||||
return this.UNKNOWN;
|
||||
},
|
||||
set indexedDB(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
let value = (aValue != this.DENY);
|
||||
Services.prefs.setBoolPref("dom.indexedDB.enabled", value);
|
||||
},
|
||||
|
||||
|
@ -123,11 +123,11 @@ libs:: $(topsrcdir)/tools/rb/fix_macosx_stack.py
|
||||
|
||||
# Basic unit tests for some stuff in the unify script
|
||||
check::
|
||||
# build ppc/i386 binaries, and unify them
|
||||
rm -f unify-test-ppc unify-test-i386 unify-test-universal
|
||||
$(HOST_CC) -arch ppc $(srcdir)/unify-test.c -o unify-test-ppc
|
||||
# build x64/i386 binaries, and unify them
|
||||
rm -f unify-test-x64 unify-test-i386 unify-test-universal
|
||||
$(HOST_CC) -arch x86_64 $(srcdir)/unify-test.c -o unify-test-x64
|
||||
$(HOST_CC) -arch i386 $(srcdir)/unify-test.c -o unify-test-i386
|
||||
@if ! $(srcdir)/macosx/universal/unify ./unify-test-ppc ./unify-test-i386 \
|
||||
@if ! $(srcdir)/macosx/universal/unify ./unify-test-x64 ./unify-test-i386 \
|
||||
./unify-test-universal; then \
|
||||
echo "TEST-UNEXPECTED-FAIL | build/ | unify failed to produce a universal binary!"; \
|
||||
false; \
|
||||
|
@ -8401,6 +8401,7 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
AC_DEFINE(HAVE_UINT64_T)
|
||||
|
||||
# Define macros for cairo-features.h
|
||||
TEE_SURFACE_FEATURE="#define CAIRO_HAS_TEE_SURFACE 1"
|
||||
if test "$MOZ_X11"; then
|
||||
XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
|
||||
XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1"
|
||||
@ -8483,6 +8484,7 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
AC_SUBST(QUARTZ_FONT_FEATURE)
|
||||
AC_SUBST(PNG_FUNCTIONS_FEATURE)
|
||||
AC_SUBST(QT_SURFACE_FEATURE)
|
||||
AC_SUBST(TEE_SURFACE_FEATURE)
|
||||
|
||||
MOZ_CAIRO_LIBS='$(call EXPAND_LIBNAME_PATH,mozcairo,$(DEPTH)/gfx/cairo/cairo/src)'" $CAIRO_FT_LIBS"
|
||||
|
||||
|
@ -9,14 +9,12 @@ function testCancel() {
|
||||
xhr.addEventListener("readystatechange", function(e) {
|
||||
if (xhr.readyState == 3) // NOTE : only leaks for state == 3
|
||||
xhr.abort();
|
||||
else if (xhr.readyState == 4)
|
||||
document.documentElement.className = "";
|
||||
}, false);
|
||||
|
||||
xhr.open("GET", "552651.xml", true);
|
||||
xhr.send();
|
||||
|
||||
setTimeout(function f() {
|
||||
document.documentElement.className = "";
|
||||
}, 1000);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
@ -1488,29 +1488,6 @@ public:
|
||||
return sScriptBlockerCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/Set the current number of removable updates. Currently only
|
||||
* UPDATE_CONTENT_MODEL updates are removable, and only when firing mutation
|
||||
* events. These functions should only be called by mozAutoDocUpdateRemover.
|
||||
* The count is also adjusted by the normal calls to BeginUpdate/EndUpdate.
|
||||
*/
|
||||
static void AddRemovableScriptBlocker()
|
||||
{
|
||||
AddScriptBlocker();
|
||||
++sRemovableScriptBlockerCount;
|
||||
}
|
||||
static void RemoveRemovableScriptBlocker()
|
||||
{
|
||||
NS_ASSERTION(sRemovableScriptBlockerCount != 0,
|
||||
"Number of removable blockers should never go below zero");
|
||||
--sRemovableScriptBlockerCount;
|
||||
RemoveScriptBlocker();
|
||||
}
|
||||
static PRUint32 GetRemovableScriptBlockerLevel()
|
||||
{
|
||||
return sRemovableScriptBlockerCount;
|
||||
}
|
||||
|
||||
/* Process viewport META data. This gives us information for the scale
|
||||
* and zoom of a page on mobile devices. We stick the information in
|
||||
* the document header and use it later on after rendering.
|
||||
@ -1861,7 +1838,6 @@ private:
|
||||
|
||||
static PRBool sInitialized;
|
||||
static PRUint32 sScriptBlockerCount;
|
||||
static PRUint32 sRemovableScriptBlockerCount;
|
||||
#ifdef DEBUG
|
||||
static PRUint32 sDOMNodeRemovedSuppressCount;
|
||||
#endif
|
||||
@ -1929,33 +1905,6 @@ private:
|
||||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoRemovableScriptBlocker {
|
||||
public:
|
||||
nsAutoRemovableScriptBlocker(MOZILLA_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
nsContentUtils::AddRemovableScriptBlocker();
|
||||
}
|
||||
~nsAutoRemovableScriptBlocker() {
|
||||
nsContentUtils::RemoveRemovableScriptBlocker();
|
||||
}
|
||||
private:
|
||||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS mozAutoRemovableBlockerRemover
|
||||
{
|
||||
public:
|
||||
mozAutoRemovableBlockerRemover(nsIDocument* aDocument
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
~mozAutoRemovableBlockerRemover();
|
||||
|
||||
private:
|
||||
PRUint32 mNestingLevel;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsIDocumentObserver> mObserver;
|
||||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoScriptBlockerSuppressNodeRemoved :
|
||||
public nsAutoScriptBlocker {
|
||||
public:
|
||||
|
@ -514,8 +514,7 @@ public:
|
||||
* Note: If there is no child at aIndex, this method will simply do nothing.
|
||||
*/
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex,
|
||||
PRBool aNotify,
|
||||
PRBool aMutationEvent = PR_TRUE) = 0;
|
||||
PRBool aNotify) = 0;
|
||||
|
||||
/**
|
||||
* Get a property associated with this node.
|
||||
@ -1295,8 +1294,7 @@ protected:
|
||||
* @param aMutationEvent whether to fire a mutation event for this removal.
|
||||
*/
|
||||
nsresult doRemoveChildAt(PRUint32 aIndex, PRBool aNotify, nsIContent* aKid,
|
||||
nsAttrAndChildArray& aChildArray,
|
||||
PRBool aMutationEvent);
|
||||
nsAttrAndChildArray& aChildArray);
|
||||
|
||||
/**
|
||||
* Most of the implementation of the nsINode InsertChildAt method.
|
||||
|
@ -52,9 +52,6 @@ public:
|
||||
if (mDocument) {
|
||||
mDocument->BeginUpdate(mUpdateType);
|
||||
}
|
||||
else if (aUpdateType == UPDATE_CONTENT_MODEL) {
|
||||
nsContentUtils::AddRemovableScriptBlocker();
|
||||
}
|
||||
else {
|
||||
nsContentUtils::AddScriptBlocker();
|
||||
}
|
||||
@ -65,9 +62,6 @@ public:
|
||||
if (mDocument) {
|
||||
mDocument->EndUpdate(mUpdateType);
|
||||
}
|
||||
else if (mUpdateType == UPDATE_CONTENT_MODEL) {
|
||||
nsContentUtils::RemoveRemovableScriptBlocker();
|
||||
}
|
||||
else {
|
||||
nsContentUtils::RemoveScriptBlocker();
|
||||
}
|
||||
|
@ -255,7 +255,6 @@ PRUint32 nsContentUtils::sJSGCThingRootCount;
|
||||
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
|
||||
#endif
|
||||
PRUint32 nsContentUtils::sScriptBlockerCount = 0;
|
||||
PRUint32 nsContentUtils::sRemovableScriptBlockerCount = 0;
|
||||
#ifdef DEBUG
|
||||
PRUint32 nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
|
||||
#endif
|
||||
@ -6168,35 +6167,6 @@ nsContentUtils::CheckCCWrapperTraversal(nsISupports* aScriptObjectHolder,
|
||||
}
|
||||
#endif
|
||||
|
||||
mozAutoRemovableBlockerRemover::mozAutoRemovableBlockerRemover(nsIDocument* aDocument MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
{
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
mNestingLevel = nsContentUtils::GetRemovableScriptBlockerLevel();
|
||||
mDocument = aDocument;
|
||||
nsISupports* sink = aDocument ? aDocument->GetCurrentContentSink() : nsnull;
|
||||
mObserver = do_QueryInterface(sink);
|
||||
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
|
||||
if (mObserver) {
|
||||
mObserver->EndUpdate(mDocument, UPDATE_CONTENT_MODEL);
|
||||
}
|
||||
nsContentUtils::RemoveRemovableScriptBlocker();
|
||||
}
|
||||
|
||||
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(), "killing mutation events");
|
||||
}
|
||||
|
||||
mozAutoRemovableBlockerRemover::~mozAutoRemovableBlockerRemover()
|
||||
{
|
||||
NS_ASSERTION(nsContentUtils::GetRemovableScriptBlockerLevel() == 0,
|
||||
"Should have had none");
|
||||
for (PRUint32 i = 0; i < mNestingLevel; ++i) {
|
||||
nsContentUtils::AddRemovableScriptBlocker();
|
||||
if (mObserver) {
|
||||
mObserver->BeginUpdate(mDocument, UPDATE_CONTENT_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsFocusedContent(const nsIContent* aContent)
|
||||
|
@ -610,9 +610,8 @@ nsDOMAttribute::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on attribute child removal.");
|
||||
if (aIndex != 0 || !mChild) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
|
@ -3449,9 +3449,8 @@ nsDocument::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on document child removal.");
|
||||
nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
|
||||
if (!oldKid) {
|
||||
return NS_OK;
|
||||
@ -3463,7 +3462,7 @@ nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren, aMutationEvent);
|
||||
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
|
||||
mCachedRootElement = nsnull;
|
||||
return rv;
|
||||
}
|
||||
@ -3952,12 +3951,7 @@ nsDocument::BeginUpdate(nsUpdateType aUpdateType)
|
||||
}
|
||||
|
||||
++mUpdateNestLevel;
|
||||
if (aUpdateType == UPDATE_CONTENT_MODEL) {
|
||||
nsContentUtils::AddRemovableScriptBlocker();
|
||||
}
|
||||
else {
|
||||
nsContentUtils::AddScriptBlocker();
|
||||
}
|
||||
nsContentUtils::AddScriptBlocker();
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this, aUpdateType));
|
||||
}
|
||||
|
||||
@ -3966,12 +3960,7 @@ nsDocument::EndUpdate(nsUpdateType aUpdateType)
|
||||
{
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(EndUpdate, (this, aUpdateType));
|
||||
|
||||
if (aUpdateType == UPDATE_CONTENT_MODEL) {
|
||||
nsContentUtils::RemoveRemovableScriptBlocker();
|
||||
}
|
||||
else {
|
||||
nsContentUtils::RemoveScriptBlocker();
|
||||
}
|
||||
nsContentUtils::RemoveScriptBlocker();
|
||||
|
||||
--mUpdateNestLevel;
|
||||
|
||||
|
@ -730,7 +730,7 @@ public:
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
|
@ -723,7 +723,7 @@ nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public:
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
|
@ -3663,14 +3663,13 @@ nsINode::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
|
||||
NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
|
||||
|
||||
if (oldKid) {
|
||||
return doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren,
|
||||
aMutationEvent);
|
||||
return doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -3678,8 +3677,7 @@ nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutatio
|
||||
|
||||
nsresult
|
||||
nsINode::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
nsIContent* aKid, nsAttrAndChildArray& aChildArray,
|
||||
PRBool aMutationEvent)
|
||||
nsIContent* aKid, nsAttrAndChildArray& aChildArray)
|
||||
{
|
||||
NS_PRECONDITION(aKid && aKid->GetNodeParent() == this &&
|
||||
aKid == GetChildAt(aIndex) &&
|
||||
@ -3991,10 +3989,10 @@ PRBool IsAllowedAsChild(nsIContent* aNewChild, PRUint16 aNewNodeType,
|
||||
void
|
||||
nsGenericElement::FireNodeInserted(nsIDocument* aDoc,
|
||||
nsINode* aParent,
|
||||
nsCOMArray<nsIContent>& aNodes)
|
||||
nsTArray<nsCOMPtr<nsIContent> >& aNodes)
|
||||
{
|
||||
PRInt32 count = aNodes.Count();
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
PRUint32 count = aNodes.Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsIContent* childContent = aNodes[i];
|
||||
|
||||
if (nsContentUtils::HasMutationListeners(childContent,
|
||||
@ -4159,57 +4157,18 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
|
||||
|
||||
// Copy the children into a separate array to avoid having to deal with
|
||||
// mutations to the fragment while we're inserting.
|
||||
nsCOMArray<nsIContent> fragChildren;
|
||||
if (!fragChildren.SetCapacity(count)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
nsAutoTArray<nsCOMPtr<nsIContent>, 50> fragChildren;
|
||||
fragChildren.SetCapacity(count);
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent* child = newContent->GetChildAt(i);
|
||||
NS_ASSERTION(child->GetCurrentDoc() == nsnull,
|
||||
"How did we get a child with a current doc?");
|
||||
fragChildren.AppendObject(child);
|
||||
fragChildren.AppendElement(child);
|
||||
}
|
||||
|
||||
// Remove the children from the fragment and flag for possible mutations.
|
||||
PRBool mutated = PR_FALSE;
|
||||
for (i = count; i > 0;) {
|
||||
// We don't need to update i if someone mutates the DOM. The only thing
|
||||
// that'd happen is that the resulting child list might be unexpected,
|
||||
// but we should never crash since RemoveChildAt is out-of-bounds safe.
|
||||
nsMutationGuard guard;
|
||||
// Remove the children from the fragment.
|
||||
for (PRUint32 i = count; i > 0;) {
|
||||
newContent->RemoveChildAt(--i, PR_TRUE);
|
||||
mutated = mutated || guard.Mutated(1);
|
||||
}
|
||||
|
||||
// If we've had any unexpected mutations so far we need to recheck that
|
||||
// the child can still be inserted.
|
||||
if (mutated) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
// Get the n:th child from the array.
|
||||
nsIContent* childContent = fragChildren[i];
|
||||
if (!HasSameOwnerDoc(childContent) ||
|
||||
doc != childContent->GetOwnerDoc()) {
|
||||
return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> tmpNode = do_QueryInterface(childContent);
|
||||
PRUint16 tmpType = 0;
|
||||
tmpNode->GetNodeType(&tmpType);
|
||||
|
||||
if (childContent->GetNodeParent() ||
|
||||
!IsAllowedAsChild(childContent, tmpType, this, PR_FALSE,
|
||||
refContent)) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
insPos = refContent ? IndexOf(refContent) : GetChildCount();
|
||||
if (insPos < 0) {
|
||||
// Someone seriously messed up the childlist. We have no idea
|
||||
// where to insert the remaining children, so just bail.
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool appending =
|
||||
@ -4219,12 +4178,10 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
|
||||
|
||||
// Iterate through the fragment's children, and insert them in the new
|
||||
// parent
|
||||
for (i = 0; i < count; ++i, ++insPos) {
|
||||
nsIContent* childContent = fragChildren[i];
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i, ++insPos) {
|
||||
// XXXbz how come no reparenting here? That seems odd...
|
||||
// Insert the child.
|
||||
res = InsertChildAt(childContent, insPos, PR_FALSE);
|
||||
res = InsertChildAt(fragChildren[i], insPos, !appending);
|
||||
if (NS_FAILED(res)) {
|
||||
// Make sure to notify on any children that we did succeed to insert
|
||||
if (appending && i != 0) {
|
||||
@ -4234,22 +4191,17 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!appending) {
|
||||
nsNodeUtils::ContentInserted(this, childContent, insPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify
|
||||
// Notify and fire mutation events when appending
|
||||
if (appending) {
|
||||
nsNodeUtils::ContentAppended(static_cast<nsIContent*>(this),
|
||||
firstInsertedContent, firstInsPos);
|
||||
}
|
||||
|
||||
// Fire mutation events. Optimize for the case when there are no listeners
|
||||
if (nsContentUtils::
|
||||
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsGenericElement::FireNodeInserted(doc, this, fragChildren);
|
||||
// Optimize for the case when there are no listeners
|
||||
if (nsContentUtils::
|
||||
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsGenericElement::FireNodeInserted(doc, this, fragChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -4629,7 +4581,7 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
|
||||
// Hold a script blocker while calling ParseAttribute since that can call
|
||||
// out to id-observers
|
||||
nsAutoRemovableScriptBlocker scriptBlocker;
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
nsAttrValue attrValue;
|
||||
if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
|
||||
|
@ -329,7 +329,7 @@ public:
|
||||
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
@ -596,7 +596,7 @@ public:
|
||||
*/
|
||||
static void FireNodeInserted(nsIDocument* aDoc,
|
||||
nsINode* aParent,
|
||||
nsCOMArray<nsIContent>& aNodes);
|
||||
nsTArray<nsCOMPtr<nsIContent> >& aNodes);
|
||||
|
||||
/**
|
||||
* Helper methods for implementing querySelector/querySelectorAll
|
||||
|
@ -136,7 +136,7 @@ nsStyledElementNotElementCSSInlineStyle::UnsetAttr(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsAutoRemovableScriptBlocker scriptBlocker;
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
if (aAttribute == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
|
||||
// Have to do this before clearing flag. See RemoveFromIdTable
|
||||
RemoveFromIdTable();
|
||||
|
@ -782,12 +782,12 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
|
||||
PRInt32 newChildCount = GetChildCount();
|
||||
if (newChildCount && nsContentUtils::
|
||||
HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMArray<nsIContent> childNodes;
|
||||
nsAutoTArray<nsCOMPtr<nsIContent>, 50> childNodes;
|
||||
NS_ASSERTION(newChildCount - oldChildCount >= 0,
|
||||
"What, some unexpected dom mutation has happened?");
|
||||
childNodes.SetCapacity(newChildCount - oldChildCount);
|
||||
for (nsINode::ChildIterator iter(this); !iter.IsDone(); iter.Next()) {
|
||||
childNodes.AppendObject(iter);
|
||||
childNodes.AppendElement(iter);
|
||||
}
|
||||
nsGenericElement::FireNodeInserted(doc, this, childNodes);
|
||||
}
|
||||
|
@ -217,8 +217,7 @@ nsHTMLFieldSetElement::InsertChildAt(nsIContent* aChild, PRUint32 aIndex,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFieldSetElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
PRBool aMutationEvent /* = PR_TRUE */)
|
||||
nsHTMLFieldSetElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
bool firstLegendHasChanged = false;
|
||||
|
||||
@ -236,7 +235,7 @@ nsHTMLFieldSetElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (firstLegendHasChanged) {
|
||||
|
@ -76,8 +76,7 @@ public:
|
||||
|
||||
virtual nsresult InsertChildAt(nsIContent* aChild, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
|
||||
// nsIFormControl
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_FIELDSET; }
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
// nsGenericElement
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
@ -182,10 +182,11 @@ nsHTMLOptGroupElement::InsertChildAt(nsIContent* aKid,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLOptGroupElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsHTMLOptGroupElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
nsSafeOptionListMutation safeMutation(GetSelect(), this, nsnull, aIndex, aNotify);
|
||||
nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
nsSafeOptionListMutation safeMutation(GetSelect(), this, nsnull, aIndex,
|
||||
aNotify);
|
||||
nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify);
|
||||
if (NS_FAILED(rv)) {
|
||||
safeMutation.MutationFailed();
|
||||
}
|
||||
|
@ -237,11 +237,10 @@ nsHTMLSelectElement::InsertChildAt(nsIContent* aKid,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSelectElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsHTMLSelectElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on select child removal.");
|
||||
nsSafeOptionListMutation safeMutation(this, this, nsnull, aIndex, aNotify);
|
||||
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify);
|
||||
if (NS_FAILED(rv)) {
|
||||
safeMutation.MutationFailed();
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ public:
|
||||
virtual PRBool IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRInt32 *aTabIndex);
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
|
||||
// Overriden nsIFormControl methods
|
||||
NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_SELECT; }
|
||||
|
@ -121,10 +121,9 @@ nsSVGSwitchElement::InsertChildAt(nsIContent* aKid,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGSwitchElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsSVGSwitchElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on switch child removal.");
|
||||
nsresult rv = nsSVGSwitchElementBase::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
nsresult rv = nsSVGSwitchElementBase::RemoveChildAt(aIndex, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MaybeInvalidate();
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
// nsINode
|
||||
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
|
||||
// nsIContent
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
@ -72,7 +72,7 @@ nsresult
|
||||
nsXMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsAutoRemovableScriptBlocker scriptBlocker;
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
PRBool isId = PR_FALSE;
|
||||
if (aAttribute == GetIDAttributeName() &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
|
@ -271,13 +271,12 @@ nsXTFElementWrapper::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXTFElementWrapper::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsXTFElementWrapper::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on xtf child removal.");
|
||||
nsresult rv;
|
||||
if (mNotificationMask & nsIXTFElement::NOTIFY_WILL_REMOVE_CHILD)
|
||||
GetXTFElement()->WillRemoveChild(aIndex);
|
||||
rv = nsXTFElementWrapperBase::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
rv = nsXTFElementWrapperBase::RemoveChildAt(aIndex, aNotify);
|
||||
if (mNotificationMask & nsIXTFElement::NOTIFY_CHILD_REMOVED)
|
||||
GetXTFElement()->ChildRemoved(aIndex);
|
||||
return rv;
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
PRBool aNotify);
|
||||
nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
nsIAtom *GetIDAttributeName() const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
|
@ -946,9 +946,8 @@ nsXULElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
|
||||
nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on XUL child removal.");
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
|
||||
if (!oldKid) {
|
||||
@ -1015,7 +1014,7 @@ nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEve
|
||||
}
|
||||
}
|
||||
|
||||
rv = nsStyledElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
|
||||
rv = nsStyledElement::RemoveChildAt(aIndex, aNotify);
|
||||
|
||||
if (newCurrentIndex == -2)
|
||||
controlElement->SetCurrentItem(nsnull);
|
||||
|
@ -505,7 +505,7 @@ public:
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep, PRBool aNullParent);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual PRBool GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAString& aResult) const;
|
||||
virtual PRBool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
|
||||
|
@ -7846,6 +7846,56 @@ nsDocShell::CheckLoadingPermissions()
|
||||
//*****************************************************************************
|
||||
// nsDocShell: Site Loading
|
||||
//*****************************************************************************
|
||||
namespace
|
||||
{
|
||||
|
||||
// Callback used by CopyFavicon to inform the favicon service that one URI
|
||||
// (mNewURI) has the same favicon URI (OnFaviconDataAvailable's aFaviconURI) as
|
||||
// another.
|
||||
class nsCopyFaviconCallback : public nsIFaviconDataCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsCopyFaviconCallback(nsIURI *aNewURI)
|
||||
: mNewURI(aNewURI)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OnFaviconDataAvailable(nsIURI *aFaviconURI, PRUint32 aDataLen,
|
||||
const PRUint8 *aData, const nsACString &aMimeType)
|
||||
{
|
||||
NS_ASSERTION(aDataLen == 0,
|
||||
"We weren't expecting the callback to deliver data.");
|
||||
nsCOMPtr<mozIAsyncFavicons> favSvc =
|
||||
do_GetService("@mozilla.org/browser/favicon-service;1");
|
||||
NS_ENSURE_STATE(favSvc);
|
||||
|
||||
return favSvc->SetAndFetchFaviconForPage(mNewURI, aFaviconURI,
|
||||
PR_FALSE, nsnull);
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIURI> mNewURI;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCopyFaviconCallback, nsIFaviconDataCallback)
|
||||
|
||||
// Tell the favicon service that aNewURI has the same favicon as aOldURI.
|
||||
void CopyFavicon(nsIURI *aOldURI, nsIURI *aNewURI)
|
||||
{
|
||||
nsCOMPtr<mozIAsyncFavicons> favSvc =
|
||||
do_GetService("@mozilla.org/browser/favicon-service;1");
|
||||
if (favSvc) {
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
new nsCopyFaviconCallback(aNewURI);
|
||||
favSvc->GetFaviconURLForPage(aOldURI, callback);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class InternalLoadEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
@ -8450,6 +8500,10 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the favicon service that the favicon for oldURI also
|
||||
// applies to aURI.
|
||||
CopyFavicon(oldURI, aURI);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -9439,43 +9493,6 @@ nsDocShell::SetReferrerURI(nsIURI * aURI)
|
||||
// nsDocShell: Session History
|
||||
//*****************************************************************************
|
||||
|
||||
namespace
|
||||
{
|
||||
// Callback used in nsDocShell::AddState. When we change URIs with
|
||||
// push/replaceState, we use this callback to ensure that Places associates
|
||||
// a favicon with the new URI.
|
||||
class nsAddStateFaviconCallback : public nsIFaviconDataCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsAddStateFaviconCallback(nsIURI *aNewURI)
|
||||
: mNewURI(aNewURI)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OnFaviconDataAvailable(nsIURI *aFaviconURI, PRUint32 aDataLen,
|
||||
const PRUint8 *aData, const nsACString &aMimeType)
|
||||
{
|
||||
NS_ASSERTION(aDataLen == 0,
|
||||
"We weren't expecting the callback to deliver data.");
|
||||
nsCOMPtr<mozIAsyncFavicons> favSvc =
|
||||
do_GetService("@mozilla.org/browser/favicon-service;1");
|
||||
NS_ENSURE_STATE(favSvc);
|
||||
|
||||
return favSvc->SetAndFetchFaviconForPage(mNewURI, aFaviconURI,
|
||||
PR_FALSE, nsnull);
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIURI> mNewURI;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAddStateFaviconCallback, nsIFaviconDataCallback)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
|
||||
const nsAString& aURL, PRBool aReplace, JSContext* aCx)
|
||||
@ -9766,13 +9783,7 @@ nsDocShell::AddState(nsIVariant *aData, const nsAString& aTitle,
|
||||
|
||||
// Inform the favicon service that our old favicon applies to this new
|
||||
// URI.
|
||||
nsCOMPtr<mozIAsyncFavicons> favSvc =
|
||||
do_GetService("@mozilla.org/browser/favicon-service;1");
|
||||
if (favSvc) {
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback =
|
||||
new nsAddStateFaviconCallback(newURI);
|
||||
favSvc->GetFaviconURLForPage(oldURI, callback);
|
||||
}
|
||||
CopyFavicon(oldURI, newURI);
|
||||
}
|
||||
else {
|
||||
FireDummyOnLocationChange();
|
||||
|
@ -51,6 +51,8 @@ _BROWSER_TEST_FILES = \
|
||||
browser_bug388121-1.js \
|
||||
browser_bug388121-2.js \
|
||||
browser_bug441169.js \
|
||||
browser_bug420605.js \
|
||||
file_bug420605.html \
|
||||
browser_bug503832.js \
|
||||
browser_loadDisallowInherit.js \
|
||||
file_bug503832.html \
|
||||
|
123
docshell/test/browser/browser_bug420605.js
Normal file
123
docshell/test/browser/browser_bug420605.js
Normal file
@ -0,0 +1,123 @@
|
||||
/* Test for Bug 420605
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=420605
|
||||
*/
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var pageurl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html";
|
||||
var fragmenturl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html#firefox";
|
||||
|
||||
var historyService = Cc["@mozilla.org/browser/nav-history-service;1"]
|
||||
.getService(Ci.nsINavHistoryService);
|
||||
|
||||
/* Queries nsINavHistoryService and returns a single history entry
|
||||
* for a given URI */
|
||||
function getNavHistoryEntry(aURI) {
|
||||
var options = historyService.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
|
||||
options.maxResults = 1;
|
||||
|
||||
var query = historyService.getNewQuery();
|
||||
query.uri = aURI;
|
||||
|
||||
var result = historyService.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
|
||||
if (!result.root.childCount) {
|
||||
return null;
|
||||
}
|
||||
return result.root.getChild(0);
|
||||
}
|
||||
|
||||
// We'll save the favicon URL of the orignal page here and check that the
|
||||
// page with a hash has the same favicon.
|
||||
var originalFavicon;
|
||||
|
||||
// Control flow in this test is a bit complicated.
|
||||
//
|
||||
// When the page loads, onPageLoad (the DOMContentLoaded handler) and
|
||||
// historyObserver::onPageChanged are both called, in some order. Once
|
||||
// they've both run, we click a fragment link in the content page
|
||||
// (clickLinkIfReady), which should trigger another onPageChanged event,
|
||||
// this time for the fragment's URL.
|
||||
|
||||
var _clickLinkTimes = 0;
|
||||
function clickLinkIfReady() {
|
||||
_clickLinkTimes++;
|
||||
if (_clickLinkTimes == 2) {
|
||||
EventUtils.sendMouseEvent({type:'click'}, 'firefox-link',
|
||||
gBrowser.selectedBrowser.contentWindow);
|
||||
}
|
||||
}
|
||||
|
||||
/* Global history observer that triggers for the two test URLs above. */
|
||||
var historyObserver = {
|
||||
onBeginUpdateBatch: function() {},
|
||||
onEndUpdateBatch: function() {},
|
||||
onVisit: function(aURI, aVisitID, aTime, aSessionId, aReferringId,
|
||||
aTransitionType, _added) {},
|
||||
onTitleChanged: function(aURI, aPageTitle) {},
|
||||
onBeforeDeleteURI: function(aURI) {},
|
||||
onDeleteURI: function(aURI) {},
|
||||
onClearHistory: function() {},
|
||||
onPageChanged: function(aURI, aWhat, aValue) {
|
||||
if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
|
||||
return;
|
||||
}
|
||||
aURI = aURI.spec;
|
||||
switch (aURI) {
|
||||
case pageurl:
|
||||
ok(aValue, "Favicon value is not null for page without fragment.");
|
||||
originalFavicon = aValue;
|
||||
|
||||
// Now that the favicon has loaded, click on fragment link.
|
||||
// This should trigger the |case fragmenturl| below.
|
||||
clickLinkIfReady();
|
||||
|
||||
return;
|
||||
case fragmenturl:
|
||||
// If the fragment URL's favicon isn't set, this branch won't
|
||||
// be called and the test will time out.
|
||||
|
||||
is(aValue, originalFavicon, "New favicon should be same as original favicon.");
|
||||
|
||||
// Let's explicitly check that we can get the favicon
|
||||
// from nsINavHistoryService now.
|
||||
let info = getNavHistoryEntry(makeURI(aURI));
|
||||
ok(info, "There must be a history entry for the fragment.");
|
||||
ok(info.icon, "The history entry must have an associated favicon.");
|
||||
historyService.removeObserver(historyObserver, false);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
},
|
||||
onPageExpired: function(aURI, aVisitTime, aWholeEntry) {},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsINavHistoryObserver) ||
|
||||
iid.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
historyService.addObserver(historyObserver, false);
|
||||
|
||||
function onPageLoad() {
|
||||
gBrowser.selectedBrowser
|
||||
.removeEventListener("DOMContentLoaded", arguments.callee, true);
|
||||
clickLinkIfReady();
|
||||
}
|
||||
|
||||
// Make sure neither of the test pages haven't been loaded before.
|
||||
var info = getNavHistoryEntry(makeURI(pageurl));
|
||||
ok(!info, "The test page must not have been visited already.");
|
||||
info = getNavHistoryEntry(makeURI(fragmenturl));
|
||||
ok(!info, "The fragment test page must not have been visited already.");
|
||||
|
||||
// Now open the test page in a new tab.
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener(
|
||||
"DOMContentLoaded", onPageLoad, true);
|
||||
content.location = pageurl;
|
||||
}
|
31
docshell/test/browser/file_bug420605.html
Normal file
31
docshell/test/browser/file_bug420605.html
Normal file
@ -0,0 +1,31 @@
|
||||
<head>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="/>
|
||||
<title>Page Title for Bug 420605</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Fragment links</h1>
|
||||
|
||||
<p>This page has a bunch of fragment links to sections below:</p>
|
||||
|
||||
<ul>
|
||||
<li><a id="firefox-link" href="#firefox">Firefox</a></li>
|
||||
<li><a id="thunderbird-link" href="#thunderbird">Thunderbird</a></li>
|
||||
<li><a id="seamonkey-link" href="#seamonkey">Seamonkey</a></li>
|
||||
</ul>
|
||||
|
||||
<p>And here are the sections:</p>
|
||||
|
||||
<h2 id="firefox">Firefox</h2>
|
||||
|
||||
<p>Firefox is a browser.</p>
|
||||
|
||||
<h2 id="thunderbird">Thunderbird</h2>
|
||||
|
||||
<p>Thunderbird is an email client</p>
|
||||
|
||||
<h2 id="seamonkey">Seamonkey</h2>
|
||||
|
||||
<p>Seamonkey is the all-in-one application.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -5807,7 +5807,8 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ASSERTION(rangeCount == rangeItemArray.Length(), "How did that happen?");
|
||||
NS_ASSERTION(static_cast<PRUint32>(rangeCount) == rangeItemArray.Length(),
|
||||
"How did that happen?");
|
||||
|
||||
// first register ranges for special editor gravity
|
||||
for (i = 0; i < rangeCount; i++)
|
||||
|
@ -1700,7 +1700,27 @@ nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection)
|
||||
return aSelection->Collapse(rootElement, 0);
|
||||
}
|
||||
|
||||
return nsEditor::SelectEntireDocument(aSelection);
|
||||
nsresult rv = nsEditor::SelectEntireDocument(aSelection);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Don't select the trailing BR node if we have one
|
||||
PRInt32 selOffset;
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
rv = GetEndNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> childNode = GetChildAt(selNode, selOffset - 1);
|
||||
|
||||
if (childNode && nsTextEditUtils::IsMozBR(childNode)) {
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
PRInt32 parentOffset;
|
||||
rv = GetNodeLocation(childNode, address_of(parentNode), &parentOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aSelection->Extend(parentNode, parentOffset);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMEventTarget>
|
||||
|
@ -70,20 +70,25 @@ CSRCS = \
|
||||
cairo-arc.c \
|
||||
cairo-array.c \
|
||||
cairo-atomic.c \
|
||||
cairo-base64-stream.c \
|
||||
cairo-bentley-ottmann.c \
|
||||
cairo-bentley-ottmann-rectilinear.c \
|
||||
cairo-bentley-ottmann-rectangular.c \
|
||||
cairo-base64-stream.c \
|
||||
cairo-botor-scan-converter.c \
|
||||
cairo-boxes.c \
|
||||
cairo-cache.c \
|
||||
cairo-clip.c \
|
||||
cairo-color.c \
|
||||
cairo-composite-rectangles.c \
|
||||
cairo-debug.c \
|
||||
cairo-deflate-stream.c \
|
||||
cairo-device.c \
|
||||
cairo-fixed.c \
|
||||
cairo-font-face.c \
|
||||
cairo-font-face-twin.c \
|
||||
cairo-font-face-twin-data.c \
|
||||
cairo-font-options.c \
|
||||
cairo-freed-pool.c \
|
||||
cairo-freelist.c \
|
||||
cairo-gstate.c \
|
||||
cairo-hash.c \
|
||||
@ -94,6 +99,7 @@ CSRCS = \
|
||||
cairo-matrix.c \
|
||||
cairo-misc.c \
|
||||
cairo-mutex.c \
|
||||
cairo-observer.c \
|
||||
cairo-output-stream.c \
|
||||
cairo-paginated-surface.c \
|
||||
cairo-path.c \
|
||||
@ -107,6 +113,7 @@ CSRCS = \
|
||||
cairo-polygon.c \
|
||||
cairo-recording-surface.c \
|
||||
cairo-rectangle.c \
|
||||
cairo-rectangular-scan-converter.c \
|
||||
cairo-region.c \
|
||||
cairo-scaled-font.c \
|
||||
cairo-scaled-font-subsets.c \
|
||||
@ -117,6 +124,9 @@ CSRCS = \
|
||||
cairo-surface.c \
|
||||
cairo-surface-clipper.c \
|
||||
cairo-surface-fallback.c \
|
||||
cairo-surface-offset.c \
|
||||
cairo-surface-snapshot.c \
|
||||
cairo-surface-subsurface.c \
|
||||
cairo-surface-wrapper.c \
|
||||
cairo-tee-surface.c \
|
||||
cairo-tor-scan-converter.c \
|
||||
@ -130,7 +140,7 @@ CSRCS = \
|
||||
|
||||
EXPORTS_NAMESPACES = cairo
|
||||
|
||||
EXPORTS_cairo = cairo.h cairo-version.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h
|
||||
EXPORTS_cairo = cairo.h cairo-version.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h cairo-tee.h
|
||||
|
||||
# cairo-type1-subset.c should be here, but it's only supported on freetype platforms
|
||||
|
||||
@ -153,6 +163,7 @@ PDF_EXPORTS = cairo-pdf.h
|
||||
PS_EXPORTS = cairo-ps.h
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
DEFINES += -DDISABLE_SOME_FLOATING_POINT
|
||||
CSRCS += cairo-win32-surface.c
|
||||
|
||||
ifndef WINCE
|
||||
@ -269,3 +280,4 @@ endif
|
||||
|
||||
cairo-features.h: $(srcdir)/cairo-features.h.in $(GLOBAL_DEPS)
|
||||
$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) ./$@
|
||||
cat cairo-dwrite-font.i | gzip | python -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)"
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -37,6 +37,8 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_analysis_surface_create (cairo_surface_t *target);
|
||||
|
||||
@ -71,4 +73,6 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_null_surface_create (cairo_content_t content);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_ANALYSIS_SURFACE_H */
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -37,8 +37,10 @@
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-paginated-private.h"
|
||||
#include "cairo-recording-surface-private.h"
|
||||
#include "cairo-surface-subsurface-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
|
||||
typedef struct {
|
||||
@ -99,10 +101,11 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
|
||||
cairo_bool_t old_has_ctm;
|
||||
cairo_matrix_t old_ctm, p2d;
|
||||
cairo_status_t status;
|
||||
cairo_surface_t *source;
|
||||
|
||||
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
||||
surface_pattern = (const cairo_surface_pattern_t *) pattern;
|
||||
assert (_cairo_surface_is_recording (surface_pattern->surface));
|
||||
assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
|
||||
|
||||
old_ctm = surface->ctm;
|
||||
old_has_ctm = surface->has_ctm;
|
||||
@ -114,8 +117,13 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
|
||||
cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
|
||||
surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
|
||||
|
||||
status = _cairo_recording_surface_replay_and_create_regions (surface_pattern->surface,
|
||||
&surface->base);
|
||||
source = surface_pattern->surface;
|
||||
if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
|
||||
cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
|
||||
source = sub->target;
|
||||
}
|
||||
|
||||
status = _cairo_recording_surface_replay_and_create_regions (source, &surface->base);
|
||||
|
||||
surface->ctm = old_ctm;
|
||||
surface->has_ctm = old_has_ctm;
|
||||
@ -396,9 +404,9 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_clip_t *clip)
|
||||
@ -716,7 +724,9 @@ _cairo_analysis_surface_create (cairo_surface_t *target)
|
||||
|
||||
/* I believe the content type here is truly arbitrary. I'm quite
|
||||
* sure nothing will ever use this value. */
|
||||
_cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
|
||||
_cairo_surface_init (&surface->base,
|
||||
&cairo_analysis_surface_backend,
|
||||
NULL, /* device */
|
||||
CAIRO_CONTENT_COLOR_ALPHA);
|
||||
|
||||
cairo_matrix_init_identity (&surface->ctm);
|
||||
@ -831,9 +841,9 @@ typedef cairo_int_status_t
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_clip_t *clip);
|
||||
@ -906,7 +916,10 @@ _cairo_null_surface_create (cairo_content_t content)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
_cairo_surface_init (surface, &cairo_null_surface_backend, content);
|
||||
_cairo_surface_init (surface,
|
||||
&cairo_null_surface_backend,
|
||||
NULL, /* device */
|
||||
content);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -36,6 +36,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
/**
|
||||
* _cairo_array_init:
|
||||
@ -260,7 +261,7 @@ _cairo_array_append (cairo_array_t *array,
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_append:
|
||||
* _cairo_array_append_multiple:
|
||||
* @array: a #cairo_array_t
|
||||
*
|
||||
* Append one or more items onto the array by growing the array by
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2007 Chris Wilson
|
||||
* Copyright © 2010 Andrea Canciani
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
@ -12,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -32,6 +33,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
* Andrea Canciani <ranma42@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_ATOMIC_PRIVATE_H
|
||||
@ -57,12 +59,29 @@ CAIRO_BEGIN_DECLS
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
static cairo_always_inline cairo_atomic_int_t
|
||||
_cairo_atomic_int_get (cairo_atomic_int_t *x)
|
||||
{
|
||||
__sync_synchronize ();
|
||||
return *x;
|
||||
}
|
||||
|
||||
static cairo_always_inline void *
|
||||
_cairo_atomic_ptr_get (void **x)
|
||||
{
|
||||
__sync_synchronize ();
|
||||
return *x;
|
||||
}
|
||||
#else
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_set(x, value) ((*x) = value)
|
||||
# define _cairo_atomic_ptr_get(x) (*x)
|
||||
#endif
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv)
|
||||
# define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
|
||||
|
||||
#if SIZEOF_VOID_P==SIZEOF_INT
|
||||
typedef int cairo_atomic_intptr_t;
|
||||
@ -75,7 +94,10 @@ typedef long long cairo_atomic_intptr_t;
|
||||
#endif
|
||||
|
||||
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
|
||||
(void*)__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
|
||||
__sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
|
||||
|
||||
# define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
|
||||
_cairo_atomic_intptr_to_voidptr (__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv))
|
||||
|
||||
#endif
|
||||
|
||||
@ -87,11 +109,10 @@ typedef long long cairo_atomic_intptr_t;
|
||||
typedef AO_t cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_get(x) (AO_load_full (x))
|
||||
# define _cairo_atomic_int_set(x, value) (AO_store_full (x))
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) ((cairo_atomic_int_t) AO_compare_and_swap_full(x, oldv, newv) ? oldv : *x)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(x, oldv, newv)
|
||||
|
||||
#if SIZEOF_VOID_P==SIZEOF_INT
|
||||
typedef unsigned int cairo_atomic_intptr_t;
|
||||
@ -103,45 +124,129 @@ typedef unsigned long long cairo_atomic_intptr_t;
|
||||
#error No matching integer pointer type
|
||||
#endif
|
||||
|
||||
# define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x))
|
||||
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
|
||||
(void*) (cairo_atomic_intptr_t) _cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
|
||||
_cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
|
||||
|
||||
#endif
|
||||
|
||||
#if HAVE_OS_ATOMIC_OPS
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#define HAS_ATOMIC_OPS 1
|
||||
|
||||
typedef int32_t cairo_atomic_int_t;
|
||||
|
||||
# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
|
||||
|
||||
# define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x))
|
||||
# define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x)
|
||||
|
||||
#if SIZEOF_VOID_P==4
|
||||
typedef int32_t cairo_atomic_intptr_t;
|
||||
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
|
||||
OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
|
||||
|
||||
#elif SIZEOF_VOID_P==8
|
||||
typedef int64_t cairo_atomic_intptr_t;
|
||||
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
|
||||
OSAtomicCompareAndSwap64Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
|
||||
|
||||
#else
|
||||
#error No matching integer pointer type
|
||||
#endif
|
||||
|
||||
# define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x))
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAS_ATOMIC_OPS
|
||||
|
||||
typedef int cairo_atomic_int_t;
|
||||
#if SIZEOF_VOID_P==SIZEOF_INT
|
||||
typedef unsigned int cairo_atomic_intptr_t;
|
||||
#elif SIZEOF_VOID_P==SIZEOF_LONG
|
||||
typedef unsigned long cairo_atomic_intptr_t;
|
||||
#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
|
||||
typedef unsigned long long cairo_atomic_intptr_t;
|
||||
#else
|
||||
#error No matching integer pointer type
|
||||
#endif
|
||||
|
||||
typedef cairo_atomic_intptr_t cairo_atomic_int_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_inc (int *x);
|
||||
_cairo_atomic_int_inc (cairo_atomic_int_t *x);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x);
|
||||
_cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x);
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
|
||||
cairo_private cairo_atomic_int_t
|
||||
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv);
|
||||
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
|
||||
|
||||
#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_impl (x, oldv, newv)
|
||||
#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_impl (x, oldv, newv)
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
|
||||
# include "cairo-compiler-private.h"
|
||||
|
||||
cairo_private int
|
||||
_cairo_atomic_int_get (int *x);
|
||||
|
||||
cairo_private void
|
||||
_cairo_atomic_int_set (int *x, int value);
|
||||
cairo_private cairo_atomic_int_t
|
||||
_cairo_atomic_int_get (cairo_atomic_int_t *x);
|
||||
# define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x)
|
||||
#else
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_ptr_get(x) (*x)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
# define _cairo_atomic_int_get(x) (*x)
|
||||
# define _cairo_atomic_int_set(x, value) ((*x) = value)
|
||||
/* Workaround GCC complaining about casts */
|
||||
static cairo_always_inline void *
|
||||
_cairo_atomic_intptr_to_voidptr (cairo_atomic_intptr_t x)
|
||||
{
|
||||
return (void *) x;
|
||||
}
|
||||
|
||||
static cairo_always_inline cairo_atomic_int_t
|
||||
_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv)
|
||||
{
|
||||
cairo_atomic_int_t curr;
|
||||
|
||||
do {
|
||||
curr = _cairo_atomic_int_get (x);
|
||||
} while (curr == oldv && !_cairo_atomic_int_cmpxchg (x, oldv, newv));
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
static cairo_always_inline void *
|
||||
_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
|
||||
{
|
||||
void *curr;
|
||||
|
||||
do {
|
||||
curr = _cairo_atomic_ptr_get (x);
|
||||
} while (curr == oldv && !_cairo_atomic_ptr_cmpxchg (x, oldv, newv));
|
||||
|
||||
return curr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _cairo_atomic_int_cmpxchg_return_old
|
||||
#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_fallback (x, oldv, newv)
|
||||
#endif
|
||||
|
||||
#ifndef _cairo_atomic_ptr_cmpxchg_return_old
|
||||
#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_fallback (x, oldv, newv)
|
||||
#endif
|
||||
|
||||
#ifndef _cairo_atomic_int_cmpxchg
|
||||
#define _cairo_atomic_int_cmpxchg(x, oldv, newv) (_cairo_atomic_int_cmpxchg_return_old (x, oldv, newv) == oldv)
|
||||
#endif
|
||||
|
||||
#ifndef _cairo_atomic_ptr_cmpxchg
|
||||
#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) (_cairo_atomic_ptr_cmpxchg_return_old (x, oldv, newv) == oldv)
|
||||
#endif
|
||||
|
||||
#define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x)
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -42,7 +42,7 @@ COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) ||
|
||||
sizeof(void*) == sizeof(long long));
|
||||
#else
|
||||
void
|
||||
_cairo_atomic_int_inc (int *x)
|
||||
_cairo_atomic_int_inc (cairo_atomic_intptr_t *x)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x += 1;
|
||||
@ -50,7 +50,7 @@ _cairo_atomic_int_inc (int *x)
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_atomic_int_dec_and_test (int *x)
|
||||
_cairo_atomic_int_dec_and_test (cairo_atomic_intptr_t *x)
|
||||
{
|
||||
cairo_bool_t ret;
|
||||
|
||||
@ -61,10 +61,10 @@ _cairo_atomic_int_dec_and_test (int *x)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
|
||||
cairo_atomic_intptr_t
|
||||
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t oldv, cairo_atomic_intptr_t newv)
|
||||
{
|
||||
int ret;
|
||||
cairo_atomic_intptr_t ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
@ -76,7 +76,7 @@ _cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
|
||||
}
|
||||
|
||||
void *
|
||||
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
|
||||
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
@ -88,13 +88,12 @@ _cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
int
|
||||
_cairo_atomic_int_get (int *x)
|
||||
cairo_atomic_intptr_t
|
||||
_cairo_atomic_int_get (cairo_atomic_intptr_t *x)
|
||||
{
|
||||
int ret;
|
||||
cairo_atomic_intptr_t ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
@ -102,12 +101,6 @@ _cairo_atomic_int_get (int *x)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_atomic_int_set (int *x, int value)
|
||||
{
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
*x = value;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -37,6 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct _cairo_base64_stream {
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
|
||||
typedef struct _cairo_base85_stream {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -38,7 +38,9 @@
|
||||
/* Provide definitions for standalone compilation */
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-boxes-private.h"
|
||||
#include "cairo-combsort-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
typedef struct _cairo_bo_edge cairo_bo_edge_t;
|
||||
typedef struct _cairo_bo_trap cairo_bo_trap_t;
|
||||
@ -215,20 +217,33 @@ edges_collinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
|
||||
static cairo_status_t
|
||||
_cairo_bo_edge_end_trap (cairo_bo_edge_t *left,
|
||||
int32_t bot,
|
||||
cairo_traps_t *traps)
|
||||
cairo_bool_t do_traps,
|
||||
void *container)
|
||||
{
|
||||
cairo_bo_trap_t *trap = &left->deferred_trap;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* Only emit (trivial) non-degenerate trapezoids with positive height. */
|
||||
if (likely (trap->top < bot)) {
|
||||
_cairo_traps_add_trap (traps,
|
||||
trap->top, bot,
|
||||
&left->edge.line, &trap->right->edge.line);
|
||||
if (do_traps) {
|
||||
_cairo_traps_add_trap (container,
|
||||
trap->top, bot,
|
||||
&left->edge.line, &trap->right->edge.line);
|
||||
status = _cairo_traps_status ((cairo_traps_t *) container);
|
||||
} else {
|
||||
cairo_box_t box;
|
||||
|
||||
box.p1.x = left->edge.line.p1.x;
|
||||
box.p1.y = trap->top;
|
||||
box.p2.x = trap->right->edge.line.p1.x;
|
||||
box.p2.y = bot;
|
||||
status = _cairo_boxes_add (container, &box);
|
||||
}
|
||||
}
|
||||
|
||||
trap->right = NULL;
|
||||
|
||||
return _cairo_traps_status (traps);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Start a new trapezoid at the given top y coordinate, whose edges
|
||||
@ -240,7 +255,8 @@ static inline cairo_status_t
|
||||
_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *left,
|
||||
cairo_bo_edge_t *right,
|
||||
int top,
|
||||
cairo_traps_t *traps)
|
||||
cairo_bool_t do_traps,
|
||||
void *container)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
@ -255,7 +271,7 @@ _cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *left,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = _cairo_bo_edge_end_trap (left, top, traps);
|
||||
status = _cairo_bo_edge_end_trap (left, top, do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
@ -272,7 +288,8 @@ static inline cairo_status_t
|
||||
_active_edges_to_traps (cairo_bo_edge_t *left,
|
||||
int32_t top,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_traps_t *traps)
|
||||
cairo_bool_t do_traps,
|
||||
void *container)
|
||||
{
|
||||
cairo_bo_edge_t *right;
|
||||
cairo_status_t status;
|
||||
@ -303,7 +320,7 @@ _active_edges_to_traps (cairo_bo_edge_t *left,
|
||||
right = left->next;
|
||||
while (right != NULL) {
|
||||
if (right->deferred_trap.right != NULL) {
|
||||
status = _cairo_bo_edge_end_trap (right, top, traps);
|
||||
status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
@ -321,8 +338,8 @@ _active_edges_to_traps (cairo_bo_edge_t *left,
|
||||
right = right->next;
|
||||
}
|
||||
|
||||
status = _cairo_bo_edge_start_or_continue_trap (left, right,
|
||||
top, traps);
|
||||
status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
|
||||
do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -337,7 +354,7 @@ _active_edges_to_traps (cairo_bo_edge_t *left,
|
||||
right = left->next;
|
||||
while (right != NULL) {
|
||||
if (right->deferred_trap.right != NULL) {
|
||||
status = _cairo_bo_edge_end_trap (right, top, traps);
|
||||
status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
@ -358,8 +375,8 @@ _active_edges_to_traps (cairo_bo_edge_t *left,
|
||||
right = right->next;
|
||||
}
|
||||
|
||||
status = _cairo_bo_edge_start_or_continue_trap (left, right,
|
||||
top, traps);
|
||||
status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
|
||||
do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -376,7 +393,8 @@ static cairo_status_t
|
||||
_cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t **start_events,
|
||||
int num_events,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_traps_t *traps)
|
||||
cairo_bool_t do_traps,
|
||||
void *container)
|
||||
{
|
||||
cairo_bo_sweep_line_t sweep_line;
|
||||
cairo_bo_event_t *event;
|
||||
@ -388,7 +406,7 @@ _cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t **start_events
|
||||
if (event->point.y != sweep_line.current_y) {
|
||||
status = _active_edges_to_traps (sweep_line.head,
|
||||
sweep_line.current_y,
|
||||
fill_rule, traps);
|
||||
fill_rule, do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -406,7 +424,7 @@ _cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t **start_events
|
||||
if (event->edge->deferred_trap.right != NULL) {
|
||||
status = _cairo_bo_edge_end_trap (event->edge,
|
||||
sweep_line.current_y,
|
||||
traps);
|
||||
do_traps, container);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
@ -476,7 +494,8 @@ _cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t *traps,
|
||||
}
|
||||
|
||||
status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
|
||||
fill_rule, traps);
|
||||
fill_rule,
|
||||
TRUE, traps);
|
||||
if (events != stack_events)
|
||||
free (events);
|
||||
|
||||
@ -485,6 +504,72 @@ _cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t *traps,
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (const cairo_polygon_t *polygon,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_boxes_t *boxes)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)];
|
||||
cairo_bo_event_t *events;
|
||||
cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
|
||||
cairo_bo_event_t **event_ptrs;
|
||||
cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)];
|
||||
cairo_bo_edge_t *edges;
|
||||
int num_events;
|
||||
int i, j;
|
||||
|
||||
if (unlikely (polygon->num_edges == 0))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
num_events = 2 * polygon->num_edges;
|
||||
|
||||
events = stack_events;
|
||||
event_ptrs = stack_event_ptrs;
|
||||
edges = stack_edges;
|
||||
if (num_events > ARRAY_LENGTH (stack_events)) {
|
||||
events = _cairo_malloc_ab_plus_c (num_events,
|
||||
sizeof (cairo_bo_event_t) +
|
||||
sizeof (cairo_bo_edge_t) +
|
||||
sizeof (cairo_bo_event_t *),
|
||||
sizeof (cairo_bo_event_t *));
|
||||
if (unlikely (events == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
event_ptrs = (cairo_bo_event_t **) (events + num_events);
|
||||
edges = (cairo_bo_edge_t *) (event_ptrs + num_events + 1);
|
||||
}
|
||||
|
||||
for (i = j = 0; i < polygon->num_edges; i++) {
|
||||
edges[i].edge = polygon->edges[i];
|
||||
edges[i].deferred_trap.right = NULL;
|
||||
edges[i].prev = NULL;
|
||||
edges[i].next = NULL;
|
||||
|
||||
event_ptrs[j] = &events[j];
|
||||
events[j].type = CAIRO_BO_EVENT_TYPE_START;
|
||||
events[j].point.y = polygon->edges[i].top;
|
||||
events[j].point.x = polygon->edges[i].line.p1.x;
|
||||
events[j].edge = &edges[i];
|
||||
j++;
|
||||
|
||||
event_ptrs[j] = &events[j];
|
||||
events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
|
||||
events[j].point.y = polygon->edges[i].bottom;
|
||||
events[j].point.x = polygon->edges[i].line.p1.x;
|
||||
events[j].edge = &edges[i];
|
||||
j++;
|
||||
}
|
||||
|
||||
status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
|
||||
fill_rule,
|
||||
FALSE, boxes);
|
||||
if (events != stack_events)
|
||||
free (events);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps,
|
||||
cairo_fill_rule_t fill_rule)
|
||||
@ -572,7 +657,7 @@ _cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps,
|
||||
_cairo_traps_clear (traps);
|
||||
status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
|
||||
fill_rule,
|
||||
traps);
|
||||
TRUE, traps);
|
||||
traps->is_rectilinear = TRUE;
|
||||
|
||||
if (events != stack_events)
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -38,6 +38,7 @@
|
||||
/* Provide definitions for standalone compilation */
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-freelist-private.h"
|
||||
#include "cairo-combsort-private.h"
|
||||
|
||||
@ -129,21 +130,25 @@ static void
|
||||
dump_traps (cairo_traps_t *traps, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
cairo_box_t extents;
|
||||
int n;
|
||||
|
||||
if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if (traps->has_limits) {
|
||||
printf ("%s: limits=(%d, %d, %d, %d)\n",
|
||||
filename,
|
||||
traps->limits.p1.x, traps->limits.p1.y,
|
||||
traps->limits.p2.x, traps->limits.p2.y);
|
||||
}
|
||||
#endif
|
||||
_cairo_traps_extents (traps, &extents);
|
||||
printf ("%s: extents=(%d, %d, %d, %d)\n",
|
||||
filename,
|
||||
traps->extents.p1.x, traps->extents.p1.y,
|
||||
traps->extents.p2.x, traps->extents.p2.y);
|
||||
extents.p1.x, extents.p1.y,
|
||||
extents.p2.x, extents.p2.y);
|
||||
|
||||
file = fopen (filename, "a");
|
||||
if (file != NULL) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
2199
gfx/cairo/cairo/src/cairo-botor-scan-converter.c
Normal file
2199
gfx/cairo/cairo/src/cairo-botor-scan-converter.c
Normal file
File diff suppressed because it is too large
Load Diff
84
gfx/cairo/cairo/src/cairo-boxes-private.h
Normal file
84
gfx/cairo/cairo/src/cairo-boxes-private.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_BOXES_H
|
||||
#define CAIRO_BOXES_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
struct _cairo_boxes_t {
|
||||
cairo_status_t status;
|
||||
cairo_box_t limit;
|
||||
const cairo_box_t *limits;
|
||||
int num_limits;
|
||||
int num_boxes;
|
||||
unsigned int is_pixel_aligned : 1;
|
||||
|
||||
struct _cairo_boxes_chunk {
|
||||
struct _cairo_boxes_chunk *next;
|
||||
cairo_box_t *base;
|
||||
int count;
|
||||
int size;
|
||||
} chunks, *tail;
|
||||
cairo_box_t boxes_embedded[32];
|
||||
};
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_init (cairo_boxes_t *boxes);
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
|
||||
cairo_box_t *array,
|
||||
int num_boxes);
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_limit (cairo_boxes_t *boxes,
|
||||
const cairo_box_t *limits,
|
||||
int num_limits);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_boxes_add (cairo_boxes_t *boxes,
|
||||
const cairo_box_t *box);
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_extents (const cairo_boxes_t *boxes,
|
||||
cairo_rectangle_int_t *extents);
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_clear (cairo_boxes_t *boxes);
|
||||
|
||||
cairo_private void
|
||||
_cairo_boxes_fini (cairo_boxes_t *boxes);
|
||||
|
||||
#endif /* CAIRO_BOXES_H */
|
300
gfx/cairo/cairo/src/cairo-boxes.c
Normal file
300
gfx/cairo/cairo/src/cairo-boxes.c
Normal file
@ -0,0 +1,300 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-boxes-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
void
|
||||
_cairo_boxes_init (cairo_boxes_t *boxes)
|
||||
{
|
||||
boxes->status = CAIRO_STATUS_SUCCESS;
|
||||
boxes->num_limits = 0;
|
||||
boxes->num_boxes = 0;
|
||||
|
||||
boxes->tail = &boxes->chunks;
|
||||
boxes->chunks.next = NULL;
|
||||
boxes->chunks.base = boxes->boxes_embedded;
|
||||
boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
|
||||
boxes->chunks.count = 0;
|
||||
|
||||
boxes->is_pixel_aligned = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
|
||||
cairo_box_t *array,
|
||||
int num_boxes)
|
||||
{
|
||||
int n;
|
||||
|
||||
boxes->status = CAIRO_STATUS_SUCCESS;
|
||||
boxes->num_limits = 0;
|
||||
boxes->num_boxes = num_boxes;
|
||||
|
||||
boxes->tail = &boxes->chunks;
|
||||
boxes->chunks.next = NULL;
|
||||
boxes->chunks.base = array;
|
||||
boxes->chunks.size = num_boxes;
|
||||
boxes->chunks.count = num_boxes;
|
||||
|
||||
for (n = 0; n < num_boxes; n++) {
|
||||
if (! _cairo_fixed_is_integer (array[n].p1.x) ||
|
||||
! _cairo_fixed_is_integer (array[n].p1.y) ||
|
||||
! _cairo_fixed_is_integer (array[n].p2.x) ||
|
||||
! _cairo_fixed_is_integer (array[n].p2.y))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boxes->is_pixel_aligned = n == num_boxes;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_boxes_limit (cairo_boxes_t *boxes,
|
||||
const cairo_box_t *limits,
|
||||
int num_limits)
|
||||
{
|
||||
int n;
|
||||
|
||||
boxes->limits = limits;
|
||||
boxes->num_limits = num_limits;
|
||||
|
||||
if (boxes->num_limits) {
|
||||
boxes->limit = limits[0];
|
||||
for (n = 1; n < num_limits; n++) {
|
||||
if (limits[n].p1.x < boxes->limit.p1.x)
|
||||
boxes->limit.p1.x = limits[n].p1.x;
|
||||
|
||||
if (limits[n].p1.y < boxes->limit.p1.y)
|
||||
boxes->limit.p1.y = limits[n].p1.y;
|
||||
|
||||
if (limits[n].p2.x > boxes->limit.p2.x)
|
||||
boxes->limit.p2.x = limits[n].p2.x;
|
||||
|
||||
if (limits[n].p2.y > boxes->limit.p2.y)
|
||||
boxes->limit.p2.y = limits[n].p2.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_boxes_add_internal (cairo_boxes_t *boxes,
|
||||
const cairo_box_t *box)
|
||||
{
|
||||
struct _cairo_boxes_chunk *chunk;
|
||||
|
||||
if (unlikely (boxes->status))
|
||||
return;
|
||||
|
||||
chunk = boxes->tail;
|
||||
if (unlikely (chunk->count == chunk->size)) {
|
||||
int size;
|
||||
|
||||
size = chunk->size * 2;
|
||||
chunk->next = _cairo_malloc_ab_plus_c (size,
|
||||
sizeof (cairo_box_t),
|
||||
sizeof (struct _cairo_boxes_chunk));
|
||||
|
||||
if (unlikely (chunk->next == NULL)) {
|
||||
boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
chunk = chunk->next;
|
||||
boxes->tail = chunk;
|
||||
|
||||
chunk->next = NULL;
|
||||
chunk->count = 0;
|
||||
chunk->size = size;
|
||||
chunk->base = (cairo_box_t *) (chunk + 1);
|
||||
}
|
||||
|
||||
chunk->base[chunk->count++] = *box;
|
||||
boxes->num_boxes++;
|
||||
|
||||
if (boxes->is_pixel_aligned) {
|
||||
boxes->is_pixel_aligned =
|
||||
_cairo_fixed_is_integer (box->p1.x) &&
|
||||
_cairo_fixed_is_integer (box->p1.y) &&
|
||||
_cairo_fixed_is_integer (box->p2.x) &&
|
||||
_cairo_fixed_is_integer (box->p2.y);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_boxes_add (cairo_boxes_t *boxes,
|
||||
const cairo_box_t *box)
|
||||
{
|
||||
if (box->p1.y == box->p2.y)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (box->p1.x == box->p2.x)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (boxes->num_limits) {
|
||||
cairo_point_t p1, p2;
|
||||
cairo_bool_t reversed = FALSE;
|
||||
int n;
|
||||
|
||||
/* support counter-clockwise winding for rectangular tessellation */
|
||||
if (box->p1.x < box->p2.x) {
|
||||
p1.x = box->p1.x;
|
||||
p2.x = box->p2.x;
|
||||
} else {
|
||||
p2.x = box->p1.x;
|
||||
p1.x = box->p2.x;
|
||||
reversed = ! reversed;
|
||||
}
|
||||
|
||||
if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (box->p1.y < box->p2.y) {
|
||||
p1.y = box->p1.y;
|
||||
p2.y = box->p2.y;
|
||||
} else {
|
||||
p2.y = box->p1.y;
|
||||
p1.y = box->p2.y;
|
||||
reversed = ! reversed;
|
||||
}
|
||||
|
||||
if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
for (n = 0; n < boxes->num_limits; n++) {
|
||||
const cairo_box_t *limits = &boxes->limits[n];
|
||||
cairo_box_t _box;
|
||||
cairo_point_t _p1, _p2;
|
||||
|
||||
if (p1.x >= limits->p2.x || p2.x <= limits->p1.x)
|
||||
continue;
|
||||
if (p1.y >= limits->p2.y || p2.y <= limits->p1.y)
|
||||
continue;
|
||||
|
||||
/* Otherwise, clip the box to the limits. */
|
||||
_p1 = p1;
|
||||
if (_p1.x < limits->p1.x)
|
||||
_p1.x = limits->p1.x;
|
||||
if (_p1.y < limits->p1.y)
|
||||
_p1.y = limits->p1.y;
|
||||
|
||||
_p2 = p2;
|
||||
if (_p2.x > limits->p2.x)
|
||||
_p2.x = limits->p2.x;
|
||||
if (_p2.y > limits->p2.y)
|
||||
_p2.y = limits->p2.y;
|
||||
|
||||
if (_p2.y <= _p1.y || _p2.x <= _p1.x)
|
||||
continue;
|
||||
|
||||
_box.p1.y = _p1.y;
|
||||
_box.p2.y = _p2.y;
|
||||
if (reversed) {
|
||||
_box.p1.x = _p2.x;
|
||||
_box.p2.x = _p1.x;
|
||||
} else {
|
||||
_box.p1.x = _p1.x;
|
||||
_box.p2.x = _p2.x;
|
||||
}
|
||||
|
||||
_cairo_boxes_add_internal (boxes, &_box);
|
||||
}
|
||||
} else {
|
||||
_cairo_boxes_add_internal (boxes, box);
|
||||
}
|
||||
|
||||
return boxes->status;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_boxes_extents (const cairo_boxes_t *boxes,
|
||||
cairo_rectangle_int_t *extents)
|
||||
{
|
||||
const struct _cairo_boxes_chunk *chunk;
|
||||
cairo_box_t box;
|
||||
int i;
|
||||
|
||||
box.p1.y = box.p1.x = INT_MAX;
|
||||
box.p2.y = box.p2.x = INT_MIN;
|
||||
|
||||
for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
|
||||
const cairo_box_t *b = chunk->base;
|
||||
for (i = 0; i < chunk->count; i++) {
|
||||
if (b[i].p1.x < box.p1.x)
|
||||
box.p1.x = b[i].p1.x;
|
||||
|
||||
if (b[i].p1.y < box.p1.y)
|
||||
box.p1.y = b[i].p1.y;
|
||||
|
||||
if (b[i].p2.x > box.p2.x)
|
||||
box.p2.x = b[i].p2.x;
|
||||
|
||||
if (b[i].p2.y > box.p2.y)
|
||||
box.p2.y = b[i].p2.y;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_box_round_to_rectangle (&box, extents);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_boxes_clear (cairo_boxes_t *boxes)
|
||||
{
|
||||
struct _cairo_boxes_chunk *chunk, *next;
|
||||
|
||||
for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
|
||||
next = chunk->next;
|
||||
free (chunk);
|
||||
}
|
||||
|
||||
boxes->tail = &boxes->chunks;
|
||||
boxes->chunks.next = 0;
|
||||
boxes->chunks.count = 0;
|
||||
boxes->num_boxes = 0;
|
||||
|
||||
boxes->is_pixel_aligned = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_boxes_fini (cairo_boxes_t *boxes)
|
||||
{
|
||||
struct _cairo_boxes_chunk *chunk, *next;
|
||||
|
||||
for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
|
||||
next = chunk->next;
|
||||
free (chunk);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -37,6 +37,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
static void
|
||||
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
|
||||
@ -174,9 +175,7 @@ _cairo_cache_thaw (cairo_cache_t *cache)
|
||||
{
|
||||
assert (cache->freeze_count > 0);
|
||||
|
||||
cache->freeze_count--;
|
||||
|
||||
if (cache->freeze_count == 0)
|
||||
if (--cache->freeze_count == 0)
|
||||
_cairo_cache_shrink_to_accommodate (cache, 0);
|
||||
}
|
||||
|
||||
@ -240,9 +239,6 @@ static void
|
||||
_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
|
||||
unsigned long additional)
|
||||
{
|
||||
if (cache->freeze_count)
|
||||
return;
|
||||
|
||||
while (cache->size + additional > cache->max_size) {
|
||||
if (! _cairo_cache_remove_random (cache))
|
||||
return;
|
||||
@ -267,7 +263,8 @@ _cairo_cache_insert (cairo_cache_t *cache,
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_cache_shrink_to_accommodate (cache, entry->size);
|
||||
if (entry->size && ! cache->freeze_count)
|
||||
_cairo_cache_shrink_to_accommodate (cache, entry->size);
|
||||
|
||||
status = _cairo_hash_table_insert (cache->hash_table,
|
||||
(cairo_hash_entry_t *) entry);
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -41,6 +41,7 @@
|
||||
|
||||
#define _BSD_SOURCE /* for snprintf(), strdup() */
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
#if CAIRO_HAS_FONT_SUBSET
|
||||
|
||||
@ -117,6 +118,7 @@ typedef struct _cairo_cff_font {
|
||||
cairo_array_t local_sub_index;
|
||||
int num_glyphs;
|
||||
cairo_bool_t is_cid;
|
||||
int units_per_em;
|
||||
|
||||
/* CID Font Data */
|
||||
int *fdselect;
|
||||
@ -1772,6 +1774,9 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
|
||||
font->y_max = (int16_t) be16_to_cpu (head.y_max);
|
||||
font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
|
||||
font->descent = (int16_t) be16_to_cpu (hhea.descender);
|
||||
font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
|
||||
if (font->units_per_em == 0)
|
||||
font->units_per_em = 1000;
|
||||
|
||||
font->font_name = NULL;
|
||||
status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
|
||||
@ -1955,20 +1960,20 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
||||
cff_subset->font_name = NULL;
|
||||
}
|
||||
|
||||
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
|
||||
if (unlikely (cff_subset->widths == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
cff_subset->widths[i] = font->widths[i];
|
||||
cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
|
||||
|
||||
cff_subset->x_min = font->x_min;
|
||||
cff_subset->y_min = font->y_min;
|
||||
cff_subset->x_max = font->x_max;
|
||||
cff_subset->y_max = font->y_max;
|
||||
cff_subset->ascent = font->ascent;
|
||||
cff_subset->descent = font->descent;
|
||||
cff_subset->x_min = (double)font->x_min/font->units_per_em;
|
||||
cff_subset->y_min = (double)font->y_min/font->units_per_em;
|
||||
cff_subset->x_max = (double)font->x_max/font->units_per_em;
|
||||
cff_subset->y_max = (double)font->y_max/font->units_per_em;
|
||||
cff_subset->ascent = (double)font->ascent/font->units_per_em;
|
||||
cff_subset->descent = (double)font->descent/font->units_per_em;
|
||||
|
||||
cff_subset->data = malloc (length);
|
||||
if (unlikely (cff_subset->data == NULL)) {
|
||||
@ -2212,21 +2217,21 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
|
||||
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
|
||||
if (unlikely (cff_subset->widths == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
|
||||
cff_subset->widths[i] = type2_subset.widths[i];
|
||||
cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
|
||||
|
||||
cff_subset->x_min = type2_subset.x_min;
|
||||
cff_subset->y_min = type2_subset.y_min;
|
||||
cff_subset->x_max = type2_subset.x_max;
|
||||
cff_subset->y_max = type2_subset.y_max;
|
||||
cff_subset->ascent = type2_subset.y_max;
|
||||
cff_subset->descent = type2_subset.y_min;
|
||||
cff_subset->x_min = (double)type2_subset.x_min/1000;
|
||||
cff_subset->y_min = (double)type2_subset.y_min/1000;
|
||||
cff_subset->x_max = (double)type2_subset.x_max/1000;
|
||||
cff_subset->y_max = (double)type2_subset.y_max/1000;
|
||||
cff_subset->ascent = (double)type2_subset.y_max/1000;
|
||||
cff_subset->descent = (double)type2_subset.y_min/1000;
|
||||
|
||||
cff_subset->data = malloc (length);
|
||||
if (unlikely (cff_subset->data == NULL)) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -76,10 +76,6 @@ struct _cairo_clip {
|
||||
cairo_private void
|
||||
_cairo_clip_init (cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_init_rectangle (cairo_clip_t *clip,
|
||||
const cairo_rectangle_int_t *rect);
|
||||
|
||||
cairo_private_no_warn cairo_clip_t *
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
|
||||
|
||||
@ -91,6 +87,10 @@ _cairo_clip_init_copy_transformed (cairo_clip_t *clip,
|
||||
cairo_private void
|
||||
_cairo_clip_reset (cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_equal (const cairo_clip_t *clip_a,
|
||||
const cairo_clip_t *clip_b);
|
||||
|
||||
#define _cairo_clip_fini(clip) _cairo_clip_reset (clip)
|
||||
|
||||
cairo_private cairo_status_t
|
||||
@ -112,12 +112,12 @@ cairo_private const cairo_rectangle_int_t *
|
||||
_cairo_clip_get_extents (const cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
|
||||
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
int dst_x, int dst_y);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_clip_get_region (cairo_clip_t *clip,
|
||||
@ -128,6 +128,20 @@ _cairo_clip_get_boxes (cairo_clip_t *clip,
|
||||
cairo_box_t **boxes,
|
||||
int *count);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_clip_to_boxes (cairo_clip_t **clip,
|
||||
cairo_composite_rectangles_t *extents,
|
||||
cairo_box_t **boxes,
|
||||
int *num_boxes);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
|
||||
const cairo_rectangle_int_t *rect);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_clip_contains_extents (cairo_clip_t *clip,
|
||||
const cairo_composite_rectangles_t *extents);
|
||||
|
||||
cairo_private void
|
||||
_cairo_clip_drop_cache (cairo_clip_t *clip);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -41,95 +41,16 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-clip-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-freed-pool-private.h"
|
||||
#include "cairo-gstate-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-composite-rectangles-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
|
||||
/* Keep a stash of recently freed clip_paths, since we need to
|
||||
* reallocate them frequently.
|
||||
*/
|
||||
#define MAX_FREED_POOL_SIZE 4
|
||||
typedef struct {
|
||||
void *pool[MAX_FREED_POOL_SIZE];
|
||||
int top;
|
||||
} freed_pool_t;
|
||||
|
||||
#if HAS_FREED_POOL
|
||||
static freed_pool_t clip_path_pool;
|
||||
|
||||
static void *
|
||||
_atomic_fetch (void **slot)
|
||||
{
|
||||
return _cairo_atomic_ptr_cmpxchg (slot, *slot, NULL);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_atomic_store (void **slot, void *ptr)
|
||||
{
|
||||
return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr) == NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_freed_pool_get (freed_pool_t *pool)
|
||||
{
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
i = pool->top - 1;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (ptr != NULL) {
|
||||
pool->top = i;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* either empty or contended */
|
||||
for (i = ARRAY_LENGTH (pool->pool); i--;) {
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (ptr != NULL) {
|
||||
pool->top = i;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* empty */
|
||||
pool->top = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_freed_pool_put (freed_pool_t *pool, void *ptr)
|
||||
{
|
||||
int i = pool->top;
|
||||
|
||||
if (_atomic_store (&pool->pool[i], ptr)) {
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* either full or contended */
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
if (_atomic_store (&pool->pool[i], ptr)) {
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* full */
|
||||
pool->top = ARRAY_LENGTH (pool->pool);
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
_freed_pool_reset (freed_pool_t *pool)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
free (pool->pool[i]);
|
||||
pool->pool[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_clip_path_t *
|
||||
_cairo_clip_path_create (cairo_clip_t *clip)
|
||||
@ -158,9 +79,6 @@ _cairo_clip_path_create (cairo_clip_t *clip)
|
||||
static cairo_clip_path_t *
|
||||
_cairo_clip_path_reference (cairo_clip_path_t *clip_path)
|
||||
{
|
||||
if (clip_path == NULL)
|
||||
return NULL;
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
|
||||
|
||||
_cairo_reference_count_inc (&clip_path->ref_count);
|
||||
@ -247,47 +165,40 @@ _cairo_clip_intersect_rectangle (cairo_clip_t *clip,
|
||||
status = _cairo_path_fixed_close_path (&clip_path->path);
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
clip_path->extents = *rect;
|
||||
clip_path->fill_rule = CAIRO_FILL_RULE_WINDING;
|
||||
clip_path->tolerance = 1;
|
||||
clip_path->antialias = CAIRO_ANTIALIAS_NONE;
|
||||
clip_path->antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
|
||||
|
||||
clip_path->extents = *rect;
|
||||
if (clip_path->prev != NULL) {
|
||||
if (! _cairo_rectangle_intersect (&clip_path->extents,
|
||||
&clip_path->prev->extents))
|
||||
{
|
||||
_cairo_clip_set_all_clipped (clip);
|
||||
}
|
||||
}
|
||||
|
||||
/* could preallocate the region if it proves worthwhile */
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX consider accepting a matrix, no users yet. */
|
||||
cairo_status_t
|
||||
_cairo_clip_init_rectangle (cairo_clip_t *clip,
|
||||
const cairo_rectangle_int_t *rect)
|
||||
{
|
||||
_cairo_clip_init (clip);
|
||||
|
||||
if (rect == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (rect->width == 0 || rect->height == 0) {
|
||||
_cairo_clip_set_all_clipped (clip);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return _cairo_clip_intersect_rectangle (clip, rect);
|
||||
}
|
||||
|
||||
cairo_clip_t *
|
||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
||||
{
|
||||
if (other != NULL) {
|
||||
clip->all_clipped = other->all_clipped;
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
|
||||
/* this guy is here because of the weird return semantics of _cairo_clip_init_copy */
|
||||
if (!other->path)
|
||||
return NULL;
|
||||
if (other->path == NULL) {
|
||||
clip->path = NULL;
|
||||
if (! clip->all_clipped)
|
||||
clip = NULL;
|
||||
} else {
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
}
|
||||
} else {
|
||||
_cairo_clip_init (clip);
|
||||
clip = NULL;
|
||||
}
|
||||
|
||||
return clip;
|
||||
@ -318,9 +229,8 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
|
||||
|
||||
if (clip->path != NULL) {
|
||||
if (clip->path->fill_rule == fill_rule &&
|
||||
(path->is_rectilinear ||
|
||||
(tolerance == clip->path->tolerance &&
|
||||
antialias == clip->path->antialias)) &&
|
||||
(path->is_rectilinear || tolerance == clip->path->tolerance) &&
|
||||
antialias == clip->path->antialias &&
|
||||
_cairo_path_fixed_equal (&clip->path->path, path))
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -372,6 +282,38 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_clip_equal (const cairo_clip_t *clip_a,
|
||||
const cairo_clip_t *clip_b)
|
||||
{
|
||||
const cairo_clip_path_t *clip_path_a, *clip_path_b;
|
||||
|
||||
clip_path_a = clip_a->path;
|
||||
clip_path_b = clip_b->path;
|
||||
|
||||
while (clip_path_a && clip_path_b) {
|
||||
if (clip_path_a == clip_path_b)
|
||||
return TRUE;
|
||||
|
||||
if (clip_path_a->fill_rule != clip_path_b->fill_rule)
|
||||
return FALSE;
|
||||
|
||||
if (clip_path_a->tolerance != clip_path_b->tolerance)
|
||||
return FALSE;
|
||||
|
||||
if (clip_path_a->antialias != clip_path_b->antialias)
|
||||
return FALSE;
|
||||
|
||||
if (! _cairo_path_fixed_equal (&clip_path_a->path, &clip_path_b->path))
|
||||
return FALSE;
|
||||
|
||||
clip_path_a = clip_path_a->prev;
|
||||
clip_path_b = clip_path_b->prev;
|
||||
}
|
||||
|
||||
return clip_path_a == clip_path_b; /* ie both NULL */
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_clip (cairo_clip_t *clip,
|
||||
const cairo_path_fixed_t *path,
|
||||
@ -409,7 +351,7 @@ _cairo_clip_rectangle (cairo_clip_t *clip,
|
||||
if (clip->path != NULL) {
|
||||
if (rectangle->x <= clip->path->extents.x &&
|
||||
rectangle->y <= clip->path->extents.y &&
|
||||
rectangle->x + rectangle->width >= clip->path->extents.x + clip->path->extents.width &&
|
||||
rectangle->x + rectangle->width >= clip->path->extents.x + clip->path->extents.width &&
|
||||
rectangle->y + rectangle->height >= clip->path->extents.y + clip->path->extents.height)
|
||||
{
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -443,6 +385,7 @@ _cairo_clip_path_reapply_clip_path_transform (cairo_clip_t *clip,
|
||||
status = _cairo_path_fixed_init_copy (&clip_path->path,
|
||||
&other_path->path);
|
||||
if (unlikely (status)) {
|
||||
clip->path = clip->path->prev;
|
||||
_cairo_clip_path_destroy (clip_path);
|
||||
return status;
|
||||
}
|
||||
@ -485,6 +428,7 @@ _cairo_clip_path_reapply_clip_path_translate (cairo_clip_t *clip,
|
||||
status = _cairo_path_fixed_init_copy (&clip_path->path,
|
||||
&other_path->path);
|
||||
if (unlikely (status)) {
|
||||
clip->path = clip->path->prev;
|
||||
_cairo_clip_path_destroy (clip_path);
|
||||
return status;
|
||||
}
|
||||
@ -500,6 +444,13 @@ _cairo_clip_path_reapply_clip_path_translate (cairo_clip_t *clip,
|
||||
clip_path->flags = other_path->flags;
|
||||
if (other_path->region != NULL) {
|
||||
clip_path->region = cairo_region_copy (other_path->region);
|
||||
status = clip_path->region->status;
|
||||
if (unlikely (status)) {
|
||||
clip->path = clip->path->prev;
|
||||
_cairo_clip_path_destroy (clip_path);
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_region_translate (clip_path->region, tx, ty);
|
||||
}
|
||||
clip_path->surface = cairo_surface_reference (other_path->surface);
|
||||
@ -997,104 +948,73 @@ _cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_combine_region (cairo_surface_t *surface,
|
||||
const cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
{
|
||||
cairo_region_t clear_region;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_region_init_rectangle (&clear_region, extents);
|
||||
status = cairo_region_subtract (&clear_region, region);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (! cairo_region_is_empty (&clear_region)) {
|
||||
cairo_region_translate (&clear_region, -extents->x, -extents->y);
|
||||
status = _cairo_surface_fill_region (surface,
|
||||
CAIRO_OPERATOR_CLEAR,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
&clear_region);
|
||||
}
|
||||
_cairo_region_fini (&clear_region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
cairo_surface_t *target)
|
||||
cairo_surface_t *target,
|
||||
int *tx, int *ty)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status;
|
||||
const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
|
||||
cairo_clip_path_t *prev;
|
||||
cairo_bool_t need_translate;
|
||||
cairo_surface_t *surface;
|
||||
cairo_clip_path_t *prev;
|
||||
cairo_status_t status;
|
||||
|
||||
while (clip_path->prev != NULL &&
|
||||
clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
|
||||
clip_path->path.maybe_fill_region)
|
||||
{
|
||||
clip_path = clip_path->prev;
|
||||
}
|
||||
|
||||
clip_extents = &clip_path->extents;
|
||||
if (clip_path->surface != NULL &&
|
||||
clip_path->surface->backend == target->backend)
|
||||
{
|
||||
return cairo_surface_reference (clip_path->surface);
|
||||
*tx = clip_extents->x;
|
||||
*ty = clip_extents->y;
|
||||
return clip_path->surface;
|
||||
}
|
||||
|
||||
surface = _cairo_surface_create_similar_solid (target,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
clip_extents->width,
|
||||
clip_extents->height,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
FALSE);
|
||||
surface = _cairo_surface_create_similar_scratch (target,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
clip_extents->width,
|
||||
clip_extents->height);
|
||||
if (surface == NULL) {
|
||||
if (clip_path->surface != NULL &&
|
||||
clip_path->surface->backend == &_cairo_image_surface_backend)
|
||||
{
|
||||
return cairo_surface_reference (clip_path->surface);
|
||||
}
|
||||
|
||||
surface =
|
||||
_cairo_image_surface_create_with_content (CAIRO_CONTENT_ALPHA,
|
||||
clip_extents->width,
|
||||
clip_extents->height);
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
|
||||
clip_extents->width,
|
||||
clip_extents->height);
|
||||
}
|
||||
if (unlikely (surface->status))
|
||||
return surface;
|
||||
|
||||
_cairo_pattern_init_solid (&pattern.solid,
|
||||
CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
|
||||
status = _cairo_clip_path_to_region (clip_path);
|
||||
if (unlikely (_cairo_status_is_error (status)))
|
||||
goto BAIL;
|
||||
|
||||
need_translate = clip_extents->x | clip_extents->y;
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
if (need_translate) {
|
||||
cairo_region_translate (clip_path->region,
|
||||
-clip_extents->x, -clip_extents->y);
|
||||
}
|
||||
status = _cairo_surface_fill_region (surface,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
CAIRO_COLOR_WHITE,
|
||||
clip_path->region);
|
||||
if (need_translate) {
|
||||
cairo_region_translate (clip_path->region,
|
||||
clip_extents->x, clip_extents->y);
|
||||
}
|
||||
if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
|
||||
clip_path->path.maybe_fill_region)
|
||||
{
|
||||
status = _cairo_surface_paint (surface,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
&_cairo_pattern_white.base,
|
||||
NULL);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = _cairo_surface_paint (surface,
|
||||
CAIRO_OPERATOR_CLEAR,
|
||||
&_cairo_pattern_clear.base,
|
||||
NULL);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
||||
goto DONE;
|
||||
} else {
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (-clip_extents->x),
|
||||
_cairo_fixed_from_int (-clip_extents->y));
|
||||
}
|
||||
status = _cairo_surface_fill (surface,
|
||||
CAIRO_OPERATOR_OVER,
|
||||
&pattern.base,
|
||||
CAIRO_OPERATOR_ADD,
|
||||
&_cairo_pattern_white.base,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
@ -1111,19 +1031,16 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
}
|
||||
|
||||
prev = clip_path->prev;
|
||||
NEXT_PATH:
|
||||
if (prev != NULL) {
|
||||
status = _cairo_clip_path_to_region (prev);
|
||||
if (unlikely (_cairo_status_is_error (status)))
|
||||
goto BAIL;
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
status = _combine_region (surface, prev->region, clip_extents);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
} else if (prev->flags & CAIRO_CLIP_PATH_IS_BOX) {
|
||||
while (prev != NULL) {
|
||||
if (prev->flags & CAIRO_CLIP_PATH_IS_BOX &&
|
||||
prev->path.maybe_fill_region)
|
||||
{
|
||||
/* a simple box only affects the extents */
|
||||
} else if (prev->path.is_rectilinear) {
|
||||
}
|
||||
else if (prev->path.is_rectilinear ||
|
||||
prev->surface == NULL ||
|
||||
prev->surface->backend != target->backend)
|
||||
{
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&prev->path,
|
||||
_cairo_fixed_from_int (-clip_extents->x),
|
||||
@ -1131,7 +1048,7 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
}
|
||||
status = _cairo_surface_fill (surface,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
&_cairo_pattern_white.base,
|
||||
&prev->path,
|
||||
prev->fill_rule,
|
||||
prev->tolerance,
|
||||
@ -1145,19 +1062,23 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
||||
prev = prev->prev;
|
||||
goto NEXT_PATH;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_surface_pattern_t pattern;
|
||||
cairo_surface_t *prev_surface;
|
||||
int prev_tx, prev_ty;
|
||||
|
||||
prev_surface = _cairo_clip_path_get_surface (prev, target);
|
||||
_cairo_pattern_init_for_surface (&pattern.surface, prev_surface);
|
||||
cairo_surface_destroy (prev_surface);
|
||||
prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
|
||||
status = prev_surface->status;
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern, prev_surface);
|
||||
pattern.base.filter = CAIRO_FILTER_NEAREST;
|
||||
cairo_matrix_init_translate (&pattern.base.matrix,
|
||||
-prev->extents.x + clip_extents->x,
|
||||
-prev->extents.y + clip_extents->y);
|
||||
clip_extents->x - prev_tx,
|
||||
clip_extents->y - prev_ty);
|
||||
status = _cairo_surface_paint (surface,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
@ -1166,18 +1087,75 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
|
||||
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
prev = prev->prev;
|
||||
}
|
||||
|
||||
DONE:
|
||||
*tx = clip_extents->x;
|
||||
*ty = clip_extents->y;
|
||||
cairo_surface_destroy (clip_path->surface);
|
||||
return clip_path->surface = cairo_surface_reference (surface);
|
||||
return clip_path->surface = surface;
|
||||
|
||||
BAIL:
|
||||
cairo_surface_destroy (surface);
|
||||
return _cairo_surface_create_in_error (status);
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
|
||||
const cairo_rectangle_int_t *rect)
|
||||
{
|
||||
cairo_clip_path_t *clip_path;
|
||||
|
||||
if (clip == NULL)
|
||||
return FALSE;
|
||||
|
||||
clip_path = clip->path;
|
||||
if (clip_path->extents.x > rect->x ||
|
||||
clip_path->extents.y > rect->y ||
|
||||
clip_path->extents.x + clip_path->extents.width < rect->x + rect->width ||
|
||||
clip_path->extents.y + clip_path->extents.height < rect->y + rect->height)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
do {
|
||||
cairo_box_t box;
|
||||
|
||||
if ((clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) == 0)
|
||||
return FALSE;
|
||||
|
||||
if (! _cairo_path_fixed_is_box (&clip_path->path, &box))
|
||||
return FALSE;
|
||||
|
||||
if (box.p1.x > _cairo_fixed_from_int (rect->x) ||
|
||||
box.p1.y > _cairo_fixed_from_int (rect->y) ||
|
||||
box.p2.x < _cairo_fixed_from_int (rect->x + rect->width) ||
|
||||
box.p2.y < _cairo_fixed_from_int (rect->y + rect->height))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
} while ((clip_path = clip_path->prev) != NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_clip_contains_extents (cairo_clip_t *clip,
|
||||
const cairo_composite_rectangles_t *extents)
|
||||
{
|
||||
const cairo_rectangle_int_t *rect;
|
||||
|
||||
if (clip == NULL)
|
||||
return FALSE;
|
||||
|
||||
rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
|
||||
return _cairo_clip_contains_rectangle (clip, rect);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
|
||||
{
|
||||
@ -1202,72 +1180,48 @@ _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
|
||||
|
||||
clip_path = clip->path;
|
||||
do {
|
||||
fprintf (stream, "path: has region? %s, has surface? %s: ",
|
||||
fprintf (stream, "path: has region? %s, has surface? %s, aa=%d, tolerance=%f, rule=%d: ",
|
||||
clip_path->region == NULL ? "no" : "yes",
|
||||
clip_path->surface == NULL ? "no" : "yes");
|
||||
clip_path->surface == NULL ? "no" : "yes",
|
||||
clip_path->antialias,
|
||||
clip_path->tolerance,
|
||||
clip_path->fill_rule);
|
||||
_cairo_debug_print_path (stream, &clip_path->path);
|
||||
fprintf (stream, "\n");
|
||||
} while ((clip_path = clip_path->prev) != NULL);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
|
||||
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
|
||||
{
|
||||
/* XXX is_clear -> all_clipped */
|
||||
assert (clip->path != NULL);
|
||||
return _cairo_clip_path_get_surface (clip->path, target);
|
||||
return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_combine_with_surface (cairo_clip_t *clip,
|
||||
cairo_surface_t *dst,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
int dst_x, int dst_y)
|
||||
{
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_clip_path_t *clip_path = clip->path;
|
||||
cairo_bool_t need_translate;
|
||||
cairo_status_t status;
|
||||
|
||||
assert (clip_path != NULL);
|
||||
|
||||
if (clip_path->surface != NULL &&
|
||||
clip_path->surface->backend == dst->backend)
|
||||
{
|
||||
_cairo_pattern_init_for_surface (&pattern.surface,
|
||||
clip_path->surface);
|
||||
cairo_matrix_init_translate (&pattern.base.matrix,
|
||||
extents->x - clip_path->extents.x,
|
||||
extents->y - clip_path->extents.y);
|
||||
status = _cairo_surface_paint (dst,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
NULL);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
_cairo_pattern_init_solid (&pattern.solid,
|
||||
CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
|
||||
need_translate = extents->x | extents->y;
|
||||
need_translate = dst_x | dst_y;
|
||||
do {
|
||||
status = _cairo_clip_path_to_region (clip_path);
|
||||
if (unlikely (_cairo_status_is_error (status)))
|
||||
return status;
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return _combine_region (dst, clip_path->region, extents);
|
||||
|
||||
if (clip_path->surface != NULL &&
|
||||
clip_path->surface->backend == dst->backend)
|
||||
{
|
||||
_cairo_pattern_init_for_surface (&pattern.surface,
|
||||
clip_path->surface);
|
||||
cairo_surface_pattern_t pattern;
|
||||
|
||||
_cairo_pattern_init_for_surface (&pattern, clip_path->surface);
|
||||
cairo_matrix_init_translate (&pattern.base.matrix,
|
||||
extents->x - clip_path->extents.x,
|
||||
extents->y - clip_path->extents.y);
|
||||
dst_x - clip_path->extents.x,
|
||||
dst_y - clip_path->extents.y);
|
||||
pattern.base.filter = CAIRO_FILTER_NEAREST;
|
||||
status = _cairo_surface_paint (dst,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
@ -1278,30 +1232,29 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) {
|
||||
cairo_region_t clip_region;
|
||||
if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
|
||||
clip_path->path.maybe_fill_region)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_cairo_region_init_rectangle (&clip_region, &clip_path->extents);
|
||||
status = _combine_region (dst, &clip_region, extents);
|
||||
} else {
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (-extents->x),
|
||||
_cairo_fixed_from_int (-extents->y));
|
||||
}
|
||||
status = _cairo_surface_fill (dst,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&pattern.base,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias,
|
||||
NULL);
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (extents->x),
|
||||
_cairo_fixed_from_int (extents->y));
|
||||
}
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (-dst_x),
|
||||
_cairo_fixed_from_int (-dst_y));
|
||||
}
|
||||
status = _cairo_surface_fill (dst,
|
||||
CAIRO_OPERATOR_IN,
|
||||
&_cairo_pattern_white.base,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias,
|
||||
NULL);
|
||||
if (need_translate) {
|
||||
_cairo_path_fixed_translate (&clip_path->path,
|
||||
_cairo_fixed_from_int (dst_x),
|
||||
_cairo_fixed_from_int (dst_y));
|
||||
}
|
||||
|
||||
if (unlikely (status))
|
||||
@ -1432,6 +1385,90 @@ _cairo_clip_get_boxes (cairo_clip_t *clip,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
box_is_aligned (const cairo_box_t *box)
|
||||
{
|
||||
return
|
||||
_cairo_fixed_is_integer (box->p1.x) &&
|
||||
_cairo_fixed_is_integer (box->p1.y) &&
|
||||
_cairo_fixed_is_integer (box->p2.x) &&
|
||||
_cairo_fixed_is_integer (box->p2.y);
|
||||
}
|
||||
|
||||
static void
|
||||
intersect_with_boxes (cairo_composite_rectangles_t *extents,
|
||||
cairo_box_t *boxes,
|
||||
int num_boxes)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_box_t box;
|
||||
cairo_bool_t is_empty;
|
||||
|
||||
box.p1.x = box.p1.y = INT_MIN;
|
||||
box.p2.x = box.p2.y = INT_MAX;
|
||||
while (num_boxes--) {
|
||||
if (boxes->p1.x < box.p1.x)
|
||||
box.p1.x = boxes->p1.x;
|
||||
if (boxes->p1.y < box.p1.y)
|
||||
box.p1.y = boxes->p1.y;
|
||||
|
||||
if (boxes->p2.x > box.p2.x)
|
||||
box.p2.x = boxes->p2.x;
|
||||
if (boxes->p2.y > box.p2.y)
|
||||
box.p2.y = boxes->p2.y;
|
||||
}
|
||||
|
||||
_cairo_box_round_to_rectangle (&box, &rect);
|
||||
is_empty = _cairo_rectangle_intersect (&extents->bounded, &rect);
|
||||
is_empty = _cairo_rectangle_intersect (&extents->unbounded, &rect);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_to_boxes (cairo_clip_t **clip,
|
||||
cairo_composite_rectangles_t *extents,
|
||||
cairo_box_t **boxes,
|
||||
int *num_boxes)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const cairo_rectangle_int_t *rect;
|
||||
|
||||
rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
|
||||
|
||||
if (*clip == NULL)
|
||||
goto EXTENTS;
|
||||
|
||||
status = _cairo_clip_rectangle (*clip, rect);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
|
||||
switch ((int) status) {
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
intersect_with_boxes (extents, *boxes, *num_boxes);
|
||||
if (rect->width == 0 || rect->height == 0 ||
|
||||
extents->is_bounded ||
|
||||
(*num_boxes == 1 && box_is_aligned (*boxes)))
|
||||
{
|
||||
*clip = NULL;
|
||||
}
|
||||
goto DONE;
|
||||
|
||||
case CAIRO_INT_STATUS_UNSUPPORTED:
|
||||
goto EXTENTS;
|
||||
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
|
||||
EXTENTS:
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
_cairo_box_from_rectangle (&(*boxes)[0], rect);
|
||||
*num_boxes = 1;
|
||||
DONE:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static cairo_rectangle_list_t *
|
||||
_cairo_rectangle_list_create_in_error (cairo_status_t status)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -67,13 +67,14 @@ _cairo_stock_color (cairo_stock_t stock)
|
||||
return &cairo_color_black;
|
||||
case CAIRO_STOCK_TRANSPARENT:
|
||||
return &cairo_color_transparent;
|
||||
|
||||
case CAIRO_STOCK_NUM_COLORS:
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
/* If the user can get here somehow, give a color that indicates a
|
||||
* problem. */
|
||||
return &cairo_color_magenta;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
|
||||
/* If the user can get here somehow, give a color that indicates a
|
||||
* problem. */
|
||||
return &cairo_color_magenta;
|
||||
}
|
||||
|
||||
void
|
||||
@ -161,6 +162,7 @@ _cairo_color_get_rgba_premultiplied (cairo_color_t *color,
|
||||
*alpha = color->alpha;
|
||||
}
|
||||
|
||||
/* NB: This function works both for unmultiplied and premultiplied colors */
|
||||
cairo_bool_t
|
||||
_cairo_color_equal (const cairo_color_t *color_a,
|
||||
const cairo_color_t *color_b)
|
||||
@ -168,8 +170,42 @@ _cairo_color_equal (const cairo_color_t *color_a,
|
||||
if (color_a == color_b)
|
||||
return TRUE;
|
||||
|
||||
if (color_a->alpha_short != color_b->alpha_short)
|
||||
return FALSE;
|
||||
|
||||
if (color_a->alpha_short == 0)
|
||||
return TRUE;
|
||||
|
||||
return color_a->red_short == color_b->red_short &&
|
||||
color_a->green_short == color_b->green_short &&
|
||||
color_a->blue_short == color_b->blue_short &&
|
||||
color_a->alpha_short == color_b->alpha_short;
|
||||
color_a->blue_short == color_b->blue_short;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_color_stop_equal (const cairo_color_stop_t *color_a,
|
||||
const cairo_color_stop_t *color_b)
|
||||
{
|
||||
if (color_a == color_b)
|
||||
return TRUE;
|
||||
|
||||
return color_a->alpha_short == color_b->alpha_short &&
|
||||
color_a->red_short == color_b->red_short &&
|
||||
color_a->green_short == color_b->green_short &&
|
||||
color_a->blue_short == color_b->blue_short;
|
||||
}
|
||||
|
||||
cairo_content_t
|
||||
_cairo_color_get_content (const cairo_color_t *color)
|
||||
{
|
||||
if (CAIRO_COLOR_IS_OPAQUE (color))
|
||||
return CAIRO_CONTENT_COLOR;
|
||||
|
||||
if (color->red_short == 0 &&
|
||||
color->green_short == 0 &&
|
||||
color->blue_short == 0)
|
||||
{
|
||||
return CAIRO_CONTENT_ALPHA;
|
||||
}
|
||||
|
||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -44,6 +44,45 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Size in bytes of buffer to use off the stack per functions.
|
||||
* Mostly used by text functions. For larger allocations, they'll
|
||||
* malloc(). */
|
||||
#ifndef CAIRO_STACK_BUFFER_SIZE
|
||||
#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int))
|
||||
#endif
|
||||
|
||||
#define CAIRO_STACK_ARRAY_LENGTH(T) (CAIRO_STACK_BUFFER_SIZE / sizeof(T))
|
||||
|
||||
/*
|
||||
* The goal of this block is to define the following macros for
|
||||
* providing faster linkage to functions in the public API for calls
|
||||
* from within cairo.
|
||||
*
|
||||
* slim_hidden_proto(f)
|
||||
* slim_hidden_proto_no_warn(f)
|
||||
*
|
||||
* Declares `f' as a library internal function and hides the
|
||||
* function from the global symbol table. This macro must be
|
||||
* expanded after `f' has been declared with a prototype but before
|
||||
* any calls to the function are seen by the compiler. The no_warn
|
||||
* variant inhibits warnings about the return value being unused at
|
||||
* call sites. The macro works by renaming `f' to an internal name
|
||||
* in the symbol table and hiding that. As far as cairo internal
|
||||
* calls are concerned they're calling a library internal function
|
||||
* and thus don't need to bounce via the PLT.
|
||||
*
|
||||
* slim_hidden_def(f)
|
||||
*
|
||||
* Exports `f' back to the global symbol table. This macro must be
|
||||
* expanded right after the function definition and only for symbols
|
||||
* hidden previously with slim_hidden_proto(). The macro works by
|
||||
* adding a global entry to the symbol table which points at the
|
||||
* internal name of `f' created by slim_hidden_proto().
|
||||
*
|
||||
* Functions in the public API which aren't called by the library
|
||||
* don't need to be hidden and re-exported using the slim hidden
|
||||
* macros.
|
||||
*/
|
||||
#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
|
||||
# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
|
||||
# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
|
||||
@ -134,9 +173,11 @@
|
||||
#if __GNUC__ >= 3
|
||||
#define cairo_pure __attribute__((pure))
|
||||
#define cairo_const __attribute__((const))
|
||||
#define cairo_always_inline inline __attribute__((always_inline))
|
||||
#else
|
||||
#define cairo_pure
|
||||
#define cairo_const
|
||||
#define cairo_always_inline inline
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
|
||||
@ -171,6 +212,26 @@
|
||||
#ifdef _MSC_VER
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
|
||||
/* there are currently linkage problems that arise when trying to include intrin.h in c++:
|
||||
* D:\sdks\v7.0\include\winnt.h(3674) : error C2733: second C linkage of overloaded function '_interlockedbittestandset' not allowed
|
||||
* so avoid defining ffs in c++ code for now */
|
||||
#ifndef __cplusplus
|
||||
/* Add a definition of ffs */
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_BitScanForward)
|
||||
static __forceinline int
|
||||
ffs (int x)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if (_BitScanForward(&i, x) != 0)
|
||||
return i + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
|
105
gfx/cairo/cairo/src/cairo-composite-rectangles-private.h
Normal file
105
gfx/cairo/cairo/src/cairo-composite-rectangles-private.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.u>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
|
||||
#define CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
/* Rectangles that take part in a composite operation.
|
||||
*
|
||||
* The source and mask track the extents of the respective patterns in device
|
||||
* space. The unbounded rectangle is essentially the clip rectangle. And the
|
||||
* intersection of all is the bounded rectangle, which is the minimum extents
|
||||
* the operation may require. Whether or not the operation is actually bounded
|
||||
* is tracked in the is_bounded boolean.
|
||||
*
|
||||
*/
|
||||
struct _cairo_composite_rectangles {
|
||||
cairo_rectangle_int_t source;
|
||||
cairo_rectangle_int_t mask;
|
||||
cairo_rectangle_int_t bounded; /* dst */
|
||||
cairo_rectangle_int_t unbounded; /* clip */
|
||||
uint32_t is_bounded;
|
||||
};
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
const cairo_pattern_t *mask,
|
||||
cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_clip_t *clip);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_clip_t *clip,
|
||||
cairo_bool_t *overlap);
|
||||
|
||||
#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */
|
195
gfx/cairo/cairo/src/cairo-composite-rectangles.c
Normal file
195
gfx/cairo/cairo/src/cairo-composite-rectangles.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-composite-rectangles-private.h"
|
||||
|
||||
/* A collection of routines to facilitate writing compositors. */
|
||||
|
||||
static inline cairo_bool_t
|
||||
_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_clip_t *clip)
|
||||
{
|
||||
extents->unbounded = *surface_extents;
|
||||
|
||||
if (clip != NULL) {
|
||||
const cairo_rectangle_int_t *clip_extents;
|
||||
|
||||
clip_extents = _cairo_clip_get_extents (clip);
|
||||
if (clip_extents == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extents->bounded = extents->unbounded;
|
||||
extents->is_bounded = _cairo_operator_bounded_by_either (op);
|
||||
|
||||
_cairo_pattern_get_extents (source, &extents->source);
|
||||
if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
|
||||
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_clip_t *clip)
|
||||
{
|
||||
if (! _cairo_composite_rectangles_init (extents,
|
||||
surface_extents,
|
||||
op, source, clip))
|
||||
{
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
extents->mask = extents->bounded;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
|
||||
{
|
||||
cairo_bool_t ret;
|
||||
|
||||
ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
|
||||
if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
const cairo_pattern_t *mask,
|
||||
cairo_clip_t *clip)
|
||||
{
|
||||
if (! _cairo_composite_rectangles_init (extents,
|
||||
surface_extents,
|
||||
op, source, clip))
|
||||
{
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
_cairo_pattern_get_extents (mask, &extents->mask);
|
||||
|
||||
return _cairo_composite_rectangles_intersect (extents);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_clip_t *clip)
|
||||
{
|
||||
if (! _cairo_composite_rectangles_init (extents,
|
||||
surface_extents,
|
||||
op, source, clip))
|
||||
{
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
_cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
|
||||
|
||||
return _cairo_composite_rectangles_intersect (extents);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_clip_t *clip)
|
||||
{
|
||||
if (! _cairo_composite_rectangles_init (extents,
|
||||
surface_extents,
|
||||
op, source, clip))
|
||||
{
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
_cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
|
||||
|
||||
return _cairo_composite_rectangles_intersect (extents);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_clip_t *clip,
|
||||
cairo_bool_t *overlap)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (! _cairo_composite_rectangles_init (extents,
|
||||
surface_extents,
|
||||
op, source, clip))
|
||||
{
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
|
||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||
glyphs, num_glyphs,
|
||||
&extents->mask,
|
||||
overlap);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_composite_rectangles_intersect (extents);
|
||||
}
|
@ -43,10 +43,8 @@
|
||||
#include <d3d10.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
extern "C" {
|
||||
#include "cairoint.h"
|
||||
#include "cairo-surface-clipper-private.h"
|
||||
}
|
||||
|
||||
#include "cairo-win32-refptr.h"
|
||||
#include "cairo-d2d-private-fx.h"
|
||||
|
@ -39,10 +39,9 @@
|
||||
#include "cairo-d2d-private.h"
|
||||
#include "cairo-dwrite-private.h"
|
||||
|
||||
extern "C" {
|
||||
#include "cairo-win32.h"
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
}
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
// Required for using placement new.
|
||||
#include <new>
|
||||
@ -649,9 +648,9 @@ _cairo_d2d_stroke(void *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_clip_t *clip);
|
||||
@ -763,6 +762,16 @@ _cairo_d2d_compute_surface_mem_size(cairo_d2d_surface_t *surface)
|
||||
return size;
|
||||
}
|
||||
|
||||
static D2D1_COLOR_F
|
||||
_cairo_d2d_color_from_cairo_color_stop(const cairo_color_stop_t &color)
|
||||
{
|
||||
return D2D1::ColorF((FLOAT)color.red,
|
||||
(FLOAT)color.green,
|
||||
(FLOAT)color.blue,
|
||||
(FLOAT)color.alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the surface buffer texture for window surfaces whose backbuffer
|
||||
* is not directly usable as a bitmap.
|
||||
@ -1435,7 +1444,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
|
||||
}
|
||||
stops[i].color =
|
||||
_cairo_d2d_color_from_cairo_color(source_pattern->base.stops[stop].color);
|
||||
_cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
|
||||
}
|
||||
} else {
|
||||
// Simple case, we don't need to reflect.
|
||||
@ -1445,7 +1454,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
// Calculate which stop this would be in the original pattern
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
|
||||
stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
}
|
||||
} else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
|
||||
@ -1458,7 +1467,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
|
||||
stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
} else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
|
||||
float offset_factor = (outer_radius - inner_radius) / outer_radius;
|
||||
@ -1482,7 +1491,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
for (unsigned int j = 0; j < source_pattern->base.n_stops; j++, i++) {
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[j];
|
||||
stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
stops[i].position = 1.0f;
|
||||
stops[i].color = D2D1::ColorF(0, 0);
|
||||
@ -1514,7 +1523,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
// Cairo behavior in this situation is to draw a solid color the size of the last stop.
|
||||
RefPtr<ID2D1SolidColorBrush> brush;
|
||||
d2dsurf->rt->CreateSolidColorBrush(
|
||||
_cairo_d2d_color_from_cairo_color(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
|
||||
_cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
|
||||
&brush);
|
||||
return brush;
|
||||
}
|
||||
@ -1619,7 +1628,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
|
||||
}
|
||||
stops[i].color =
|
||||
_cairo_d2d_color_from_cairo_color(source_pattern->base.stops[stop].color);
|
||||
_cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
|
||||
}
|
||||
} else {
|
||||
// Simple case, we don't need to reflect.
|
||||
@ -1629,7 +1638,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
// Calculate which stop this would be in the original pattern
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
|
||||
stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
}
|
||||
} else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
|
||||
@ -1637,7 +1646,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
|
||||
stops[i].position = (FLOAT)stop->offset;
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
} else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
|
||||
num_stops += 2;
|
||||
@ -1647,7 +1656,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||
for (unsigned int i = 1; i < source_pattern->base.n_stops + 1; i++) {
|
||||
cairo_gradient_stop_t *stop = &source_pattern->base.stops[i - 1];
|
||||
stops[i].position = (FLOAT)stop->offset;
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
|
||||
stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
|
||||
}
|
||||
stops[source_pattern->base.n_stops + 1].position = 1.0f;
|
||||
stops[source_pattern->base.n_stops + 1].color = D2D1::ColorF(0, 0);
|
||||
@ -2309,6 +2318,16 @@ static cairo_operator_t _cairo_d2d_simplify_operator(cairo_operator_t op,
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_d2d_surface_init(cairo_d2d_surface_t *newSurf, cairo_d2d_device_t *d2d_device, cairo_format_t format)
|
||||
{
|
||||
newSurf->format = format;
|
||||
|
||||
newSurf->device = d2d_device;
|
||||
cairo_addref_device(&d2d_device->base);
|
||||
d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
}
|
||||
|
||||
// Implementation
|
||||
static cairo_surface_t*
|
||||
_cairo_d2d_create_similar(void *surface,
|
||||
@ -2320,7 +2339,7 @@ _cairo_d2d_create_similar(void *surface,
|
||||
cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
|
||||
|
||||
new (newSurf) cairo_d2d_surface_t();
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
|
||||
|
||||
|
||||
D2D1_SIZE_U sizePixels;
|
||||
@ -2425,9 +2444,7 @@ _cairo_d2d_create_similar(void *surface,
|
||||
|
||||
_d2d_clear_surface(newSurf);
|
||||
|
||||
newSurf->device = d2dsurf->device;
|
||||
cairo_addref_device(&newSurf->device->base);
|
||||
newSurf->device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
_cairo_d2d_surface_init(newSurf, d2dsurf->device, _cairo_format_from_content(content));
|
||||
|
||||
return reinterpret_cast<cairo_surface_t*>(newSurf);
|
||||
|
||||
@ -2501,8 +2518,8 @@ _cairo_d2d_acquire_source_image(void *abstract_surface,
|
||||
return _cairo_error(CAIRO_STATUS_NO_DEVICE);
|
||||
}
|
||||
*image_out =
|
||||
(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
|
||||
d2dsurf->base.content,
|
||||
(cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData,
|
||||
d2dsurf->format,
|
||||
size.width,
|
||||
size.height,
|
||||
data.RowPitch);
|
||||
@ -2573,8 +2590,8 @@ _cairo_d2d_acquire_dest_image(void *abstract_surface,
|
||||
return _cairo_error(CAIRO_STATUS_NO_DEVICE);
|
||||
}
|
||||
*image_out =
|
||||
(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
|
||||
d2dsurf->base.content,
|
||||
(cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData,
|
||||
_cairo_format_from_content(d2dsurf->base.content),
|
||||
size.width,
|
||||
size.height,
|
||||
data.RowPitch);
|
||||
@ -3178,7 +3195,7 @@ _cairo_d2d_mask(void *surface,
|
||||
if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
cairo_solid_pattern_t *solidPattern =
|
||||
(cairo_solid_pattern_t*)mask;
|
||||
if (solidPattern->content = CAIRO_CONTENT_ALPHA) {
|
||||
if (_cairo_color_get_content (&solidPattern->color) == CAIRO_CONTENT_ALPHA) {
|
||||
isSolidAlphaMask = true;
|
||||
solidAlphaValue = solidPattern->color.alpha;
|
||||
}
|
||||
@ -3321,9 +3338,9 @@ _cairo_d2d_stroke(void *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_pattern_t *source,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse,
|
||||
const cairo_stroke_style_t *style,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_matrix_t *ctm_inverse,
|
||||
double tolerance,
|
||||
cairo_antialias_t antialias,
|
||||
cairo_clip_t *clip)
|
||||
@ -3526,7 +3543,12 @@ _cairo_d2d_fill(void *surface,
|
||||
|
||||
if (target_rt.get() != d2dsurf->rt.get()) {
|
||||
double x1, y1, x2, y2;
|
||||
_cairo_path_fixed_bounds(path, &x1, &y1, &x2, &y2);
|
||||
cairo_box_t box;
|
||||
_cairo_path_fixed_extents (path, &box);
|
||||
x1 = _cairo_fixed_to_double (box.p1.x);
|
||||
y1 = _cairo_fixed_to_double (box.p1.y);
|
||||
x2 = _cairo_fixed_to_double (box.p2.x);
|
||||
y2 = _cairo_fixed_to_double (box.p2.y);
|
||||
cairo_rectangle_int_t bounds;
|
||||
_cairo_d2d_round_out_to_int_rect(&bounds, x1, y1, x2, y2);
|
||||
return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip, &bounds);
|
||||
@ -4118,6 +4140,8 @@ _cairo_d2d_getextents(void *surface,
|
||||
|
||||
/** Helper functions. */
|
||||
|
||||
|
||||
|
||||
cairo_surface_t*
|
||||
cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
|
||||
HWND wnd,
|
||||
@ -4127,7 +4151,7 @@ cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
|
||||
cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
|
||||
new (newSurf) cairo_d2d_surface_t();
|
||||
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
|
||||
|
||||
RECT rc;
|
||||
HRESULT hr;
|
||||
@ -4229,9 +4253,7 @@ cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
|
||||
|
||||
_d2d_clear_surface(newSurf);
|
||||
|
||||
newSurf->device = d2d_device;
|
||||
cairo_addref_device(cairo_device);
|
||||
d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
_cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
|
||||
|
||||
return reinterpret_cast<cairo_surface_t*>(newSurf);
|
||||
|
||||
@ -4241,6 +4263,8 @@ FAIL_HWND:
|
||||
return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
|
||||
|
||||
cairo_surface_t *
|
||||
cairo_d2d_surface_create(cairo_device_t *device,
|
||||
cairo_format_t format,
|
||||
@ -4258,12 +4282,12 @@ cairo_d2d_surface_create(cairo_device_t *device,
|
||||
DXGI_FORMAT dxgiformat = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
if (format == CAIRO_FORMAT_ARGB32) {
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR_ALPHA);
|
||||
} else if (format == CAIRO_FORMAT_RGB24) {
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
|
||||
alpha = D2D1_ALPHA_MODE_IGNORE;
|
||||
} else {
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_ALPHA);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
|
||||
dxgiformat = DXGI_FORMAT_A8_UNORM;
|
||||
}
|
||||
|
||||
@ -4343,9 +4367,7 @@ cairo_d2d_surface_create(cairo_device_t *device,
|
||||
|
||||
_d2d_clear_surface(newSurf);
|
||||
|
||||
newSurf->device = d2d_device;
|
||||
cairo_addref_device(device);
|
||||
d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
_cairo_d2d_surface_init(newSurf, d2d_device, format);
|
||||
|
||||
return reinterpret_cast<cairo_surface_t*>(newSurf);
|
||||
|
||||
@ -4398,7 +4420,7 @@ cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo
|
||||
status = CAIRO_STATUS_INVALID_CONTENT;
|
||||
goto FAIL_CREATEHANDLE;
|
||||
}
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
|
||||
if (content == CAIRO_CONTENT_COLOR) {
|
||||
alpha = D2D1_ALPHA_MODE_IGNORE;
|
||||
}
|
||||
@ -4407,7 +4429,7 @@ cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo
|
||||
status = CAIRO_STATUS_INVALID_CONTENT;
|
||||
goto FAIL_CREATEHANDLE;
|
||||
}
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_ALPHA);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
|
||||
} else {
|
||||
status = CAIRO_STATUS_INVALID_FORMAT;
|
||||
// We don't know how to support this format!
|
||||
@ -4444,9 +4466,7 @@ cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo
|
||||
|
||||
newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
|
||||
|
||||
newSurf->device = d2d_device;
|
||||
cairo_addref_device(device);
|
||||
d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
_cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
|
||||
|
||||
return &newSurf->base;
|
||||
|
||||
@ -4467,10 +4487,10 @@ cairo_d2d_surface_create_for_texture(cairo_device_t *device,
|
||||
|
||||
D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
if (content == CAIRO_CONTENT_COLOR) {
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
|
||||
alpha = D2D1_ALPHA_MODE_IGNORE;
|
||||
} else {
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
|
||||
_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
|
||||
}
|
||||
|
||||
D2D1_SIZE_U sizePixels;
|
||||
@ -4527,9 +4547,7 @@ cairo_d2d_surface_create_for_texture(cairo_device_t *device,
|
||||
|
||||
newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
|
||||
|
||||
newSurf->device = d2d_device;
|
||||
cairo_addref_device(device);
|
||||
d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
|
||||
_cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
|
||||
|
||||
return reinterpret_cast<cairo_surface_t*>(newSurf);
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -77,10 +77,14 @@ cairo_debug_reset_static_data (void)
|
||||
|
||||
_cairo_clip_reset_static_data ();
|
||||
|
||||
_cairo_image_reset_static_data ();
|
||||
|
||||
#if CAIRO_HAS_DRM_SURFACE
|
||||
_cairo_drm_device_reset_static_data ();
|
||||
#endif
|
||||
|
||||
_cairo_reset_static_data ();
|
||||
|
||||
CAIRO_MUTEX_FINALIZE ();
|
||||
}
|
||||
|
||||
@ -106,10 +110,14 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
|
||||
case CAIRO_FORMAT_A8:
|
||||
width = image->width;
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB16_565:
|
||||
width = image->width*2;
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
width = image->width*4;
|
||||
break;
|
||||
case CAIRO_FORMAT_INVALID:
|
||||
default:
|
||||
/* XXX compute width from pixman bpp */
|
||||
return;
|
||||
@ -221,6 +229,12 @@ _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
printf ("path: extents=(%f, %f), (%f, %f)\n",
|
||||
_cairo_fixed_to_double (path->extents.p1.x),
|
||||
_cairo_fixed_to_double (path->extents.p1.y),
|
||||
_cairo_fixed_to_double (path->extents.p2.x),
|
||||
_cairo_fixed_to_double (path->extents.p2.y));
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_print_move_to,
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-output-stream-private.h"
|
||||
#include <zlib.h>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -36,20 +36,6 @@
|
||||
#ifndef CAIRO_DEPRECATED_H
|
||||
#define CAIRO_DEPRECATED_H
|
||||
|
||||
/* The %CAIRO_FORMAT_RGB16_565 value was added in cairo 1.2.0 as part
|
||||
* of fixing cairo's xlib backend to work with X servers advertising a
|
||||
* 16-bit, 565 visual. But as it turned out, adding this format to
|
||||
* #cairo_format_t was not necessary, and was a mistake, (cairo's xlib
|
||||
* backend can work fine with 16-bit visuals in the same way it works
|
||||
* with BGR visuals without any BGR formats in
|
||||
* #cairo_format_t).
|
||||
*
|
||||
* Additionally, the support for the RGB16_565 format was never
|
||||
* completely implemented. So while this format value is currently
|
||||
* deprecated, it may eventually acquire complete support in the future.
|
||||
*/
|
||||
/* #define CAIRO_FORMAT_RGB16_565 4 */
|
||||
|
||||
#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
|
||||
|
||||
/* Obsolete functions. These definitions exist to coerce the compiler
|
||||
@ -123,7 +109,6 @@
|
||||
#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
|
||||
#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create
|
||||
#define cairo_set_target_glitz cairo_set_target_glitz_DEPRECATED_BY_cairo_glitz_surface_create
|
||||
#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
|
||||
#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
|
||||
#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
|
||||
|
86
gfx/cairo/cairo/src/cairo-device-private.h
Normal file
86
gfx/cairo/cairo/src/cairo-device-private.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Intel Corporation.
|
||||
*
|
||||
* Contributors(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_DEVICE_PRIVATE_H_
|
||||
#define _CAIRO_DEVICE_PRIVATE_H_
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-mutex-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-types-private.h"
|
||||
|
||||
struct _cairo_device {
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
const cairo_device_backend_t *backend;
|
||||
|
||||
cairo_recursive_mutex_t mutex;
|
||||
unsigned mutex_depth;
|
||||
|
||||
cairo_bool_t finished;
|
||||
};
|
||||
|
||||
struct _cairo_device_backend {
|
||||
cairo_device_type_t type;
|
||||
|
||||
void (*lock) (void *device);
|
||||
void (*unlock) (void *device);
|
||||
|
||||
cairo_warn cairo_status_t (*flush) (void *device);
|
||||
void (*finish) (void *device);
|
||||
void (*destroy) (void *device);
|
||||
};
|
||||
|
||||
cairo_private cairo_device_t *
|
||||
_cairo_device_create_in_error (cairo_status_t status);
|
||||
|
||||
cairo_private void
|
||||
_cairo_device_init (cairo_device_t *device,
|
||||
const cairo_device_backend_t *backend);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_device_set_error (cairo_device_t *device,
|
||||
cairo_status_t error);
|
||||
|
||||
slim_hidden_proto_no_warn (cairo_device_reference);
|
||||
slim_hidden_proto (cairo_device_acquire);
|
||||
slim_hidden_proto (cairo_device_release);
|
||||
slim_hidden_proto (cairo_device_flush);
|
||||
slim_hidden_proto (cairo_device_finish);
|
||||
slim_hidden_proto (cairo_device_destroy);
|
||||
|
||||
#endif /* _CAIRO_DEVICE_PRIVATE_H_ */
|
533
gfx/cairo/cairo/src/cairo-device.c
Normal file
533
gfx/cairo/cairo/src/cairo-device.c
Normal file
@ -0,0 +1,533 @@
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Intel Corporation.
|
||||
*
|
||||
* Contributors(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-device-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:cairo-device
|
||||
* @Title: cairo_device_t
|
||||
* @Short_Description: interface to underlying rendering system
|
||||
* @See_Also: #cairo_surface_t
|
||||
*
|
||||
* Devices are the abstraction Cairo employs for the rendering system
|
||||
* used by a #cairo_surface_t. You can get the device of a surface using
|
||||
* cairo_surface_get_device().
|
||||
*
|
||||
* Devices are created using custom functions specific to the rendering
|
||||
* system you want to use. See the documentation for the surface types
|
||||
* for those functions.
|
||||
*
|
||||
* An important function that devices fulfill is sharing access to the
|
||||
* rendering system between Cairo and your application. If you want to
|
||||
* access a device directly that you used to draw to with Cairo, you must
|
||||
* first call cairo_device_flush() to ensure that Cairo finishes all
|
||||
* operations on the device and resets it to a clean state.
|
||||
*
|
||||
* Cairo also provides the functions cairo_device_acquire() and
|
||||
* cairo_device_release() to synchronize access to the rendering system
|
||||
* in a multithreaded environment. This is done internally, but can also
|
||||
* be used by applications.
|
||||
*
|
||||
* Putting this all together, a function that works with devices should
|
||||
* look something like this:
|
||||
* <informalexample><programlisting>
|
||||
* void
|
||||
* my_device_modifying_function (cairo_device_t *device)
|
||||
* {
|
||||
* cairo_status_t status;
|
||||
*
|
||||
* // Ensure the device is properly reset
|
||||
* cairo_device_flush (device);
|
||||
* // Try to acquire the device
|
||||
* status = cairo_device_acquire (device);
|
||||
* if (status != CAIRO_STATUS_SUCCESS) {
|
||||
* printf ("Failed to acquire the device: %s\n", cairo_status_to_string (status));
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* // Do the custom operations on the device here.
|
||||
* // But do not call any Cairo functions that might acquire devices.
|
||||
*
|
||||
* // Release the device when done.
|
||||
* cairo_device_release (device);
|
||||
* }
|
||||
* </programlisting></informalexample>
|
||||
*
|
||||
* <note><para>Please refer to the documentation of each backend for
|
||||
* additional usage requirements, guarantees provided, and
|
||||
* interactions with existing surface API of the device functions for
|
||||
* surfaces of that type.
|
||||
* </para></note>
|
||||
*/
|
||||
|
||||
static const cairo_device_t _nil_device = {
|
||||
CAIRO_REFERENCE_COUNT_INVALID,
|
||||
CAIRO_STATUS_NO_MEMORY,
|
||||
};
|
||||
|
||||
static const cairo_device_t _mismatch_device = {
|
||||
CAIRO_REFERENCE_COUNT_INVALID,
|
||||
CAIRO_STATUS_DEVICE_TYPE_MISMATCH,
|
||||
};
|
||||
|
||||
static const cairo_device_t _invalid_device = {
|
||||
CAIRO_REFERENCE_COUNT_INVALID,
|
||||
CAIRO_STATUS_DEVICE_ERROR,
|
||||
};
|
||||
|
||||
cairo_device_t *
|
||||
_cairo_device_create_in_error (cairo_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_NO_MEMORY:
|
||||
return (cairo_device_t *) &_nil_device;
|
||||
case CAIRO_STATUS_DEVICE_ERROR:
|
||||
return (cairo_device_t *) &_invalid_device;
|
||||
case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
|
||||
return (cairo_device_t *) &_mismatch_device;
|
||||
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
case CAIRO_STATUS_LAST_STATUS:
|
||||
ASSERT_NOT_REACHED;
|
||||
/* fall-through */
|
||||
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
|
||||
case CAIRO_STATUS_INVALID_STATUS:
|
||||
case CAIRO_STATUS_INVALID_FORMAT:
|
||||
case CAIRO_STATUS_INVALID_VISUAL:
|
||||
case CAIRO_STATUS_READ_ERROR:
|
||||
case CAIRO_STATUS_WRITE_ERROR:
|
||||
case CAIRO_STATUS_FILE_NOT_FOUND:
|
||||
case CAIRO_STATUS_TEMP_FILE_ERROR:
|
||||
case CAIRO_STATUS_INVALID_STRIDE:
|
||||
case CAIRO_STATUS_INVALID_SIZE:
|
||||
case CAIRO_STATUS_INVALID_RESTORE:
|
||||
case CAIRO_STATUS_INVALID_POP_GROUP:
|
||||
case CAIRO_STATUS_NO_CURRENT_POINT:
|
||||
case CAIRO_STATUS_INVALID_MATRIX:
|
||||
case CAIRO_STATUS_NULL_POINTER:
|
||||
case CAIRO_STATUS_INVALID_STRING:
|
||||
case CAIRO_STATUS_INVALID_PATH_DATA:
|
||||
case CAIRO_STATUS_SURFACE_FINISHED:
|
||||
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
|
||||
case CAIRO_STATUS_INVALID_DASH:
|
||||
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
||||
case CAIRO_STATUS_INVALID_INDEX:
|
||||
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
|
||||
case CAIRO_STATUS_FONT_TYPE_MISMATCH:
|
||||
case CAIRO_STATUS_USER_FONT_IMMUTABLE:
|
||||
case CAIRO_STATUS_USER_FONT_ERROR:
|
||||
case CAIRO_STATUS_NEGATIVE_COUNT:
|
||||
case CAIRO_STATUS_INVALID_CLUSTERS:
|
||||
case CAIRO_STATUS_INVALID_SLANT:
|
||||
case CAIRO_STATUS_INVALID_WEIGHT:
|
||||
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
|
||||
case CAIRO_STATUS_INVALID_CONTENT:
|
||||
default:
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_device_t *) &_nil_device;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_device_init (cairo_device_t *device,
|
||||
const cairo_device_backend_t *backend)
|
||||
{
|
||||
CAIRO_REFERENCE_COUNT_INIT (&device->ref_count, 1);
|
||||
device->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
device->backend = backend;
|
||||
|
||||
CAIRO_RECURSIVE_MUTEX_INIT (device->mutex);
|
||||
device->mutex_depth = 0;
|
||||
|
||||
device->finished = FALSE;
|
||||
|
||||
_cairo_user_data_array_init (&device->user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_reference:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Increases the reference count on @device by one. This prevents
|
||||
* @device from being destroyed until a matching call to
|
||||
* cairo_device_destroy() is made.
|
||||
*
|
||||
* The number of references to a #cairo_device_t can be get using
|
||||
* cairo_device_get_reference_count().
|
||||
*
|
||||
* Return value: the referenced #cairo_device_t.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_device_t *
|
||||
cairo_device_reference (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
{
|
||||
return device;
|
||||
}
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count));
|
||||
_cairo_reference_count_inc (&device->ref_count);
|
||||
|
||||
return device;
|
||||
}
|
||||
slim_hidden_def (cairo_device_reference);
|
||||
|
||||
/**
|
||||
* cairo_device_status:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Checks whether an error has previously occurred for this
|
||||
* device.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS on success or an error code if
|
||||
* the device is in an error state.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_device_status (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL)
|
||||
return CAIRO_STATUS_NULL_POINTER;
|
||||
|
||||
return device->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_flush:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Finish any pending operations for the device and also restore any
|
||||
* temporary modifications cairo has made to the device's state.
|
||||
* This function must be called before switching from using the
|
||||
* device with Cairo to operating on it directly with native APIs.
|
||||
* If the device doesn't support direct access, then this function
|
||||
* does nothing.
|
||||
*
|
||||
* This function may acquire devices.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_device_flush (cairo_device_t *device)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (device == NULL || device->status)
|
||||
return;
|
||||
|
||||
if (device->backend->flush != NULL) {
|
||||
status = device->backend->flush (device);
|
||||
if (unlikely (status))
|
||||
status = _cairo_device_set_error (device, status);
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_device_flush);
|
||||
|
||||
/**
|
||||
* cairo_device_finish:
|
||||
* @device: the #cairo_device_t to finish
|
||||
*
|
||||
* This function finishes the device and drops all references to
|
||||
* external resources. All surfaces, fonts and other objects created
|
||||
* for this @device will be finished, too.
|
||||
* Further operations on the @device will not affect the @device but
|
||||
* will instead trigger a %CAIRO_STATUS_DEVICE_FINISHED error.
|
||||
*
|
||||
* When the last call to cairo_device_destroy() decreases the
|
||||
* reference count to zero, cairo will call cairo_device_finish() if
|
||||
* it hasn't been called already, before freeing the resources
|
||||
* associated with the device.
|
||||
*
|
||||
* This function may acquire devices.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_device_finish (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->finished)
|
||||
return;
|
||||
|
||||
cairo_device_flush (device);
|
||||
|
||||
device->finished = TRUE;
|
||||
|
||||
if (device->backend->finish != NULL)
|
||||
device->backend->finish (device);
|
||||
}
|
||||
slim_hidden_def (cairo_device_finish);
|
||||
|
||||
/**
|
||||
* cairo_device_destroy:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Decreases the reference count on @device by one. If the result is
|
||||
* zero, then @device and all associated resources are freed. See
|
||||
* cairo_device_reference().
|
||||
*
|
||||
* This function may acquire devices if the last reference was dropped.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_device_destroy (cairo_device_t *device)
|
||||
{
|
||||
cairo_user_data_array_t user_data;
|
||||
|
||||
if (device == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count));
|
||||
if (! _cairo_reference_count_dec_and_test (&device->ref_count))
|
||||
return;
|
||||
|
||||
cairo_device_finish (device);
|
||||
|
||||
assert (device->mutex_depth == 0);
|
||||
CAIRO_MUTEX_FINI (device->mutex);
|
||||
|
||||
user_data = device->user_data;
|
||||
|
||||
device->backend->destroy (device);
|
||||
|
||||
_cairo_user_data_array_fini (&user_data);
|
||||
|
||||
}
|
||||
slim_hidden_def (cairo_device_destroy);
|
||||
|
||||
/**
|
||||
* cairo_device_get_type:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* This function returns the type of the device. See #cairo_device_type_t
|
||||
* for available types.
|
||||
*
|
||||
* Return value: The type of @device.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_device_type_t
|
||||
cairo_device_get_type (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
{
|
||||
return (cairo_device_type_t) -1;
|
||||
}
|
||||
|
||||
return device->backend->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_acquire:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Acquires the @device for the current thread. This function will block
|
||||
* until no other thread has acquired the device.
|
||||
*
|
||||
* If the return value is %CAIRO_STATUS_SUCCESS, you successfully acquired the
|
||||
* device. From now on your thread owns the device and no other thread will be
|
||||
* able to acquire it until a matching call to cairo_device_release(). It is
|
||||
* allowed to recursively acquire the device multiple times from the same
|
||||
* thread.
|
||||
*
|
||||
* <note><para>You must never acquire two different devices at the same time
|
||||
* unless this is explicitly allowed. Otherwise the possibility of deadlocks
|
||||
* exist.
|
||||
*
|
||||
* As various Cairo functions can acquire devices when called, these functions
|
||||
* may also cause deadlocks when you call them with an acquired device. So you
|
||||
* must not have a device acquired when calling them. These functions are
|
||||
* marked in the documentation.
|
||||
* </para></note>
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS on success or an error code if
|
||||
* the device is in an error state and could not be
|
||||
* acquired. After a successful call to cairo_device_acquire(),
|
||||
* a matching call to cairo_device_release() is required.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_device_acquire (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (unlikely (device->status))
|
||||
return device->status;
|
||||
|
||||
if (unlikely (device->finished))
|
||||
return _cairo_device_set_error (device, CAIRO_STATUS_SURFACE_FINISHED); /* XXX */
|
||||
|
||||
CAIRO_MUTEX_LOCK (device->mutex);
|
||||
if (device->mutex_depth++ == 0) {
|
||||
if (device->backend->lock != NULL)
|
||||
device->backend->lock (device);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_device_acquire);
|
||||
|
||||
/**
|
||||
* cairo_device_release:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Releases a @device previously acquired using cairo_device_acquire(). See
|
||||
* that function for details.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_device_release (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
assert (device->mutex_depth > 0);
|
||||
|
||||
if (--device->mutex_depth == 0) {
|
||||
if (device->backend->unlock != NULL)
|
||||
device->backend->unlock (device);
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (device->mutex);
|
||||
}
|
||||
slim_hidden_def (cairo_device_release);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_device_set_error (cairo_device_t *device,
|
||||
cairo_status_t status)
|
||||
{
|
||||
if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (&device->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_get_reference_count:
|
||||
* @device: a #cairo_device_t
|
||||
*
|
||||
* Returns the current reference count of @device.
|
||||
*
|
||||
* Return value: the current reference count of @device. If the
|
||||
* object is a nil object, 0 will be returned.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
unsigned int
|
||||
cairo_device_get_reference_count (cairo_device_t *device)
|
||||
{
|
||||
if (device == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
return 0;
|
||||
|
||||
return CAIRO_REFERENCE_COUNT_GET_VALUE (&device->ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_get_user_data:
|
||||
* @device: a #cairo_device_t
|
||||
* @key: the address of the #cairo_user_data_key_t the user data was
|
||||
* attached to
|
||||
*
|
||||
* Return user data previously attached to @device using the
|
||||
* specified key. If no user data has been attached with the given
|
||||
* key this function returns %NULL.
|
||||
*
|
||||
* Return value: the user data previously attached or %NULL.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void *
|
||||
cairo_device_get_user_data (cairo_device_t *device,
|
||||
const cairo_user_data_key_t *key)
|
||||
{
|
||||
return _cairo_user_data_array_get_data (&device->user_data,
|
||||
key);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_device_set_user_data:
|
||||
* @device: a #cairo_device_t
|
||||
* @key: the address of a #cairo_user_data_key_t to attach the user data to
|
||||
* @user_data: the user data to attach to the #cairo_device_t
|
||||
* @destroy: a #cairo_destroy_func_t which will be called when the
|
||||
* #cairo_t is destroyed or when new user data is attached using the
|
||||
* same key.
|
||||
*
|
||||
* Attach user data to @device. To remove user data from a surface,
|
||||
* call this function with the key that was used to set it and %NULL
|
||||
* for @data.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
|
||||
* slot could not be allocated for the user data.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_device_set_user_data (cairo_device_t *device,
|
||||
const cairo_user_data_key_t *key,
|
||||
void *user_data,
|
||||
cairo_destroy_func_t destroy)
|
||||
{
|
||||
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
|
||||
return device->status;
|
||||
|
||||
return _cairo_user_data_array_set_data (&device->user_data,
|
||||
key, user_data, destroy);
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -39,6 +39,7 @@
|
||||
#include "cairo-directfb.h"
|
||||
|
||||
#include "cairo-clip-private.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
#include <pixman.h>
|
||||
|
||||
@ -564,6 +565,7 @@ _cairo_directfb_surface_create_internal (IDirectFB *dfb,
|
||||
|
||||
_cairo_surface_init (&surface->base,
|
||||
&_cairo_directfb_surface_backend,
|
||||
NULL, /* device */
|
||||
content);
|
||||
surface->pixman_format = _directfb_to_pixman_format (format);
|
||||
surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);
|
||||
@ -762,14 +764,14 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
pixman_image_composite (PIXMAN_OP_SRC,
|
||||
image_src->pixman_image,
|
||||
NULL,
|
||||
pixman_image,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height);
|
||||
pixman_image_composite32 (PIXMAN_OP_SRC,
|
||||
image_src->pixman_image,
|
||||
NULL,
|
||||
pixman_image,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
pixman_image_unref (pixman_image);
|
||||
|
||||
@ -1814,7 +1816,7 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
|
||||
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b, cairo_content_t content)
|
||||
_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b)
|
||||
{
|
||||
cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
|
||||
cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;
|
||||
@ -1955,6 +1957,7 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
|
||||
|
||||
_cairo_surface_init (&surface->base,
|
||||
&_cairo_directfb_surface_backend,
|
||||
NULL, /* device */
|
||||
_directfb_format_to_content (format));
|
||||
|
||||
return &surface->base;
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -39,56 +39,41 @@
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
typedef struct _cairo_drm_device cairo_drm_device_t;
|
||||
|
||||
struct udev_device;
|
||||
|
||||
cairo_public cairo_drm_device_t *
|
||||
cairo_public cairo_device_t *
|
||||
cairo_drm_device_get (struct udev_device *device);
|
||||
|
||||
cairo_public cairo_drm_device_t *
|
||||
cairo_public cairo_device_t *
|
||||
cairo_drm_device_get_for_fd (int fd);
|
||||
|
||||
cairo_public cairo_drm_device_t *
|
||||
cairo_public cairo_device_t *
|
||||
cairo_drm_device_default (void);
|
||||
|
||||
cairo_public cairo_drm_device_t *
|
||||
cairo_drm_device_reference (cairo_drm_device_t *device);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_drm_device_status (cairo_drm_device_t *device);
|
||||
|
||||
cairo_public int
|
||||
cairo_drm_device_get_fd (cairo_drm_device_t *device);
|
||||
cairo_drm_device_get_fd (cairo_device_t *device);
|
||||
|
||||
cairo_public void
|
||||
cairo_drm_device_throttle (cairo_drm_device_t *device);
|
||||
|
||||
cairo_public void
|
||||
cairo_drm_device_destroy (cairo_drm_device_t *device);
|
||||
|
||||
cairo_drm_device_throttle (cairo_device_t *device);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_drm_surface_create (cairo_drm_device_t *device,
|
||||
cairo_content_t content,
|
||||
cairo_drm_surface_create (cairo_device_t *device,
|
||||
cairo_format_t format,
|
||||
int width, int height);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_drm_surface_create_for_name (cairo_drm_device_t *device,
|
||||
cairo_drm_surface_create_for_name (cairo_device_t *device,
|
||||
unsigned int name,
|
||||
cairo_format_t format,
|
||||
int width, int height, int stride);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_drm_surface_create_from_cacheable_image (cairo_drm_device_t *device,
|
||||
cairo_drm_surface_create_from_cacheable_image (cairo_device_t *device,
|
||||
cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_drm_surface_enable_scan_out (cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_drm_device_t *
|
||||
cairo_drm_surface_get_device (cairo_surface_t *abstract_surface);
|
||||
|
||||
cairo_public unsigned int
|
||||
cairo_drm_surface_get_handle (cairo_surface_t *surface);
|
||||
|
||||
@ -120,7 +105,7 @@ cairo_drm_surface_get_stride (cairo_surface_t *surface);
|
||||
* will also disassociate the mapping.)
|
||||
*/
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_drm_surface_map (cairo_surface_t *surface);
|
||||
cairo_drm_surface_map_to_image (cairo_surface_t *surface);
|
||||
|
||||
cairo_public void
|
||||
cairo_drm_surface_unmap (cairo_surface_t *drm_surface,
|
||||
|
@ -34,13 +34,12 @@
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-win32-private.h"
|
||||
#include "cairo-surface-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
}
|
||||
|
||||
#include "cairo-d2d-private.h"
|
||||
#include "cairo-dwrite-private.h"
|
||||
#include <float.h>
|
||||
|
60
gfx/cairo/cairo/src/cairo-error-private.h
Normal file
60
gfx/cairo/cairo/src/cairo-error-private.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2002 University of Southern California
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_ERROR_PRIVATE_H_
|
||||
#define _CAIRO_ERROR_PRIVATE_H_
|
||||
|
||||
#include "cairo.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#define _cairo_status_is_error(status) \
|
||||
(status != CAIRO_STATUS_SUCCESS && status <= CAIRO_STATUS_LAST_STATUS)
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_error (cairo_status_t status);
|
||||
|
||||
/* hide compiler warnings when discarding the return value */
|
||||
#define _cairo_error_throw(status) do { \
|
||||
cairo_status_t status__ = _cairo_error (status); \
|
||||
(void) status__; \
|
||||
} while (0)
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* _CAIRO_ERROR_PRIVATE_H_ */
|
@ -89,6 +89,8 @@
|
||||
|
||||
@QUARTZ_FONT_FEATURE@
|
||||
|
||||
@TEE_SURFACE_FEATURE@
|
||||
|
||||
@PNG_FUNCTIONS_FEATURE@
|
||||
|
||||
@FC_FONT_FEATURE@
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -53,7 +53,7 @@
|
||||
#define CAIRO_FIXED_ONE_FLOAT ((float)(1 << CAIRO_FIXED_FRAC_BITS))
|
||||
#define CAIRO_FIXED_EPSILON ((cairo_fixed_t)(1))
|
||||
|
||||
#define CAIRO_FIXED_FRAC_MASK (((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))
|
||||
#define CAIRO_FIXED_FRAC_MASK ((cairo_fixed_t)(((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS)))
|
||||
#define CAIRO_FIXED_WHOLE_MASK (~CAIRO_FIXED_FRAC_MASK)
|
||||
|
||||
static inline cairo_fixed_t
|
||||
@ -136,6 +136,16 @@ _cairo_fixed_from_26_6 (uint32_t i)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_from_16_16 (uint32_t i)
|
||||
{
|
||||
#if CAIRO_FIXED_FRAC_BITS > 16
|
||||
return i << (CAIRO_FIXED_FRAC_BITS - 16);
|
||||
#else
|
||||
return i >> (16 - CAIRO_FIXED_FRAC_BITS);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline double
|
||||
_cairo_fixed_to_double (cairo_fixed_t f)
|
||||
{
|
||||
@ -154,12 +164,48 @@ _cairo_fixed_is_integer (cairo_fixed_t f)
|
||||
return (f & CAIRO_FIXED_FRAC_MASK) == 0;
|
||||
}
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_floor (cairo_fixed_t f)
|
||||
{
|
||||
return f & ~CAIRO_FIXED_FRAC_MASK;
|
||||
}
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_round (cairo_fixed_t f)
|
||||
{
|
||||
return _cairo_fixed_floor (f + (CAIRO_FIXED_FRAC_MASK+1)/2);
|
||||
}
|
||||
|
||||
static inline cairo_fixed_t
|
||||
_cairo_fixed_round_down (cairo_fixed_t f)
|
||||
{
|
||||
return _cairo_fixed_floor (f + CAIRO_FIXED_FRAC_MASK/2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_part (cairo_fixed_t f)
|
||||
{
|
||||
return f >> CAIRO_FIXED_FRAC_BITS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_round (cairo_fixed_t f)
|
||||
{
|
||||
return _cairo_fixed_integer_part (f + (CAIRO_FIXED_FRAC_MASK+1)/2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_round_down (cairo_fixed_t f)
|
||||
{
|
||||
return _cairo_fixed_integer_part (f + CAIRO_FIXED_FRAC_MASK/2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_fractional_part (cairo_fixed_t f)
|
||||
{
|
||||
return f & CAIRO_FIXED_FRAC_MASK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_integer_floor (cairo_fixed_t f)
|
||||
{
|
||||
@ -225,12 +271,18 @@ _cairo_fixed_16_16_from_double (double d)
|
||||
}
|
||||
|
||||
static inline int
|
||||
_cairo_fixed_16_16_floor (cairo_fixed_t f)
|
||||
_cairo_fixed_16_16_floor (cairo_fixed_16_16_t f)
|
||||
{
|
||||
if (f >= 0)
|
||||
return f >> 16;
|
||||
return f >> 16;
|
||||
else
|
||||
return -((-f - 1) >> 16) - 1;
|
||||
return -((-f - 1) >> 16) - 1;
|
||||
}
|
||||
|
||||
static inline double
|
||||
_cairo_fixed_16_16_to_double (cairo_fixed_16_16_t f)
|
||||
{
|
||||
return ((double) f) / (double) (1 << 16);
|
||||
}
|
||||
|
||||
#if CAIRO_FIXED_BITS == 32
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -39,6 +39,24 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:cairo-font-face
|
||||
* @Title: cairo_font_face_t
|
||||
* @Short_Description: Base class for font faces
|
||||
* @See_Also: #cairo_scaled_font_t
|
||||
*
|
||||
* #cairo_font_face_t represents a particular font at a particular weight,
|
||||
* slant, and other characteristic but no size, transformation, or size.
|
||||
*
|
||||
* Font faces are created using <firstterm>font-backend</firstterm>-specific
|
||||
* constructors, typically of the form
|
||||
* cairo_<emphasis>backend</emphasis>_font_face_create(), or implicitly
|
||||
* using the <firstterm>toy</firstterm> text API by way of
|
||||
* cairo_select_font_face(). The resulting face can be accessed using
|
||||
* cairo_get_font_face().
|
||||
*/
|
||||
|
||||
/* #cairo_font_face_t */
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -35,12 +35,27 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-error-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:cairo-font-options
|
||||
* @Title: cairo_font_options_t
|
||||
* @Short_Description: How a font should be rendered
|
||||
* @See_Also: #cairo_scaled_font_t
|
||||
*
|
||||
* The font options specify how fonts should be rendered. Most of the
|
||||
* time the font options implied by a surface are just right and do not
|
||||
* need any changes, but for pixel-based targets tweaking font options
|
||||
* may result in superior output on a particular display.
|
||||
*/
|
||||
|
||||
static const cairo_font_options_t _cairo_font_options_nil = {
|
||||
CAIRO_ANTIALIAS_DEFAULT,
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT,
|
||||
CAIRO_LCD_FILTER_DEFAULT,
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_METRICS_DEFAULT
|
||||
CAIRO_HINT_METRICS_DEFAULT,
|
||||
CAIRO_ROUND_GLYPH_POS_DEFAULT
|
||||
};
|
||||
|
||||
/**
|
||||
@ -54,8 +69,10 @@ _cairo_font_options_init_default (cairo_font_options_t *options)
|
||||
{
|
||||
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
options->lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
|
||||
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||
options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
@ -64,8 +81,10 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
|
||||
{
|
||||
options->antialias = other->antialias;
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
options->lcd_filter = other->lcd_filter;
|
||||
options->hint_style = other->hint_style;
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
options->round_glyph_positions = other->round_glyph_positions;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,10 +208,14 @@ cairo_font_options_merge (cairo_font_options_t *options,
|
||||
options->antialias = other->antialias;
|
||||
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
if (other->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
|
||||
options->lcd_filter = other->lcd_filter;
|
||||
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
|
||||
options->hint_style = other->hint_style;
|
||||
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
if (other->round_glyph_positions != CAIRO_ROUND_GLYPH_POS_DEFAULT)
|
||||
options->round_glyph_positions = other->round_glyph_positions;
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_merge);
|
||||
|
||||
@ -221,8 +244,10 @@ cairo_font_options_equal (const cairo_font_options_t *options,
|
||||
|
||||
return (options->antialias == other->antialias &&
|
||||
options->subpixel_order == other->subpixel_order &&
|
||||
options->lcd_filter == other->lcd_filter &&
|
||||
options->hint_style == other->hint_style &&
|
||||
options->hint_metrics == other->hint_metrics);
|
||||
options->hint_metrics == other->hint_metrics &&
|
||||
options->round_glyph_positions == other->round_glyph_positions);
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_equal);
|
||||
|
||||
@ -246,7 +271,8 @@ cairo_font_options_hash (const cairo_font_options_t *options)
|
||||
|
||||
return ((options->antialias) |
|
||||
(options->subpixel_order << 4) |
|
||||
(options->hint_style << 8) |
|
||||
(options->lcd_filter << 8) |
|
||||
(options->hint_style << 12) |
|
||||
(options->hint_metrics << 16));
|
||||
}
|
||||
slim_hidden_def (cairo_font_options_hash);
|
||||
@ -327,6 +353,87 @@ cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
|
||||
return options->subpixel_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_font_options_set_lcd_filter:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @lcd_filter: the new LCD filter
|
||||
*
|
||||
* Sets the LCD filter for the font options object. The LCD filter
|
||||
* specifies how pixels are filtered when rendered with an antialiasing
|
||||
* mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
|
||||
* #cairo_lcd_filter_t for full details.
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
void
|
||||
_cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
|
||||
cairo_lcd_filter_t lcd_filter)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->lcd_filter = lcd_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_font_options_get_lcd_filter:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the LCD filter for the font options object.
|
||||
* See the documentation for #cairo_lcd_filter_t for full details.
|
||||
*
|
||||
* Return value: the LCD filter for the font options object
|
||||
*
|
||||
* Since: 1.8
|
||||
**/
|
||||
cairo_lcd_filter_t
|
||||
_cairo_font_options_get_lcd_filter (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_LCD_FILTER_DEFAULT;
|
||||
|
||||
return options->lcd_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_font_options_set_round_glyph_positions:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @round: the new rounding value
|
||||
*
|
||||
* Sets the rounding options for the font options object. If rounding is set, a
|
||||
* glyph's position will be rounded to integer values.
|
||||
*
|
||||
* Since: 1.12
|
||||
**/
|
||||
void
|
||||
_cairo_font_options_set_round_glyph_positions (cairo_font_options_t *options,
|
||||
cairo_round_glyph_positions_t round)
|
||||
{
|
||||
if (cairo_font_options_status (options))
|
||||
return;
|
||||
|
||||
options->round_glyph_positions = round;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_font_options_get_round_glyph_positions:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the glyph position rounding option for the font options object.
|
||||
*
|
||||
* Return value: The round glyph posistions flag for the font options object.
|
||||
*
|
||||
* Since: 1.12
|
||||
**/
|
||||
cairo_round_glyph_positions_t
|
||||
_cairo_font_options_get_round_glyph_positions (const cairo_font_options_t *options)
|
||||
{
|
||||
if (cairo_font_options_status ((cairo_font_options_t *) options))
|
||||
return CAIRO_ROUND_GLYPH_POS_DEFAULT;
|
||||
|
||||
return options->round_glyph_positions;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_hint_style:
|
||||
* @options: a #cairo_font_options_t
|
||||
|
78
gfx/cairo/cairo/src/cairo-fontconfig-private.h
Normal file
78
gfx/cairo/cairo/src/cairo-fontconfig-private.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2000 Keith Packard
|
||||
* Copyright © 2005 Red Hat, Inc
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Graydon Hoare <graydon@redhat.com>
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Keith Packard <keithp@keithp.com>
|
||||
* Carl Worth <cworth@cworth.org>
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_FONTCONFIG_PRIVATE_H
|
||||
#define _CAIRO_FONTCONFIG_PRIVATE_H
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
#endif
|
||||
|
||||
/* sub-pixel order */
|
||||
#ifndef FC_RGBA_UNKNOWN
|
||||
#define FC_RGBA_UNKNOWN 0
|
||||
#define FC_RGBA_RGB 1
|
||||
#define FC_RGBA_BGR 2
|
||||
#define FC_RGBA_VRGB 3
|
||||
#define FC_RGBA_VBGR 4
|
||||
#define FC_RGBA_NONE 5
|
||||
#endif
|
||||
|
||||
/* hinting style */
|
||||
#ifndef FC_HINT_NONE
|
||||
#define FC_HINT_NONE 0
|
||||
#define FC_HINT_SLIGHT 1
|
||||
#define FC_HINT_MEDIUM 2
|
||||
#define FC_HINT_FULL 3
|
||||
#endif
|
||||
|
||||
/* LCD filter */
|
||||
#ifndef FC_LCD_NONE
|
||||
#define FC_LCD_NONE 0
|
||||
#define FC_LCD_DEFAULT 1
|
||||
#define FC_LCD_LIGHT 2
|
||||
#define FC_LCD_LEGACY 3
|
||||
#endif
|
||||
|
||||
#endif /* _CAIRO_FONTCONFIG_PRIVATE_H */
|
129
gfx/cairo/cairo/src/cairo-freed-pool-private.h
Normal file
129
gfx/cairo/cairo/src/cairo-freed-pool-private.h
Normal file
@ -0,0 +1,129 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_FREED_POOL_H
|
||||
#define CAIRO_FREED_POOL_H
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-atomic-private.h"
|
||||
|
||||
#if HAS_ATOMIC_OPS
|
||||
/* Keep a stash of recently freed clip_paths, since we need to
|
||||
* reallocate them frequently.
|
||||
*/
|
||||
#define MAX_FREED_POOL_SIZE 4
|
||||
typedef struct {
|
||||
void *pool[MAX_FREED_POOL_SIZE];
|
||||
int top;
|
||||
} freed_pool_t;
|
||||
|
||||
static cairo_always_inline void *
|
||||
_atomic_fetch (void **slot)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
do {
|
||||
ptr = _cairo_atomic_ptr_get (slot);
|
||||
} while (! _cairo_atomic_ptr_cmpxchg (slot, ptr, NULL));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static cairo_always_inline cairo_bool_t
|
||||
_atomic_store (void **slot, void *ptr)
|
||||
{
|
||||
return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr);
|
||||
}
|
||||
|
||||
cairo_private void *
|
||||
_freed_pool_get_search (freed_pool_t *pool);
|
||||
|
||||
static inline void *
|
||||
_freed_pool_get (freed_pool_t *pool)
|
||||
{
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
i = pool->top - 1;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (likely (ptr != NULL)) {
|
||||
pool->top = i;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* either empty or contended */
|
||||
return _freed_pool_get_search (pool);
|
||||
}
|
||||
|
||||
cairo_private void
|
||||
_freed_pool_put_search (freed_pool_t *pool, void *ptr);
|
||||
|
||||
static inline void
|
||||
_freed_pool_put (freed_pool_t *pool, void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = pool->top;
|
||||
if (likely (i < ARRAY_LENGTH (pool->pool) &&
|
||||
_atomic_store (&pool->pool[i], ptr)))
|
||||
{
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* either full or contended */
|
||||
_freed_pool_put_search (pool, ptr);
|
||||
}
|
||||
|
||||
cairo_private void
|
||||
_freed_pool_reset (freed_pool_t *pool);
|
||||
|
||||
#define HAS_FREED_POOL 1
|
||||
|
||||
#else
|
||||
|
||||
typedef int freed_pool_t;
|
||||
|
||||
#define _freed_pool_get(pool) NULL
|
||||
#define _freed_pool_put(pool, ptr) free(ptr)
|
||||
#define _freed_pool_reset(ptr)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* CAIRO_FREED_POOL_PRIVATE_H */
|
93
gfx/cairo/cairo/src/cairo-freed-pool.c
Normal file
93
gfx/cairo/cairo/src/cairo-freed-pool.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.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/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-freed-pool-private.h"
|
||||
|
||||
#if HAS_FREED_POOL
|
||||
|
||||
void *
|
||||
_freed_pool_get_search (freed_pool_t *pool)
|
||||
{
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_LENGTH (pool->pool); i--;) {
|
||||
ptr = _atomic_fetch (&pool->pool[i]);
|
||||
if (ptr != NULL) {
|
||||
pool->top = i;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* empty */
|
||||
pool->top = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_freed_pool_put_search (freed_pool_t *pool, void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
if (_atomic_store (&pool->pool[i], ptr)) {
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* full */
|
||||
pool->top = i;
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
_freed_pool_reset (freed_pool_t *pool)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
free (pool->pool[i]);
|
||||
pool->pool[i] = NULL;
|
||||
}
|
||||
|
||||
pool->top = 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-freelist-type-private.h"
|
||||
|
||||
/* for stand-alone compilation*/
|
||||
#ifndef VG
|
||||
@ -34,32 +35,6 @@
|
||||
#define NULL (void *) 0
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_freelist_node cairo_freelist_node_t;
|
||||
struct _cairo_freelist_node {
|
||||
cairo_freelist_node_t *next;
|
||||
};
|
||||
|
||||
typedef struct _cairo_freelist {
|
||||
cairo_freelist_node_t *first_free_node;
|
||||
unsigned nodesize;
|
||||
} cairo_freelist_t;
|
||||
|
||||
typedef struct _cairo_freelist_pool cairo_freelist_pool_t;
|
||||
struct _cairo_freelist_pool {
|
||||
cairo_freelist_pool_t *next;
|
||||
unsigned size, rem;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
typedef struct _cairo_freepool {
|
||||
cairo_freelist_node_t *first_free_node;
|
||||
cairo_freelist_pool_t *pools;
|
||||
unsigned nodesize;
|
||||
cairo_freelist_pool_t embedded_pool;
|
||||
uint8_t embedded_data[1000];
|
||||
} cairo_freepool_t;
|
||||
|
||||
|
||||
/* Initialise a freelist that will be responsible for allocating
|
||||
* nodes of size nodesize. */
|
||||
cairo_private void
|
||||
@ -96,6 +71,20 @@ _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize);
|
||||
cairo_private void
|
||||
_cairo_freepool_fini (cairo_freepool_t *freepool);
|
||||
|
||||
static inline void
|
||||
_cairo_freepool_reset (cairo_freepool_t *freepool)
|
||||
{
|
||||
while (freepool->pools != &freepool->embedded_pool) {
|
||||
cairo_freelist_pool_t *pool = freepool->pools;
|
||||
freepool->pools = pool->next;
|
||||
pool->next = freepool->freepools;
|
||||
freepool->freepools = pool;
|
||||
}
|
||||
|
||||
freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
|
||||
freepool->embedded_pool.data = freepool->embedded_data;
|
||||
}
|
||||
|
||||
cairo_private void *
|
||||
_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool);
|
||||
|
||||
|
54
gfx/cairo/cairo/src/cairo-freelist-type-private.h
Normal file
54
gfx/cairo/cairo/src/cairo-freelist-type-private.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2010 Joonas Pihlaja
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef CAIRO_FREELIST_TYPE_H
|
||||
#define CAIRO_FREELIST_TYPE_H
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
typedef struct _cairo_freelist_node cairo_freelist_node_t;
|
||||
struct _cairo_freelist_node {
|
||||
cairo_freelist_node_t *next;
|
||||
};
|
||||
|
||||
typedef struct _cairo_freelist {
|
||||
cairo_freelist_node_t *first_free_node;
|
||||
unsigned nodesize;
|
||||
} cairo_freelist_t;
|
||||
|
||||
typedef struct _cairo_freelist_pool cairo_freelist_pool_t;
|
||||
struct _cairo_freelist_pool {
|
||||
cairo_freelist_pool_t *next;
|
||||
unsigned size, rem;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
typedef struct _cairo_freepool {
|
||||
cairo_freelist_node_t *first_free_node;
|
||||
cairo_freelist_pool_t *pools;
|
||||
cairo_freelist_pool_t *freepools;
|
||||
unsigned nodesize;
|
||||
cairo_freelist_pool_t embedded_pool;
|
||||
uint8_t embedded_data[1000];
|
||||
} cairo_freepool_t;
|
||||
|
||||
#endif /* CAIRO_FREELIST_TYPE_H */
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-freelist-private.h"
|
||||
|
||||
void
|
||||
@ -83,12 +84,12 @@ _cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize)
|
||||
{
|
||||
freepool->first_free_node = NULL;
|
||||
freepool->pools = &freepool->embedded_pool;
|
||||
freepool->freepools = NULL;
|
||||
freepool->nodesize = nodesize;
|
||||
|
||||
freepool->embedded_pool.next = NULL;
|
||||
@ -96,19 +97,28 @@ _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize)
|
||||
freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
|
||||
freepool->embedded_pool.data = freepool->embedded_data;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data,
|
||||
sizeof (freepool->embedded_data)));
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data, sizeof (freepool->embedded_data)));
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_freepool_fini (cairo_freepool_t *freepool)
|
||||
{
|
||||
cairo_freelist_pool_t *pool = freepool->pools;
|
||||
cairo_freelist_pool_t *pool;
|
||||
|
||||
pool = freepool->pools;
|
||||
while (pool != &freepool->embedded_pool) {
|
||||
cairo_freelist_pool_t *next = pool->next;
|
||||
free (pool);
|
||||
pool = next;
|
||||
}
|
||||
|
||||
pool = freepool->freepools;
|
||||
while (pool != NULL) {
|
||||
cairo_freelist_pool_t *next = pool->next;
|
||||
free (pool);
|
||||
pool = next;
|
||||
}
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
|
||||
}
|
||||
|
||||
@ -118,23 +128,31 @@ _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
|
||||
cairo_freelist_pool_t *pool;
|
||||
int poolsize;
|
||||
|
||||
if (freepool->pools != &freepool->embedded_pool)
|
||||
poolsize = 2 * freepool->pools->size;
|
||||
else
|
||||
poolsize = (128 * freepool->nodesize + 8191) & -8192;
|
||||
pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
|
||||
if (unlikely (pool == NULL))
|
||||
return pool;
|
||||
if (freepool->freepools != NULL) {
|
||||
pool = freepool->freepools;
|
||||
freepool->freepools = pool->next;
|
||||
|
||||
poolsize = pool->size;
|
||||
} else {
|
||||
if (freepool->pools != &freepool->embedded_pool)
|
||||
poolsize = 2 * freepool->pools->size;
|
||||
else
|
||||
poolsize = (128 * freepool->nodesize + 8191) & -8192;
|
||||
|
||||
pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
|
||||
if (unlikely (pool == NULL))
|
||||
return pool;
|
||||
|
||||
pool->size = poolsize;
|
||||
}
|
||||
|
||||
pool->next = freepool->pools;
|
||||
freepool->pools = pool;
|
||||
|
||||
pool->size = poolsize;
|
||||
pool->rem = poolsize - freepool->nodesize;
|
||||
pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, pool->rem));
|
||||
|
||||
return pool + 1;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
@ -41,14 +41,12 @@
|
||||
#define _BSD_SOURCE /* for strdup() */
|
||||
#include "cairoint.h"
|
||||
|
||||
#include "cairo-error-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
#endif
|
||||
#include "cairo-fontconfig-private.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@ -59,6 +57,30 @@
|
||||
#include FT_SYNTHESIS_H
|
||||
#endif
|
||||
|
||||
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
||||
#include FT_LCD_FILTER_H
|
||||
#endif
|
||||
|
||||
/* Fontconfig version older than 2.6 didn't have these options */
|
||||
#ifndef FC_LCD_FILTER
|
||||
#define FC_LCD_FILTER "lcdfilter"
|
||||
#endif
|
||||
/* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */
|
||||
#ifndef FC_LCD_NONE
|
||||
#define FC_LCD_NONE 0
|
||||
#define FC_LCD_DEFAULT 1
|
||||
#define FC_LCD_LIGHT 2
|
||||
#define FC_LCD_LEGACY 3
|
||||
#endif
|
||||
|
||||
/* FreeType version older than 2.3.5(?) didn't have these options */
|
||||
#ifndef FT_LCD_FILTER_NONE
|
||||
#define FT_LCD_FILTER_NONE 0
|
||||
#define FT_LCD_FILTER_DEFAULT 1
|
||||
#define FT_LCD_FILTER_LIGHT 2
|
||||
#define FT_LCD_FILTER_LEGACY 16
|
||||
#endif
|
||||
|
||||
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
|
||||
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
|
||||
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
|
||||
@ -67,11 +89,35 @@
|
||||
/* This is the max number of FT_face objects we keep open at once
|
||||
*/
|
||||
#define MAX_OPEN_FACES 10
|
||||
|
||||
/* This is the maximum font size we allow to be passed to FT_Set_Char_Size
|
||||
*/
|
||||
#define MAX_FONT_SIZE 1000
|
||||
|
||||
/**
|
||||
* SECTION:cairo-ft
|
||||
* @Title: FreeType Fonts
|
||||
* @Short_Description: Font support for FreeType
|
||||
* @See_Also: #cairo_font_face_t
|
||||
*
|
||||
* The FreeType font backend is primarily used to render text on GNU/Linux
|
||||
* systems, but can be used on other platforms too.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAIRO_HAS_FT_FONT:
|
||||
*
|
||||
* Defined if the FreeType font backend is available.
|
||||
* This macro can be used to conditionally compile backend-specific code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CAIRO_HAS_FC_FONT:
|
||||
*
|
||||
* Defined if the Fontconfig-specific functions of the FreeType font backend
|
||||
* are available.
|
||||
* This macro can be used to conditionally compile backend-specific code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The simple 2x2 matrix is converted into separate scale and shape
|
||||
* factors so that hinting works right
|
||||
@ -180,6 +226,7 @@ typedef struct _cairo_ft_unscaled_font_map {
|
||||
|
||||
static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
|
||||
|
||||
|
||||
static void
|
||||
_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
|
||||
cairo_ft_unscaled_font_t *unscaled)
|
||||
@ -779,23 +826,279 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Empirically-derived subpixel filtering values thanks to Keith
|
||||
* Packard and libXft. */
|
||||
static const int filters[3][3] = {
|
||||
/* red */
|
||||
#if 0
|
||||
{ 65538*4/7,65538*2/7,65538*1/7 },
|
||||
/* green */
|
||||
{ 65536*1/4, 65536*2/4, 65537*1/4 },
|
||||
/* blue */
|
||||
{ 65538*1/7,65538*2/7,65538*4/7 },
|
||||
#endif
|
||||
{ 65538*9/13,65538*3/13,65538*1/13 },
|
||||
/* green */
|
||||
{ 65538*1/6, 65538*4/6, 65538*1/6 },
|
||||
/* blue */
|
||||
{ 65538*1/13,65538*3/13,65538*9/13 },
|
||||
};
|
||||
/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
|
||||
* into a different format. For example, we want to convert a
|
||||
* FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
|
||||
* ARGB or ABGR bitmap.
|
||||
*
|
||||
* this function prepares a target descriptor for this operation.
|
||||
*
|
||||
* input :: target bitmap descriptor. The function will set its
|
||||
* 'width', 'rows' and 'pitch' fields, and only these
|
||||
*
|
||||
* slot :: the glyph slot containing the source bitmap. this
|
||||
* function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
|
||||
*
|
||||
* mode :: the requested final rendering mode. supported values are
|
||||
* MONO, NORMAL (i.e. gray), LCD and LCD_V
|
||||
*
|
||||
* the function returns the size in bytes of the corresponding buffer,
|
||||
* it's up to the caller to allocate the corresponding memory block
|
||||
* before calling _fill_xrender_bitmap
|
||||
*
|
||||
* it also returns -1 in case of error (e.g. incompatible arguments,
|
||||
* like trying to convert a gray bitmap into a monochrome one)
|
||||
*/
|
||||
static int
|
||||
_compute_xrender_bitmap_size(FT_Bitmap *target,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Render_Mode mode)
|
||||
{
|
||||
FT_Bitmap *ftbit;
|
||||
int width, height, pitch;
|
||||
|
||||
if (slot->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
return -1;
|
||||
|
||||
/* compute the size of the final bitmap */
|
||||
ftbit = &slot->bitmap;
|
||||
|
||||
width = ftbit->width;
|
||||
height = ftbit->rows;
|
||||
pitch = (width + 3) & ~3;
|
||||
|
||||
switch (ftbit->pixel_mode) {
|
||||
case FT_PIXEL_MODE_MONO:
|
||||
if (mode == FT_RENDER_MODE_MONO) {
|
||||
pitch = (((width + 31) & ~31) >> 3);
|
||||
break;
|
||||
}
|
||||
/* fall-through */
|
||||
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
if (mode == FT_RENDER_MODE_LCD ||
|
||||
mode == FT_RENDER_MODE_LCD_V)
|
||||
{
|
||||
/* each pixel is replicated into a 32-bit ARGB value */
|
||||
pitch = width * 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if (mode != FT_RENDER_MODE_LCD)
|
||||
return -1;
|
||||
|
||||
/* horz pixel triplets are packed into 32-bit ARGB values */
|
||||
width /= 3;
|
||||
pitch = width * 4;
|
||||
break;
|
||||
|
||||
case FT_PIXEL_MODE_LCD_V:
|
||||
if (mode != FT_RENDER_MODE_LCD_V)
|
||||
return -1;
|
||||
|
||||
/* vert pixel triplets are packed into 32-bit ARGB values */
|
||||
height /= 3;
|
||||
pitch = width * 4;
|
||||
break;
|
||||
|
||||
default: /* unsupported source format */
|
||||
return -1;
|
||||
}
|
||||
|
||||
target->width = width;
|
||||
target->rows = height;
|
||||
target->pitch = pitch;
|
||||
target->buffer = NULL;
|
||||
|
||||
return pitch * height;
|
||||
}
|
||||
|
||||
/* this functions converts the glyph bitmap found in a FT_GlyphSlot
|
||||
* into a different format (see _compute_xrender_bitmap_size)
|
||||
*
|
||||
* you should call this function after _compute_xrender_bitmap_size
|
||||
*
|
||||
* target :: target bitmap descriptor. Note that its 'buffer' pointer
|
||||
* must point to memory allocated by the caller
|
||||
*
|
||||
* slot :: the glyph slot containing the source bitmap
|
||||
*
|
||||
* mode :: the requested final rendering mode
|
||||
*
|
||||
* bgr :: boolean, set if BGR or VBGR pixel ordering is needed
|
||||
*/
|
||||
static void
|
||||
_fill_xrender_bitmap(FT_Bitmap *target,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Render_Mode mode,
|
||||
int bgr)
|
||||
{
|
||||
FT_Bitmap *ftbit = &slot->bitmap;
|
||||
unsigned char *srcLine = ftbit->buffer;
|
||||
unsigned char *dstLine = target->buffer;
|
||||
int src_pitch = ftbit->pitch;
|
||||
int width = target->width;
|
||||
int height = target->rows;
|
||||
int pitch = target->pitch;
|
||||
int subpixel;
|
||||
int h;
|
||||
|
||||
subpixel = (mode == FT_RENDER_MODE_LCD ||
|
||||
mode == FT_RENDER_MODE_LCD_V);
|
||||
|
||||
if (src_pitch < 0)
|
||||
srcLine -= src_pitch * (ftbit->rows - 1);
|
||||
|
||||
target->pixel_mode = ftbit->pixel_mode;
|
||||
|
||||
switch (ftbit->pixel_mode) {
|
||||
case FT_PIXEL_MODE_MONO:
|
||||
if (subpixel) {
|
||||
/* convert mono to ARGB32 values */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
|
||||
((unsigned int *) dstLine)[x] = 0xffffffffU;
|
||||
}
|
||||
}
|
||||
target->pixel_mode = FT_PIXEL_MODE_LCD;
|
||||
|
||||
} else if (mode == FT_RENDER_MODE_NORMAL) {
|
||||
/* convert mono to 8-bit gray */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
if (srcLine[(x >> 3)] & (0x80 >> (x & 7)))
|
||||
dstLine[x] = 0xff;
|
||||
}
|
||||
}
|
||||
target->pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
|
||||
} else {
|
||||
/* copy mono to mono */
|
||||
|
||||
int bytes = (width + 7) >> 3;
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
|
||||
memcpy (dstLine, srcLine, bytes);
|
||||
}
|
||||
break;
|
||||
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
if (subpixel) {
|
||||
/* convert gray to ARGB32 values */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
unsigned int *dst = (unsigned int *) dstLine;
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
unsigned int pix = srcLine[x];
|
||||
|
||||
pix |= (pix << 8);
|
||||
pix |= (pix << 16);
|
||||
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
target->pixel_mode = FT_PIXEL_MODE_LCD;
|
||||
} else {
|
||||
/* copy gray into gray */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
|
||||
memcpy (dstLine, srcLine, width);
|
||||
}
|
||||
break;
|
||||
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if (!bgr) {
|
||||
/* convert horizontal RGB into ARGB32 */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
unsigned char *src = srcLine;
|
||||
unsigned int *dst = (unsigned int *) dstLine;
|
||||
|
||||
for (x = 0; x < width; x++, src += 3) {
|
||||
unsigned int pix;
|
||||
|
||||
pix = ((unsigned int)src[0] << 16) |
|
||||
((unsigned int)src[1] << 8) |
|
||||
((unsigned int)src[2] ) |
|
||||
((unsigned int)src[1] << 24) ;
|
||||
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* convert horizontal BGR into ARGB32 */
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) {
|
||||
|
||||
int x;
|
||||
unsigned char *src = srcLine;
|
||||
unsigned int *dst = (unsigned int *) dstLine;
|
||||
|
||||
for (x = 0; x < width; x++, src += 3) {
|
||||
unsigned int pix;
|
||||
|
||||
pix = ((unsigned int)src[2] << 16) |
|
||||
((unsigned int)src[1] << 8) |
|
||||
((unsigned int)src[0] ) |
|
||||
((unsigned int)src[1] << 24) ;
|
||||
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* FT_PIXEL_MODE_LCD_V */
|
||||
/* convert vertical RGB into ARGB32 */
|
||||
if (!bgr) {
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += 3 * src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
unsigned char* src = srcLine;
|
||||
unsigned int* dst = (unsigned int *) dstLine;
|
||||
|
||||
for (x = 0; x < width; x++, src += 1) {
|
||||
unsigned int pix;
|
||||
pix = ((unsigned int)src[0] << 16) |
|
||||
((unsigned int)src[src_pitch] << 8) |
|
||||
((unsigned int)src[src_pitch*2] ) |
|
||||
((unsigned int)src[src_pitch] << 24) ;
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
for (h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch) {
|
||||
int x;
|
||||
unsigned char *src = srcLine;
|
||||
unsigned int *dst = (unsigned int *) dstLine;
|
||||
|
||||
for (x = 0; x < width; x++, src += 1) {
|
||||
unsigned int pix;
|
||||
|
||||
pix = ((unsigned int)src[src_pitch * 2] << 16) |
|
||||
((unsigned int)src[src_pitch] << 8) |
|
||||
((unsigned int)src[0] ) |
|
||||
((unsigned int)src[src_pitch] << 24) ;
|
||||
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Fills in val->image with an image surface created from @bitmap
|
||||
*/
|
||||
@ -808,6 +1111,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
int width, height, stride;
|
||||
unsigned char *data;
|
||||
int format = CAIRO_FORMAT_A8;
|
||||
cairo_image_surface_t *image;
|
||||
|
||||
width = bitmap->width;
|
||||
height = bitmap->rows;
|
||||
@ -864,11 +1168,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
case FT_PIXEL_MODE_LCD_V:
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
switch (font_options->antialias) {
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
default:
|
||||
if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
|
||||
stride = bitmap->pitch;
|
||||
if (own_buffer) {
|
||||
data = bitmap->buffer;
|
||||
@ -879,104 +1179,18 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
}
|
||||
format = CAIRO_FORMAT_A8;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL: {
|
||||
int x, y;
|
||||
unsigned char *in_line, *out_line, *in;
|
||||
unsigned int *out;
|
||||
unsigned int red, green, blue;
|
||||
int rf, gf, bf;
|
||||
int s;
|
||||
int o, os;
|
||||
unsigned char *data_rgba;
|
||||
unsigned int width_rgba, stride_rgba;
|
||||
int vmul = 1;
|
||||
int hmul = 1;
|
||||
|
||||
switch (font_options->subpixel_order) {
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
default:
|
||||
width /= 3;
|
||||
hmul = 3;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
vmul = 3;
|
||||
height /= 3;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Filter the glyph to soften the color fringes
|
||||
*/
|
||||
width_rgba = width;
|
||||
stride = bitmap->pitch;
|
||||
stride_rgba = (width_rgba * 4 + 3) & ~3;
|
||||
data_rgba = calloc (stride_rgba, height);
|
||||
if (unlikely (data_rgba == NULL)) {
|
||||
if (own_buffer)
|
||||
free (bitmap->buffer);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
format = CAIRO_FORMAT_A8;
|
||||
} else {
|
||||
/* if we get there, the data from the source bitmap
|
||||
* really comes from _fill_xrender_bitmap, and is
|
||||
* made of 32-bit ARGB or ABGR values */
|
||||
assert (own_buffer != 0);
|
||||
assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
|
||||
|
||||
os = 1;
|
||||
switch (font_options->subpixel_order) {
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
os = stride;
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
default:
|
||||
rf = 0;
|
||||
gf = 1;
|
||||
bf = 2;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
os = stride;
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
bf = 0;
|
||||
gf = 1;
|
||||
rf = 2;
|
||||
break;
|
||||
}
|
||||
in_line = bitmap->buffer;
|
||||
out_line = data_rgba;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
in = in_line;
|
||||
out = (unsigned int *) out_line;
|
||||
in_line += stride * vmul;
|
||||
out_line += stride_rgba;
|
||||
for (x = 0; x < width * hmul; x += hmul)
|
||||
{
|
||||
red = green = blue = 0;
|
||||
o = 0;
|
||||
for (s = 0; s < 3; s++)
|
||||
{
|
||||
red += filters[rf][s]*in[x+o];
|
||||
green += filters[gf][s]*in[x+o];
|
||||
blue += filters[bf][s]*in[x+o];
|
||||
o += os;
|
||||
}
|
||||
red = red / 65536;
|
||||
green = green / 65536;
|
||||
blue = blue / 65536;
|
||||
*out++ = (green << 24) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Images here are stored in native format. The
|
||||
* backend must convert to its own format as needed
|
||||
*/
|
||||
|
||||
if (own_buffer)
|
||||
free (bitmap->buffer);
|
||||
data = data_rgba;
|
||||
stride = stride_rgba;
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
}
|
||||
data = bitmap->buffer;
|
||||
stride = bitmap->pitch;
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
}
|
||||
break;
|
||||
case FT_PIXEL_MODE_GRAY2:
|
||||
@ -988,18 +1202,22 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
*surface = (cairo_image_surface_t *)
|
||||
/* XXX */
|
||||
*surface = image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (data,
|
||||
format,
|
||||
width, height, stride);
|
||||
if ((*surface)->base.status) {
|
||||
if (image->base.status) {
|
||||
free (data);
|
||||
return (*surface)->base.status;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data ((*surface));
|
||||
if (format == CAIRO_FORMAT_ARGB32)
|
||||
pixman_image_set_component_alpha (image->pixman_image, TRUE);
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&(*surface)->base);
|
||||
_cairo_image_surface_assume_ownership_of_data (image);
|
||||
|
||||
_cairo_debug_check_image_surface_is_defined (&image->base);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1024,16 +1242,59 @@ _render_glyph_outline (FT_Face face,
|
||||
cairo_font_options_t *font_options,
|
||||
cairo_image_surface_t **surface)
|
||||
{
|
||||
int rgba = FC_RGBA_UNKNOWN;
|
||||
int lcd_filter = FT_LCD_FILTER_LEGACY;
|
||||
FT_GlyphSlot glyphslot = face->glyph;
|
||||
FT_Outline *outline = &glyphslot->outline;
|
||||
FT_Bitmap bitmap;
|
||||
FT_BBox cbox;
|
||||
FT_Matrix matrix;
|
||||
int hmul = 1;
|
||||
int vmul = 1;
|
||||
unsigned int width, height, stride;
|
||||
cairo_bool_t subpixel = FALSE;
|
||||
unsigned int width, height;
|
||||
cairo_status_t status;
|
||||
FT_Error fterror;
|
||||
FT_Library library = glyphslot->library;
|
||||
FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
|
||||
|
||||
switch (font_options->antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
render_mode = FT_RENDER_MODE_MONO;
|
||||
break;
|
||||
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
switch (font_options->subpixel_order) {
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
render_mode = FT_RENDER_MODE_LCD;
|
||||
break;
|
||||
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
render_mode = FT_RENDER_MODE_LCD_V;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (font_options->lcd_filter) {
|
||||
case CAIRO_LCD_FILTER_NONE:
|
||||
lcd_filter = FT_LCD_FILTER_NONE;
|
||||
break;
|
||||
case CAIRO_LCD_FILTER_DEFAULT:
|
||||
case CAIRO_LCD_FILTER_INTRA_PIXEL:
|
||||
lcd_filter = FT_LCD_FILTER_LEGACY;
|
||||
break;
|
||||
case CAIRO_LCD_FILTER_FIR3:
|
||||
lcd_filter = FT_LCD_FILTER_LIGHT;
|
||||
break;
|
||||
case CAIRO_LCD_FILTER_FIR5:
|
||||
lcd_filter = FT_LCD_FILTER_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
render_mode = FT_RENDER_MODE_NORMAL;
|
||||
}
|
||||
|
||||
FT_Outline_Get_CBox (outline, &cbox);
|
||||
|
||||
@ -1044,20 +1305,21 @@ _render_glyph_outline (FT_Face face,
|
||||
|
||||
width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
|
||||
height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
|
||||
stride = (width * hmul + 3) & ~3;
|
||||
|
||||
if (width * height == 0) {
|
||||
cairo_format_t format;
|
||||
/* Looks like fb handles zero-sized images just fine */
|
||||
switch (font_options->antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
switch (render_mode) {
|
||||
case FT_RENDER_MODE_MONO:
|
||||
format = CAIRO_FORMAT_A1;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
case FT_RENDER_MODE_LCD:
|
||||
case FT_RENDER_MODE_LCD_V:
|
||||
format= CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
case FT_RENDER_MODE_LIGHT:
|
||||
case FT_RENDER_MODE_NORMAL:
|
||||
case FT_RENDER_MODE_MAX:
|
||||
default:
|
||||
format = CAIRO_FORMAT_A8;
|
||||
break;
|
||||
@ -1067,75 +1329,74 @@ _render_glyph_outline (FT_Face face,
|
||||
cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
|
||||
if ((*surface)->base.status)
|
||||
return (*surface)->base.status;
|
||||
} else {
|
||||
} else {
|
||||
|
||||
matrix.xx = matrix.yy = 0x10000L;
|
||||
matrix.xy = matrix.yx = 0;
|
||||
int bitmap_size;
|
||||
|
||||
switch (font_options->antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
bitmap.num_grays = 1;
|
||||
stride = ((width + 31) & -32) >> 3;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_DEFAULT:
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bitmap.num_grays = 256;
|
||||
stride = (width + 3) & -4;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
switch (font_options->subpixel_order) {
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
default:
|
||||
matrix.xx *= 3;
|
||||
hmul = 3;
|
||||
subpixel = TRUE;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
matrix.yy *= 3;
|
||||
vmul = 3;
|
||||
subpixel = TRUE;
|
||||
break;
|
||||
switch (render_mode) {
|
||||
case FT_RENDER_MODE_LCD:
|
||||
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) {
|
||||
rgba = FC_RGBA_BGR;
|
||||
} else {
|
||||
rgba = FC_RGBA_RGB;
|
||||
}
|
||||
case FT_RENDER_MODE_LCD_V:
|
||||
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) {
|
||||
rgba = FC_RGBA_VBGR;
|
||||
} else {
|
||||
rgba = FC_RGBA_VRGB;
|
||||
}
|
||||
break;
|
||||
case FT_RENDER_MODE_MONO:
|
||||
case FT_RENDER_MODE_LIGHT:
|
||||
case FT_RENDER_MODE_NORMAL:
|
||||
case FT_RENDER_MODE_MAX:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
FT_Outline_Transform (outline, &matrix);
|
||||
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bitmap.num_grays = 256;
|
||||
stride = (width * hmul + 3) & -4;
|
||||
}
|
||||
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
||||
FT_Library_SetLcdFilter (library, lcd_filter);
|
||||
#endif
|
||||
|
||||
bitmap.pitch = stride;
|
||||
bitmap.width = width * hmul;
|
||||
bitmap.rows = height * vmul;
|
||||
bitmap.buffer = calloc (stride, bitmap.rows);
|
||||
if (unlikely (bitmap.buffer == NULL))
|
||||
fterror = FT_Render_Glyph (face->glyph, render_mode);
|
||||
|
||||
#if HAVE_FT_LIBRARY_SETLCDFILTER
|
||||
FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE);
|
||||
#endif
|
||||
|
||||
if (fterror != 0)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
bitmap_size = _compute_xrender_bitmap_size (&bitmap,
|
||||
face->glyph,
|
||||
render_mode);
|
||||
if (bitmap_size < 0)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
|
||||
bitmap.buffer = calloc (1, bitmap_size);
|
||||
if (bitmap.buffer == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
|
||||
free (bitmap.buffer);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
_fill_xrender_bitmap (&bitmap, face->glyph, render_mode,
|
||||
(rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR));
|
||||
|
||||
/* Note:
|
||||
* _get_bitmap_surface will free bitmap.buffer if there is an error
|
||||
*/
|
||||
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: the font's coordinate system is upside down from ours, so the
|
||||
* Y coordinate of the control box needs to be negated. Moreover, device
|
||||
* offsets are position of glyph origin relative to top left while xMin
|
||||
* and yMax are offsets of top left relative to origin. Another negation.
|
||||
*/
|
||||
cairo_surface_set_device_offset (&(*surface)->base,
|
||||
floor (-(double) cbox.xMin / 64.0),
|
||||
floor (+(double) cbox.yMax / 64.0));
|
||||
/* Note: the font's coordinate system is upside down from ours, so the
|
||||
* Y coordinate of the control box needs to be negated. Moreover, device
|
||||
* offsets are position of glyph origin relative to top left while xMin
|
||||
* and yMax are offsets of top left relative to origin. Another negation.
|
||||
*/
|
||||
cairo_surface_set_device_offset (&(*surface)->base,
|
||||
(double)-glyphslot->bitmap_left,
|
||||
(double)+glyphslot->bitmap_top);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1207,8 +1468,8 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
original_to_transformed = *shape;
|
||||
|
||||
cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
|
||||
orig_width = cairo_image_surface_get_width (&(*surface)->base);
|
||||
orig_height = cairo_image_surface_get_height (&(*surface)->base);
|
||||
orig_width = (*surface)->width;
|
||||
orig_height = (*surface)->height;
|
||||
|
||||
cairo_matrix_translate (&original_to_transformed,
|
||||
-origin_x, -origin_y);
|
||||
@ -1246,9 +1507,8 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
original_to_transformed.x0 -= x_min;
|
||||
original_to_transformed.y0 -= y_min;
|
||||
|
||||
/* Create the transformed bitmap
|
||||
*/
|
||||
width = x_max - x_min;
|
||||
/* Create the transformed bitmap */
|
||||
width = x_max - x_min;
|
||||
height = y_max - y_min;
|
||||
|
||||
transformed_to_original = original_to_transformed;
|
||||
@ -1256,30 +1516,19 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
/* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
|
||||
width = (width + 3) & ~3;
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
|
||||
if (unlikely (image->status))
|
||||
return image->status;
|
||||
|
||||
/* Initialize it to empty
|
||||
*/
|
||||
status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
0, 0,
|
||||
width, height);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Draw the original bitmap transformed into the new bitmap
|
||||
*/
|
||||
_cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
|
||||
cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
|
||||
|
||||
status = _cairo_surface_paint (image, CAIRO_OPERATOR_OVER,
|
||||
&pattern.base, NULL);
|
||||
status = _cairo_surface_paint (image,
|
||||
CAIRO_OPERATOR_SOURCE,
|
||||
&pattern.base,
|
||||
NULL);
|
||||
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
@ -1355,6 +1604,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
|
||||
|
||||
if (antialias) {
|
||||
cairo_subpixel_order_t subpixel_order;
|
||||
int lcd_filter;
|
||||
|
||||
/* disable hinting if requested */
|
||||
if (FcPatternGetBool (pattern,
|
||||
@ -1390,6 +1640,25 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
|
||||
ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||
}
|
||||
|
||||
if (FcPatternGetInteger (pattern,
|
||||
FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch)
|
||||
{
|
||||
switch (lcd_filter) {
|
||||
case FC_LCD_NONE:
|
||||
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_NONE;
|
||||
break;
|
||||
case FC_LCD_DEFAULT:
|
||||
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR5;
|
||||
break;
|
||||
case FC_LCD_LIGHT:
|
||||
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR3;
|
||||
break;
|
||||
case FC_LCD_LEGACY:
|
||||
ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
if (FcPatternGetInteger (pattern,
|
||||
FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
|
||||
@ -1491,6 +1760,12 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||
if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
|
||||
options->base.hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
|
||||
if (options->base.lcd_filter == CAIRO_LCD_FILTER_DEFAULT)
|
||||
options->base.lcd_filter = other->base.lcd_filter;
|
||||
|
||||
if (other->base.lcd_filter == CAIRO_LCD_FILTER_NONE)
|
||||
options->base.lcd_filter = CAIRO_LCD_FILTER_NONE;
|
||||
|
||||
if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
|
||||
if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
@ -1514,11 +1789,11 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
load_target |= FT_LOAD_TARGET_LCD;
|
||||
load_target = FT_LOAD_TARGET_LCD;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
load_target |= FT_LOAD_TARGET_LCD_V;
|
||||
load_target = FT_LOAD_TARGET_LCD_V;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2517,6 +2792,34 @@ _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
}
|
||||
}
|
||||
|
||||
if (options->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
int lcd_filter;
|
||||
|
||||
switch (options->lcd_filter) {
|
||||
case CAIRO_LCD_FILTER_NONE:
|
||||
lcd_filter = FT_LCD_FILTER_NONE;
|
||||
break;
|
||||
case CAIRO_LCD_FILTER_DEFAULT:
|
||||
case CAIRO_LCD_FILTER_INTRA_PIXEL:
|
||||
lcd_filter = FT_LCD_FILTER_LEGACY;
|
||||
break;
|
||||
case CAIRO_LCD_FILTER_FIR3:
|
||||
lcd_filter = FT_LCD_FILTER_LIGHT;
|
||||
break;
|
||||
default:
|
||||
case CAIRO_LCD_FILTER_FIR5:
|
||||
lcd_filter = FT_LCD_FILTER_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (! FcPatternAddInteger (pattern, FC_LCD_FILTER, lcd_filter))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
|
||||
@ -2638,13 +2941,11 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
}
|
||||
|
||||
status = _cairo_ft_unscaled_font_create_for_pattern (resolved, &unscaled);
|
||||
if (unlikely (status)) {
|
||||
if (unlikely (status || unscaled == NULL)) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
goto FREE_RESOLVED;
|
||||
}
|
||||
|
||||
assert (unscaled != NULL);
|
||||
|
||||
_get_pattern_ft_options (resolved, &ft_options);
|
||||
font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
|
@ -12,7 +12,7 @@
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user