layout/base/nsStyleChangeList.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:5c7d2cdf597d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * a list of the recomputation that needs to be done in response to a
8 * style change
9 */
10
11 #include "nsStyleChangeList.h"
12 #include "nsIContent.h"
13
14 static const uint32_t kGrowArrayBy = 10;
15
16 nsStyleChangeList::nsStyleChangeList()
17 : mArray(mBuffer),
18 mArraySize(kStyleChangeBufferSize),
19 mCount(0)
20 {
21 MOZ_COUNT_CTOR(nsStyleChangeList);
22 }
23
24 nsStyleChangeList::~nsStyleChangeList()
25 {
26 MOZ_COUNT_DTOR(nsStyleChangeList);
27 Clear();
28 }
29
30 nsresult
31 nsStyleChangeList::ChangeAt(int32_t aIndex, nsIFrame*& aFrame, nsIContent*& aContent,
32 nsChangeHint& aHint) const
33 {
34 if ((0 <= aIndex) && (aIndex < mCount)) {
35 aFrame = mArray[aIndex].mFrame;
36 aContent = mArray[aIndex].mContent;
37 aHint = mArray[aIndex].mHint;
38 return NS_OK;
39 }
40 return NS_ERROR_ILLEGAL_VALUE;
41 }
42
43 nsresult
44 nsStyleChangeList::ChangeAt(int32_t aIndex, const nsStyleChangeData** aChangeData) const
45 {
46 if ((0 <= aIndex) && (aIndex < mCount)) {
47 *aChangeData = &mArray[aIndex];
48 return NS_OK;
49 }
50 return NS_ERROR_ILLEGAL_VALUE;
51 }
52
53 nsresult
54 nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint)
55 {
56 NS_ASSERTION(aFrame || (aHint & nsChangeHint_ReconstructFrame),
57 "must have frame");
58 NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame),
59 "must have content");
60 // XXXbz we should make this take Element instead of nsIContent
61 NS_ASSERTION(!aContent || aContent->IsElement(),
62 "Shouldn't be trying to restyle non-elements directly");
63 NS_ASSERTION(!(aHint & nsChangeHint_AllReflowHints) ||
64 (aHint & nsChangeHint_NeedReflow),
65 "Reflow hint bits set without actually asking for a reflow");
66
67 if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content
68 if (aContent) {
69 for (int32_t index = mCount - 1; index >= 0; --index) {
70 if (aContent == mArray[index].mContent) { // remove this change
71 aContent->Release();
72 mCount--;
73 if (index < mCount) { // move later changes down
74 ::memmove(&mArray[index], &mArray[index + 1],
75 (mCount - index) * sizeof(nsStyleChangeData));
76 }
77 }
78 }
79 }
80 }
81
82 int32_t last = mCount - 1;
83 if ((0 < mCount) && aFrame && (aFrame == mArray[last].mFrame)) { // same as last frame
84 NS_UpdateHint(mArray[last].mHint, aHint);
85 }
86 else {
87 if (mCount == mArraySize) {
88 int32_t newSize = mArraySize + kGrowArrayBy;
89 nsStyleChangeData* newArray = new nsStyleChangeData[newSize];
90 if (newArray) {
91 memcpy(newArray, mArray, mCount * sizeof(nsStyleChangeData));
92 if (mArray != mBuffer) {
93 delete [] mArray;
94 }
95 mArray = newArray;
96 mArraySize = newSize;
97 }
98 else {
99 return NS_ERROR_OUT_OF_MEMORY;
100 }
101 }
102 mArray[mCount].mFrame = aFrame;
103 mArray[mCount].mContent = aContent;
104 if (aContent) {
105 aContent->AddRef();
106 }
107 mArray[mCount].mHint = aHint;
108 mCount++;
109 }
110 return NS_OK;
111 }
112
113 void
114 nsStyleChangeList::Clear()
115 {
116 for (int32_t index = mCount - 1; index >= 0; --index) {
117 nsIContent* content = mArray[index].mContent;
118 if (content) {
119 content->Release();
120 }
121 }
122 if (mArray != mBuffer) {
123 delete [] mArray;
124 mArray = mBuffer;
125 mArraySize = kStyleChangeBufferSize;
126 }
127 mCount = 0;
128 }
129

mercurial