Bug 458861. Validate TrueType headers before activating downloaded font. r=roc, sr...
[wine-gecko.git] / layout / style / nsCSSDataBlock.h
blob01ff8ab14b714c7e52ab9604d8dd887f93f3b43d
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is nsCSSDataBlock.h.
16 * The Initial Developer of the Original Code is L. David Baron.
17 * Portions created by the Initial Developer are Copyright (C) 2003
18 * the Initial Developer. All Rights Reserved.
20 * Contributor(s):
21 * L. David Baron <dbaron@dbaron.org> (original author)
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 * compact representation of the property-value pairs within a CSS
39 * declaration, and the code for expanding and compacting it
42 #ifndef nsCSSDataBlock_h__
43 #define nsCSSDataBlock_h__
45 #include "nsCSSStruct.h"
47 struct nsRuleData;
49 class nsCSSExpandedDataBlock;
51 /**
52 * An |nsCSSCompressedDataBlock| holds an immutable chunk of
53 * property-value data for a CSS declaration block (which we misname a
54 * |nsCSSDeclaration|). Mutation is accomplished through
55 * |nsCSSExpandedDataBlock|.
57 class nsCSSCompressedDataBlock {
58 public:
59 friend class nsCSSExpandedDataBlock;
61 /**
62 * Do what |nsIStyleRule::MapRuleInfoInto| needs to do for a style
63 * rule using this block for storage.
65 nsresult MapRuleInfoInto(nsRuleData *aRuleData) const;
67 /**
68 * Return the location at which the *value* for the property is
69 * stored, or null if the block does not contain a value for the
70 * property. This is either an |nsCSSValue*|, |nsCSSRect*|, or an
71 * |nsCSSValueList**|, etc.
73 * Inefficient (by design).
75 const void* StorageFor(nsCSSProperty aProperty) const;
77 /**
78 * Clone this block, or return null on out-of-memory.
80 nsCSSCompressedDataBlock* Clone() const;
82 /**
83 * Delete all the data stored in this block, and the block itself.
85 void Destroy();
87 /**
88 * Create a new nsCSSCompressedDataBlock holding no declarations.
90 static nsCSSCompressedDataBlock* CreateEmptyBlock();
92 private:
93 PRInt32 mStyleBits; // the structs for which we have data, according to
94 // |nsCachedStyleData::GetBitForSID|.
96 enum { block_chars = 4 }; // put 4 chars in the definition of the class
97 // to ensure size not inflated by alignment
99 void* operator new(size_t aBaseSize, size_t aDataSize) {
100 // subtract off the extra size to store |mBlock_|
101 return ::operator new(aBaseSize + aDataSize -
102 sizeof(char) * block_chars);
105 nsCSSCompressedDataBlock() : mStyleBits(0) {}
107 // Only this class (through |Destroy|) or nsCSSExpandedDataBlock (in
108 // |Expand|) can delete compressed data blocks.
109 ~nsCSSCompressedDataBlock() { }
111 char* mBlockEnd; // the byte after the last valid byte
112 char mBlock_[block_chars]; // must be the last member!
114 char* Block() { return mBlock_; }
115 char* BlockEnd() { return mBlockEnd; }
116 const char* Block() const { return mBlock_; }
117 const char* BlockEnd() const { return mBlockEnd; }
118 ptrdiff_t DataSize() const { return BlockEnd() - Block(); }
121 class nsCSSExpandedDataBlock {
122 public:
123 nsCSSExpandedDataBlock();
124 ~nsCSSExpandedDataBlock();
126 * When setting properties in an |nsCSSExpandedDataBlock|, callers
127 * must make the appropriate |AddPropertyBit| call.
130 nsCSSFont mFont;
131 nsCSSDisplay mDisplay;
132 nsCSSMargin mMargin;
133 nsCSSList mList;
134 nsCSSPosition mPosition;
135 nsCSSTable mTable;
136 nsCSSColor mColor;
137 nsCSSContent mContent;
138 nsCSSText mText;
139 nsCSSUserInterface mUserInterface;
140 nsCSSAural mAural;
141 nsCSSPage mPage;
142 nsCSSBreaks mBreaks;
143 nsCSSXUL mXUL;
144 #ifdef MOZ_SVG
145 nsCSSSVG mSVG;
146 #endif
147 nsCSSColumn mColumn;
150 * Transfer all of the state from the compressed block to this
151 * expanded block. The state of this expanded block must be clear
152 * beforehand.
154 * The compressed block passed in IS DESTROYED by this method and
155 * set to null, and thus cannot be used again. (This is necessary
156 * because ownership of sub-objects is transferred to the expanded
157 * block.)
159 void Expand(nsCSSCompressedDataBlock **aNormalBlock,
160 nsCSSCompressedDataBlock **aImportantBlock);
163 * Allocate a new compressed block and transfer all of the state
164 * from this expanded block to the new compressed block, clearing
165 * the state of this expanded block.
167 void Compress(nsCSSCompressedDataBlock **aNormalBlock,
168 nsCSSCompressedDataBlock **aImportantBlock);
171 * Clear (and thus destroy) the state of this expanded block.
173 void Clear();
176 * Clear the data for the given property (including the set and
177 * important bits).
179 void ClearProperty(nsCSSProperty aPropID);
181 void AssertInitialState() {
182 #ifdef DEBUG
183 DoAssertInitialState();
184 #endif
187 private:
189 * Compute the size that will be occupied by the result of
190 * |Compress|.
192 struct ComputeSizeResult {
193 PRUint32 normal, important;
195 ComputeSizeResult ComputeSize();
197 void DoExpand(nsCSSCompressedDataBlock *aBlock, PRBool aImportant);
199 #ifdef DEBUG
200 void DoAssertInitialState();
201 #endif
203 struct PropertyOffsetInfo {
204 // XXX These could probably be pointer-to-member, if the casting can
205 // be done correctly.
206 size_t block_offset; // offset of value in nsCSSExpandedDataBlock
207 size_t ruledata_struct_offset; // offset of nsRuleData* in nsRuleData
208 size_t ruledata_member_offset; // offset of value in nsRuleData*
211 static const PropertyOffsetInfo kOffsetTable[];
213 typedef PRUint8 property_set_type;
214 enum { kPropertiesSetChunkSize = 8 }; // number of bits in
215 // |property_set_type|.
216 // number of |property_set_type|s in the set
217 enum { kPropertiesSetChunkCount =
218 (eCSSProperty_COUNT_no_shorthands + (kPropertiesSetChunkSize-1)) /
219 kPropertiesSetChunkSize };
221 * mPropertiesSet stores a bit for every property that is present,
222 * to optimize compression of blocks with small numbers of
223 * properties (the norm) and to allow quickly checking whether a
224 * property is set in this block.
226 property_set_type mPropertiesSet[kPropertiesSetChunkCount];
228 * mPropertiesImportant indicates which properties are '!important'.
230 property_set_type mPropertiesImportant[kPropertiesSetChunkCount];
232 public:
234 * Return the storage location within |this| of the value of the
235 * property (i.e., either an |nsCSSValue*|, |nsCSSRect*|, or
236 * |nsCSSValueList**| (etc.).
238 void* PropertyAt(nsCSSProperty aProperty) {
239 const PropertyOffsetInfo& offsets =
240 nsCSSExpandedDataBlock::kOffsetTable[aProperty];
241 return reinterpret_cast<void*>(reinterpret_cast<char*>(this) +
242 offsets.block_offset);
246 * Return the storage location within |aRuleData| of the value of
247 * the property (i.e., either an |nsCSSValue*|, |nsCSSRect*|, or
248 * |nsCSSValueList**| (etc.).
250 static void* RuleDataPropertyAt(nsRuleData *aRuleData,
251 nsCSSProperty aProperty) {
252 const PropertyOffsetInfo& offsets =
253 nsCSSExpandedDataBlock::kOffsetTable[aProperty];
254 NS_ASSERTION(offsets.ruledata_struct_offset != size_t(-1),
255 "property should not use CSS_PROP_BACKENDONLY");
256 char* cssstruct = *reinterpret_cast<char**>
257 (reinterpret_cast<char*>(aRuleData) +
258 offsets.ruledata_struct_offset);
259 return reinterpret_cast<void*>
260 (cssstruct + offsets.ruledata_member_offset);
263 void AssertInSetRange(nsCSSProperty aProperty) {
264 NS_ASSERTION(0 <= aProperty &&
265 aProperty < eCSSProperty_COUNT_no_shorthands,
266 "out of bounds");
269 void SetPropertyBit(nsCSSProperty aProperty) {
270 AssertInSetRange(aProperty);
271 mPropertiesSet[aProperty / kPropertiesSetChunkSize] |=
272 property_set_type(1 << (aProperty % kPropertiesSetChunkSize));
275 void ClearPropertyBit(nsCSSProperty aProperty) {
276 AssertInSetRange(aProperty);
277 mPropertiesSet[aProperty / kPropertiesSetChunkSize] &=
278 ~property_set_type(1 << (aProperty % kPropertiesSetChunkSize));
281 PRBool HasPropertyBit(nsCSSProperty aProperty) {
282 AssertInSetRange(aProperty);
283 return (mPropertiesSet[aProperty / kPropertiesSetChunkSize] &
284 (1 << (aProperty % kPropertiesSetChunkSize))) != 0;
287 void SetImportantBit(nsCSSProperty aProperty) {
288 AssertInSetRange(aProperty);
289 mPropertiesImportant[aProperty / kPropertiesSetChunkSize] |=
290 property_set_type(1 << (aProperty % kPropertiesSetChunkSize));
293 void ClearImportantBit(nsCSSProperty aProperty) {
294 AssertInSetRange(aProperty);
295 mPropertiesImportant[aProperty / kPropertiesSetChunkSize] &=
296 ~property_set_type(1 << (aProperty % kPropertiesSetChunkSize));
299 PRBool HasImportantBit(nsCSSProperty aProperty) {
300 AssertInSetRange(aProperty);
301 return (mPropertiesImportant[aProperty / kPropertiesSetChunkSize] &
302 (1 << (aProperty % kPropertiesSetChunkSize))) != 0;
305 void ClearSets() {
306 memset(mPropertiesSet, 0, sizeof(mPropertiesSet));
307 memset(mPropertiesImportant, 0, sizeof(mPropertiesImportant));
311 #endif /* !defined(nsCSSDataBlock_h__) */