Imported Upstream version 2.11.93
[platform/upstream/fontconfig.git] / src / fcrange.c
1 /*
2  * fontconfig/src/fcrange.c
3  *
4  * Copyright © 2002 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the author(s) not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  The authors make no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include "fcint.h"
26
27
28 FcRange *
29 FcRangeCreateDouble (double begin, double end)
30 {
31     FcRange *ret = malloc (sizeof (FcRange));
32
33     if (ret)
34     {
35         ret->is_double = FcTrue;
36         ret->is_inclusive = FcDoubleCmpEQ (begin, end);
37         ret->u.d.begin = begin;
38         ret->u.d.end = end;
39     }
40
41     return ret;
42 }
43
44 FcRange *
45 FcRangeCreateInteger (FcChar32 begin, FcChar32 end)
46 {
47     FcRange *ret = malloc (sizeof (FcRange));
48
49     if (ret)
50     {
51         ret->is_double = FcFalse;
52         ret->is_inclusive = (begin == end);
53         ret->u.i.begin = begin;
54         ret->u.i.end = end;
55     }
56
57     return ret;
58 }
59
60 void
61 FcRangeDestroy (FcRange *range)
62 {
63     free (range);
64 }
65
66 FcRange *
67 FcRangeCopy (const FcRange *range)
68 {
69     FcRange *ret;
70
71     if (range->is_double)
72         ret = FcRangeCreateDouble (range->u.d.begin, range->u.d.end);
73     else
74         ret = FcRangeCreateInteger (range->u.i.begin, range->u.i.end);
75
76     return ret;
77 }
78
79 FcBool
80 FcRangeGetDouble(const FcRange *range, double *begin, double *end)
81 {
82     if (!range)
83         return FcFalse;
84     if (range->is_double)
85     {
86         if (begin)
87             *begin = range->u.d.begin;
88         if (end)
89             *end = range->u.d.end;
90     }
91     else
92     {
93         if (begin)
94             *begin = (double)range->u.i.begin;
95         if (end)
96             *end = (double)range->u.i.end;
97     }
98
99     return FcTrue;
100 }
101
102 FcRange
103 FcRangeCanonicalize (const FcRange *range)
104 {
105     FcRange new;
106
107     if (range->is_double)
108         new = *range;
109     else
110     {
111         new.is_double = FcTrue;
112         new.is_inclusive = range->is_inclusive;
113         new.u.d.begin = (double)range->u.i.begin;
114         new.u.d.end = (double)range->u.i.end;
115     }
116     return new;
117 }
118
119 FcRange *
120 FcRangePromote (double v, FcValuePromotionBuffer *vbuf)
121 {
122     typedef struct {
123         FcRange r;
124     } FcRangePromotionBuffer;
125     FcRangePromotionBuffer *buf = (FcRangePromotionBuffer *) vbuf;
126
127     FC_ASSERT_STATIC (sizeof (FcRangePromotionBuffer) <= sizeof (FcValuePromotionBuffer));
128     buf->r.is_double = FcTrue;
129     buf->r.is_inclusive = FcTrue;
130     buf->r.u.d.begin = v;
131     buf->r.u.d.end = v;
132
133     return &buf->r;
134 }
135
136 FcBool
137 FcRangeIsZero (const FcRange *r)
138 {
139     FcRange c;
140
141     if (!r)
142         return FcFalse;
143     c = FcRangeCanonicalize (r);
144
145     return FcDoubleIsZero (c.u.d.begin) && FcDoubleIsZero (c.u.d.end);
146 }
147
148 FcBool
149 FcRangeIsInRange (const FcRange *a, const FcRange *b)
150 {
151     FcRange ca, cb;
152     FcBool f;
153
154     if (!a || !b)
155         return FcFalse;
156
157     ca = FcRangeCanonicalize (a);
158     cb = FcRangeCanonicalize (b);
159     if (ca.is_inclusive & cb.is_inclusive)
160         f = ca.u.d.end <= cb.u.d.end;
161     else
162         f = ca.u.d.end < cb.u.d.end;
163
164     return FcDoubleCmpGE (ca.u.d.begin, cb.u.d.begin) && f;
165 }
166
167 FcBool
168 FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b)
169 {
170     FcRange ca, cb;
171
172     switch ((int) op) {
173     case FcOpEqual:
174     case FcOpContains:
175     case FcOpListing:
176         return FcRangeIsInRange (a, b);
177     case FcOpNotEqual:
178     case FcOpNotContains:
179         return !FcRangeIsInRange (a, b);
180     case FcOpLess:
181         ca = FcRangeCanonicalize (a);
182         cb = FcRangeCanonicalize (b);
183         return ca.u.d.begin < cb.u.d.begin;
184     case FcOpLessEqual:
185         ca = FcRangeCanonicalize (a);
186         cb = FcRangeCanonicalize (b);
187         return FcDoubleCmpLE (ca.u.d.begin, cb.u.d.begin);
188     case FcOpMore:
189         ca = FcRangeCanonicalize (a);
190         cb = FcRangeCanonicalize (b);
191         return ca.u.d.end > cb.u.d.end;
192     case FcOpMoreEqual:
193         ca = FcRangeCanonicalize (a);
194         cb = FcRangeCanonicalize (b);
195         return FcDoubleCmpGE (ca.u.d.end, cb.u.d.end);
196     default:
197         break;
198     }
199     return FcFalse;
200 }
201
202 FcChar32
203 FcRangeHash (const FcRange *r)
204 {
205     FcRange c = FcRangeCanonicalize (r);
206     int b = (int) (c.u.d.begin * 100);
207     int e = (int) (c.u.d.end * 100);
208
209     return b ^ (b << 1) ^ (e << 9);
210 }
211
212 FcBool
213 FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r)
214 {
215     if (!FcSerializeAlloc (serialize, r, sizeof (FcRange)))
216         return FcFalse;
217     return FcTrue;
218 }
219
220 FcRange *
221 FcRangeSerialize (FcSerialize *serialize, const FcRange *r)
222 {
223     FcRange *r_serialize = FcSerializePtr (serialize, r);
224
225     if (!r_serialize)
226         return NULL;
227     memcpy (r_serialize, r, sizeof (FcRange));
228
229     return r_serialize;
230 }
231
232 #define __fcrange__
233 #include "fcaliastail.h"
234 #undef __fcrange__