1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_ServoBindings_h
8 #define mozilla_ServoBindings_h
9 
10 #include <stdint.h>
11 
12 #include "mozilla/ServoTypes.h"
13 #include "mozilla/ServoBindingTypes.h"
14 #include "mozilla/ServoElementSnapshot.h"
15 #include "mozilla/css/SheetParsingMode.h"
16 #include "nsChangeHint.h"
17 #include "nsStyleStruct.h"
18 
19 /*
20  * API for Servo to access Gecko data structures. This file must compile as valid
21  * C code in order for the binding generator to parse it.
22  *
23  * Functions beginning with Gecko_ are implemented in Gecko and invoked from Servo.
24  * Functions beginning with Servo_ are implemented in Servo and invoked from Gecko.
25  */
26 
27 class nsIAtom;
28 class nsIPrincipal;
29 class nsIURI;
30 struct nsFont;
31 namespace mozilla {
32   class FontFamilyList;
33   enum FontFamilyType : uint32_t;
34 }
35 using mozilla::FontFamilyList;
36 using mozilla::FontFamilyType;
37 using mozilla::ServoElementSnapshot;
38 struct nsStyleList;
39 struct nsStyleImage;
40 struct nsStyleGradientStop;
41 class nsStyleGradient;
42 class nsStyleCoord;
43 struct nsStyleDisplay;
44 
45 #define NS_DECL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
46   void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr);                    \
47   void Gecko_Release##name_##ArbitraryThread(class_* aPtr);
48 #define NS_IMPL_THREADSAFE_FFI_REFCOUNTING(class_, name_)                     \
49   static_assert(class_::HasThreadSafeRefCnt::value,                           \
50                 "NS_DECL_THREADSAFE_FFI_REFCOUNTING can only be used with "   \
51                 "classes that have thread-safe refcounting");                 \
52   void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr)                     \
53   { NS_ADDREF(aPtr); }                                                        \
54   void Gecko_Release##name_##ArbitraryThread(class_* aPtr)                    \
55   { NS_RELEASE(aPtr); }
56 
57 #define NS_DECL_HOLDER_FFI_REFCOUNTING(class_, name_)                         \
58   typedef nsMainThreadPtrHolder<class_> ThreadSafe##name_##Holder;            \
59   void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr); \
60   void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr);
61 #define NS_IMPL_HOLDER_FFI_REFCOUNTING(class_, name_)                         \
62   void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr)  \
63   { NS_ADDREF(aPtr); }                                                        \
64   void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \
65   { NS_RELEASE(aPtr); }                                                       \
66 
67 extern "C" {
68 
69 // Object refcounting.
70 NS_DECL_HOLDER_FFI_REFCOUNTING(nsIPrincipal, Principal)
71 NS_DECL_HOLDER_FFI_REFCOUNTING(nsIURI, URI)
72 
73 // DOM Traversal.
74 uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node);
75 bool Gecko_NodeIsElement(RawGeckoNodeBorrowed node);
76 RawGeckoNodeBorrowedOrNull Gecko_GetParentNode(RawGeckoNodeBorrowed node);
77 RawGeckoNodeBorrowedOrNull Gecko_GetFirstChild(RawGeckoNodeBorrowed node);
78 RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
79 RawGeckoNodeBorrowedOrNull Gecko_GetPrevSibling(RawGeckoNodeBorrowed node);
80 RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node);
81 RawGeckoElementBorrowedOrNull Gecko_GetParentElement(RawGeckoElementBorrowed element);
82 RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element);
83 RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element);
84 RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element);
85 RawGeckoElementBorrowedOrNull Gecko_GetNextSiblingElement(RawGeckoElementBorrowed element);
86 RawGeckoElementBorrowedOrNull Gecko_GetDocumentElement(RawGeckoDocumentBorrowed document);
87 
88 // By default, Servo walks the DOM by traversing the siblings of the DOM-view
89 // first child. This generally works, but misses anonymous children, which we
90 // want to traverse during styling. To support these cases, we create an
91 // optional heap-allocated iterator for nodes that need it. If the creation
92 // method returns null, Servo falls back to the aforementioned simpler (and
93 // faster) sibling traversal.
94 StyleChildrenIteratorOwnedOrNull Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed node);
95 void Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned it);
96 RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowedMut it);
97 
98 // Selector Matching.
99 uint8_t Gecko_ElementState(RawGeckoElementBorrowed element);
100 bool Gecko_IsHTMLElementInHTMLDocument(RawGeckoElementBorrowed element);
101 bool Gecko_IsLink(RawGeckoElementBorrowed element);
102 bool Gecko_IsTextNode(RawGeckoNodeBorrowed node);
103 bool Gecko_IsVisitedLink(RawGeckoElementBorrowed element);
104 bool Gecko_IsUnvisitedLink(RawGeckoElementBorrowed element);
105 bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
106 nsIAtom* Gecko_LocalName(RawGeckoElementBorrowed element);
107 nsIAtom* Gecko_Namespace(RawGeckoElementBorrowed element);
108 nsIAtom* Gecko_GetElementId(RawGeckoElementBorrowed element);
109 
110 // Attributes.
111 #define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_)  \
112   nsIAtom* prefix_##AtomAttrValue(implementor_ element, nsIAtom* attribute);  \
113   bool prefix_##HasAttr(implementor_ element, nsIAtom* ns, nsIAtom* name);    \
114   bool prefix_##AttrEquals(implementor_ element, nsIAtom* ns, nsIAtom* name,  \
115                            nsIAtom* str, bool ignoreCase);                    \
116   bool prefix_##AttrDashEquals(implementor_ element, nsIAtom* ns,             \
117                                nsIAtom* name, nsIAtom* str);                  \
118   bool prefix_##AttrIncludes(implementor_ element, nsIAtom* ns,               \
119                              nsIAtom* name, nsIAtom* str);                    \
120   bool prefix_##AttrHasSubstring(implementor_ element, nsIAtom* ns,           \
121                                  nsIAtom* name, nsIAtom* str);                \
122   bool prefix_##AttrHasPrefix(implementor_ element, nsIAtom* ns,              \
123                               nsIAtom* name, nsIAtom* str);                   \
124   bool prefix_##AttrHasSuffix(implementor_ element, nsIAtom* ns,              \
125                               nsIAtom* name, nsIAtom* str);                   \
126   uint32_t prefix_##ClassOrClassList(implementor_ element, nsIAtom** class_,  \
127                                      nsIAtom*** classList);
128 
129 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
130 SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot,
131                                               ServoElementSnapshot*)
132 
133 #undef SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS
134 
135 // Style attributes.
136 RawServoDeclarationBlockStrongBorrowedOrNull
137 Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed element);
138 
139 // Atoms.
140 nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength);
141 void Gecko_AddRefAtom(nsIAtom* aAtom);
142 void Gecko_ReleaseAtom(nsIAtom* aAtom);
143 const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength);
144 bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength);
145 bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength);
146 
147 // Strings (temporary until bug 1294742)
148 void Gecko_Utf8SliceToString(nsString* aString,
149                              const uint8_t* aBuffer,
150                              size_t aBufferLen);
151 
152 // Font style
153 void Gecko_FontFamilyList_Clear(FontFamilyList* aList);
154 void Gecko_FontFamilyList_AppendNamed(FontFamilyList* aList, nsIAtom* aName);
155 void Gecko_FontFamilyList_AppendGeneric(FontFamilyList* list, FontFamilyType familyType);
156 void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src);
157 
158 // Counter style.
159 void Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type);
160 void Gecko_CopyListStyleTypeFrom(nsStyleList* dst, const nsStyleList* src);
161 
162 // background-image style.
163 // TODO: support element() and -moz-image()
164 void Gecko_SetNullImageValue(nsStyleImage* image);
165 void Gecko_SetGradientImageValue(nsStyleImage* image, nsStyleGradient* gradient);
166 void Gecko_SetUrlImageValue(nsStyleImage* image,
167                             const uint8_t* url_bytes,
168                             uint32_t url_length,
169                             ThreadSafeURIHolder* base_uri,
170                             ThreadSafeURIHolder* referrer,
171                             ThreadSafePrincipalHolder* principal);
172 void Gecko_CopyImageValueFrom(nsStyleImage* image, const nsStyleImage* other);
173 
174 nsStyleGradient* Gecko_CreateGradient(uint8_t shape,
175                                       uint8_t size,
176                                       bool repeating,
177                                       bool legacy_syntax,
178                                       uint32_t stops);
179 
180 // list-style-image style.
181 void Gecko_SetListStyleImageNone(nsStyleList* style_struct);
182 void Gecko_SetListStyleImage(nsStyleList* style_struct,
183                              const uint8_t* string_bytes, uint32_t string_length,
184                              ThreadSafeURIHolder* base_uri,
185                              ThreadSafeURIHolder* referrer,
186                              ThreadSafePrincipalHolder* principal);
187 void Gecko_CopyListStyleImageFrom(nsStyleList* dest, const nsStyleList* src);
188 
189 // Display style.
190 void Gecko_SetMozBinding(nsStyleDisplay* style_struct,
191                          const uint8_t* string_bytes, uint32_t string_length,
192                          ThreadSafeURIHolder* base_uri,
193                          ThreadSafeURIHolder* referrer,
194                          ThreadSafePrincipalHolder* principal);
195 void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src);
196 
197 // Dirtiness tracking.
198 uint32_t Gecko_GetNodeFlags(RawGeckoNodeBorrowed node);
199 void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
200 void Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
201 
202 // Incremental restyle.
203 // TODO: We would avoid a few ffi calls if we decide to make an API like the
204 // former CalcAndStoreStyleDifference, but that would effectively mean breaking
205 // some safety guarantees in the servo side.
206 //
207 // Also, we might want a ComputedValues to ComputedValues API for animations?
208 // Not if we do them in Gecko...
209 nsStyleContext* Gecko_GetStyleContext(RawGeckoNodeBorrowed node,
210                                       nsIAtom* aPseudoTagOrNull);
211 nsChangeHint Gecko_CalcStyleDifference(nsStyleContext* oldstyle,
212                                        ServoComputedValuesBorrowed newstyle);
213 void Gecko_StoreStyleDifference(RawGeckoNodeBorrowed node, nsChangeHint change);
214 
215 // `array` must be an nsTArray
216 // If changing this signature, please update the
217 // friend function declaration in nsTArray.h
218 void Gecko_EnsureTArrayCapacity(void* array, size_t capacity, size_t elem_size);
219 
220 // Same here, `array` must be an nsTArray<T>, for some T.
221 //
222 // Important note: Only valid for POD types, since destructors won't be run
223 // otherwise. This is ensured with rust traits for the relevant structs.
224 void Gecko_ClearPODTArray(void* array, size_t elem_size, size_t elem_align);
225 
226 // Clear the mContents field in nsStyleContent. This is needed to run the
227 // destructors, otherwise we'd leak the images (though we still don't support
228 // those), strings, and whatnot.
229 void Gecko_ClearStyleContents(nsStyleContent* content);
230 void Gecko_CopyStyleContentsFrom(nsStyleContent* content, const nsStyleContent* other);
231 
232 void Gecko_EnsureImageLayersLength(nsStyleImageLayers* layers, size_t len,
233                                    nsStyleImageLayers::LayerType layer_type);
234 
235 // Clean up pointer-based coordinates
236 void Gecko_ResetStyleCoord(nsStyleUnit* unit, nsStyleUnion* value);
237 
238 // Set an nsStyleCoord to a computed `calc()` value
239 void Gecko_SetStyleCoordCalcValue(nsStyleUnit* unit, nsStyleUnion* value, nsStyleCoord::CalcValue calc);
240 
241 void Gecko_CopyClipPathValueFrom(mozilla::StyleClipPath* dst, const mozilla::StyleClipPath* src);
242 
243 void Gecko_DestroyClipPath(mozilla::StyleClipPath* clip);
244 mozilla::StyleBasicShape* Gecko_NewBasicShape(mozilla::StyleBasicShapeType type);
245 
246 void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
247 void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);
248 
249 void Gecko_FillAllBackgroundLists(nsStyleImageLayers* layers, uint32_t max_len);
250 void Gecko_FillAllMaskLists(nsStyleImageLayers* layers, uint32_t max_len);
251 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
252 
253 nsCSSShadowArray* Gecko_NewCSSShadowArray(uint32_t len);
254 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
255 
256 nsStyleQuoteValues* Gecko_NewStyleQuoteValues(uint32_t len);
257 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
258 
259 nsCSSValueSharedList* Gecko_NewCSSValueSharedList(uint32_t len);
260 void Gecko_CSSValue_SetAbsoluteLength(nsCSSValueBorrowedMut css_value, nscoord len);
261 void Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut css_value, float number);
262 void Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut css_value, nsCSSKeyword keyword);
263 void Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut css_value, float percent);
264 void Gecko_CSSValue_SetAngle(nsCSSValueBorrowedMut css_value, float radians);
265 void Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut css_value, nsStyleCoord::CalcValue calc);
266 void Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut css_value, int32_t len);
267 nsCSSValueBorrowedMut Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut css_value, int32_t index);
268 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
269 
270 // Style-struct management.
271 #define STYLE_STRUCT(name, checkdata_cb)                                       \
272   void Gecko_Construct_nsStyle##name(nsStyle##name* ptr);                      \
273   void Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr,                   \
274                                          const nsStyle##name* other);          \
275   void Gecko_Destroy_nsStyle##name(nsStyle##name* ptr);
276 #include "nsStyleStructList.h"
277 #undef STYLE_STRUCT
278 
279 #define SERVO_BINDING_FUNC(name_, return_, ...) return_ name_(__VA_ARGS__);
280 #include "mozilla/ServoBindingList.h"
281 #undef SERVO_BINDING_FUNC
282 
283 } // extern "C"
284 
285 #endif // mozilla_ServoBindings_h
286