And finished implementing attrlistInsertAt(). Woo!
This commit is contained in:
parent
75525196b1
commit
5c96266c7c
|
@ -15,7 +15,7 @@ struct attrlist {
|
||||||
};
|
};
|
||||||
|
|
||||||
// if before is NULL, add to the end of the list
|
// if before is NULL, add to the end of the list
|
||||||
static void linkInsertBefore(struct attrlist *alist, struct attr *a, struct attr *before)
|
static void attrInsertBefore(struct attrlist *alist, struct attr *a, struct attr *before)
|
||||||
{
|
{
|
||||||
// if the list is empty, this is the first item
|
// if the list is empty, this is the first item
|
||||||
if (alist->first == NULL) {
|
if (alist->first == NULL) {
|
||||||
|
@ -180,6 +180,29 @@ static int attrDropRange(struct attrlist *alist, struct attr *a, size_t start, s
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void attrGrow(struct attrlist *alist, struct attr *a, size_t start, size_t end)
|
||||||
|
{
|
||||||
|
struct attr *before;
|
||||||
|
struct attr *unused;
|
||||||
|
|
||||||
|
// adjusting the end is simple: if it ends before our new end, just set the new end
|
||||||
|
if (a->end < end)
|
||||||
|
a->end = end;
|
||||||
|
|
||||||
|
// adjusting the start is harder
|
||||||
|
// if the start is before our new start, we are done
|
||||||
|
// otherwise, we have to move the start back AND reposition the attribute to keep the sorted order
|
||||||
|
if (a->start <= start)
|
||||||
|
return;
|
||||||
|
a->start = start;
|
||||||
|
// TODO could we just return next?
|
||||||
|
attrUnlink(alist, a, &unused);
|
||||||
|
for (before = alist->first; before != NULL; before = before->next)
|
||||||
|
if (before->start > a->start)
|
||||||
|
break;
|
||||||
|
attrInsertBefore(alist, a, before);
|
||||||
|
}
|
||||||
|
|
||||||
void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, size_t start, size_t end)
|
void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, size_t start, size_t end)
|
||||||
{
|
{
|
||||||
struct attr *a;
|
struct attr *a;
|
||||||
|
@ -211,8 +234,9 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
|
||||||
|
|
||||||
// okay so this might conflict; if the val is the same as the one we want, we need to expand the existing attribute, not fragment anything
|
// okay so this might conflict; if the val is the same as the one we want, we need to expand the existing attribute, not fragment anything
|
||||||
// TODO this might cause problems with system specific attributes, if we support those; maybe also user-specific?
|
// TODO this might cause problems with system specific attributes, if we support those; maybe also user-specific?
|
||||||
|
// TODO will this cause problems with fonts?
|
||||||
if (before->val == val) {
|
if (before->val == val) {
|
||||||
// TODO
|
attrGrow(alist, a, start, end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// okay the values are different; we need to split apart
|
// okay the values are different; we need to split apart
|
||||||
|
@ -230,7 +254,7 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
|
||||||
a->val = val;
|
a->val = val;
|
||||||
a->start = start;
|
a->start = start;
|
||||||
a->end = end;
|
a->end = end;
|
||||||
linkInsertBefore(alist, a, before);
|
attrInsertBefore(alist, a, before);
|
||||||
|
|
||||||
// and finally, if we split, insert the remainder
|
// and finally, if we split, insert the remainder
|
||||||
if (tail == NULL)
|
if (tail == NULL)
|
||||||
|
@ -239,5 +263,5 @@ void attrlistInsertAt(struct attrlist *alist, uiAttribute type, uintptr_t val, s
|
||||||
for (; before != NULL; before = before->next)
|
for (; before != NULL; before = before->next)
|
||||||
if (before->start > tail->start)
|
if (before->start > tail->start)
|
||||||
break;
|
break;
|
||||||
linkInsertBefore(alist, tail, before);
|
attrInsertBefore(alist, tail, before);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue