+/* Encode offset in a pointer of type t */
+#define FcOffsetEncode(o,t) ((t *) ((o) | 1))
+
+/* Decode a pointer into an offset */
+#define FcOffsetDecode(p) (((intptr_t) (p)) & ~1)
+
+/* Compute pointer offset */
+#define FcPtrToOffset(b,p) ((intptr_t) (p) - (intptr_t) (b))
+
+/* Given base address, offset and type, return a pointer */
+#define FcOffsetToPtr(b,o,t) ((t *) ((intptr_t) (b) + (o)))
+
+/* Given base address, encoded offset and type, return a pointer */
+#define FcEncodedOffsetToPtr(b,p,t) FcOffsetToPtr(b,FcOffsetDecode(p),t)
+
+/* Given base address, pointer and type, return an encoded offset */
+#define FcPtrToEncodedOffset(b,p,t) FcOffsetEncode(FcPtrToOffset(b,p),t)
+
+/* Given a structure, offset member and type, return pointer */
+#define FcOffsetMember(s,m,t) FcOffsetToPtr(s,(s)->m,t)
+
+/* Given a structure, encoded offset member and type, return pointer to member */
+#define FcEncodedOffsetMember(s,m,t) FcOffsetToPtr(s,FcOffsetDecode((s)->m), t)
+
+/* Given a structure, member and type, convert the member to a pointer */
+#define FcPointerMember(s,m,t) (FcIsEncodedOffset((s)->m) ? \
+ FcEncodedOffsetMember (s,m,t) : \
+ (s)->m)
+
+/*
+ * Serialized values may hold strings, charsets and langsets as pointers,
+ * unfortunately FcValue is an exposed type so we can't just always use
+ * offsets
+ */
+#define FcValueString(v) FcPointerMember(v,u.s,FcChar8)
+#define FcValueCharSet(v) FcPointerMember(v,u.c,const FcCharSet)
+#define FcValueLangSet(v) FcPointerMember(v,u.l,const FcLangSet)
+
+typedef struct _FcValueList *FcValueListPtr;