1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStackViewLayout.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkStackViewLayout::SkStackViewLayout()
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
12d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fMargin.set(0, 0, 0, 0);
13d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fSpacer    = 0;
14d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fOrient    = kHorizontal_Orient;
15d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fPack    = kStart_Pack;
16d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fAlign    = kStart_Align;
17d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fRound    = false;
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setOrient(Orient ori)
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
22d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT((unsigned)ori < kOrientCount);
23d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fOrient = SkToU8(ori);
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::getMargin(SkRect* margin) const
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (margin)
29d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *margin = fMargin;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setMargin(const SkRect& margin)
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
34d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fMargin = margin;
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setSpacer(SkScalar spacer)
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
39d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fSpacer = spacer;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setPack(Pack pack)
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
44d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT((unsigned)pack < kPackCount);
45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fPack = SkToU8(pack);
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setAlign(Align align)
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
50d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT((unsigned)align < kAlignCount);
51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fAlign = SkToU8(align);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::setRound(bool r)
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fRound = SkToU8(r);
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef SkScalar (*AlignProc)(SkScalar childLimit, SkScalar parentLimit);
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef SkScalar (SkView::*GetSizeProc)() const;
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef void (SkView::*SetLocProc)(SkScalar coord);
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef void (SkView::*SetSizeProc)(SkScalar coord);
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar left_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar center_align_proc(SkScalar childLimit, SkScalar parentLimit) { return SkScalarHalf(parentLimit - childLimit); }
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar right_align_proc(SkScalar childLimit, SkScalar parentLimit) { return parentLimit - childLimit; }
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar fill_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
71d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com/*    Measure the main-dimension for all the children. If a child is marked flex in that direction
72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    ignore its current value but increment the counter for flexChildren
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar compute_children_limit(SkView* parent, GetSizeProc sizeProc, int* count,
75d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                                       uint32_t flexMask, int* flexCount)
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
77d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView::B2FIter    iter(parent);
78d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*            child;
79d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar        limit = 0;
80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    int                n = 0, flex = 0;
81d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    while ((child = iter.next()) != NULL)
83d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
84d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        n += 1;
85d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (child->getFlags() & flexMask)
86d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            flex += 1;
87d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        else
88d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            limit += (child->*sizeProc)();
89d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
90d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (count)
91d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *count = n;
92d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (flexCount)
93d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *flexCount = flex;
94d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return limit;
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::onLayoutChildren(SkView* parent)
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
99d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static AlignProc gAlignProcs[] = {
100d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        left_align_proc,
101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        center_align_proc,
102d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        right_align_proc,
103d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fill_align_proc
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    };
105d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
106d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar            startM, endM, crossStartM, crossLimit;
107d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GetSizeProc            mainGetSizeP, crossGetSizeP;
108d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SetLocProc            mainLocP, crossLocP;
109d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SetSizeProc            mainSetSizeP, crossSetSizeP;
110d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView::Flag_Mask    flexMask;
111d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
112d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fOrient == kHorizontal_Orient)
113d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
114d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        startM        = fMargin.fLeft;
115d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        endM        = fMargin.fRight;
116d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossStartM    = fMargin.fTop;
117d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossLimit    = -fMargin.fTop - fMargin.fBottom;
118d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
119d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainGetSizeP    = &SkView::width;
120d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossGetSizeP    = &SkView::height;
121d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainLocP    = &SkView::setLocX;
122d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossLocP    = &SkView::setLocY;
123d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
124d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainSetSizeP  = &SkView::setWidth;
125d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossSetSizeP = &SkView::setHeight;
126d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
127d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        flexMask    = SkView::kFlexH_Mask;
128d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
129d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else
130d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
131d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        startM        = fMargin.fTop;
132d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        endM        = fMargin.fBottom;
133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossStartM    = fMargin.fLeft;
134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossLimit    = -fMargin.fLeft - fMargin.fRight;
135d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainGetSizeP    = &SkView::height;
137d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossGetSizeP    = &SkView::width;
138d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainLocP    = &SkView::setLocY;
139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossLocP    = &SkView::setLocX;
140d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
141d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        mainSetSizeP  = &SkView::setHeight;
142d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossSetSizeP = &SkView::setWidth;
143d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
144d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        flexMask    = SkView::kFlexV_Mask;
145d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
146d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    crossLimit += (parent->*crossGetSizeP)();
147d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (fAlign != kStretch_Align)
148d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        crossSetSizeP = NULL;
149d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
150d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    int            childCount, flexCount;
151d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar    childLimit = compute_children_limit(parent, mainGetSizeP, &childCount, flexMask, &flexCount);
152d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (childCount == 0)
154d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return;
155d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
156d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    childLimit += (childCount - 1) * fSpacer;
157d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
158d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar        parentLimit = (parent->*mainGetSizeP)() - startM - endM;
159d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar        pos = startM + gAlignProcs[fPack](childLimit, parentLimit);
160d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar        flexAmount = 0;
161d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView::B2FIter    iter(parent);
162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*            child;
163d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
164d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (flexCount > 0 && parentLimit > childLimit)
165d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        flexAmount = (parentLimit - childLimit) / flexCount;
166d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
167d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    while ((child = iter.next()) != NULL)
168d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
169d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fRound)
170e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com            pos = SkScalarRoundToScalar(pos);
171d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        (child->*mainLocP)(pos);
172d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkScalar crossLoc = crossStartM + gAlignProcs[fAlign]((child->*crossGetSizeP)(), crossLimit);
173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (fRound)
174e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com            crossLoc = SkScalarRoundToScalar(crossLoc);
175d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        (child->*crossLocP)(crossLoc);
176d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
177d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (crossSetSizeP)
178d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            (child->*crossSetSizeP)(crossLimit);
179d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (child->getFlags() & flexMask)
180d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            (child->*mainSetSizeP)(flexAmount);
181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        pos += (child->*mainGetSizeP)() + fSpacer;
182d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
188d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
189d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
190d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        const char* value = dom.findAttr(node, attr);
191d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (value)
192d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
193d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
195d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    #define assert_no_attr(dom, node, attr)
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkStackViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
200d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    int            index;
201d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkScalar    value[4];
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
203d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((index = dom.findList(node, "orient", "horizontal,vertical")) >= 0)
204d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setOrient((Orient)index);
205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else {
206d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        assert_no_attr(dom, node, "orient");
2072c2508d2ede7e6a8eb43dba0ef2419905ccbb3d8tomhudson@google.com        }
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
209d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (dom.findScalars(node, "margin", value, 4))
210d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
211d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkRect    margin;
212d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        margin.set(value[0], value[1], value[2], value[3]);
213d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setMargin(margin);
214d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
215d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else {
216d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        assert_no_attr(dom, node, "margin");
2172c2508d2ede7e6a8eb43dba0ef2419905ccbb3d8tomhudson@google.com        }
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
219d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (dom.findScalar(node, "spacer", value))
220d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setSpacer(value[0]);
221d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else {
222d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        assert_no_attr(dom, node, "spacer");
2232c2508d2ede7e6a8eb43dba0ef2419905ccbb3d8tomhudson@google.com        }
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
225d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((index = dom.findList(node, "pack", "start,center,end")) >= 0)
226d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setPack((Pack)index);
227d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else {
228d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        assert_no_attr(dom, node, "pack");
2292c2508d2ede7e6a8eb43dba0ef2419905ccbb3d8tomhudson@google.com        }
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if ((index = dom.findList(node, "align", "start,center,end,stretch")) >= 0)
232d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        this->setAlign((Align)index);
233d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    else {
234d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        assert_no_attr(dom, node, "align");
2352c2508d2ede7e6a8eb43dba0ef2419905ccbb3d8tomhudson@google.com        }
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////////////
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFillViewLayout::SkFillViewLayout()
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
242d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fMargin.setEmpty();
2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFillViewLayout::getMargin(SkRect* r) const
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
247d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (r)
248d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        *r = fMargin;
2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFillViewLayout::setMargin(const SkRect& margin)
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
253d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    fMargin = margin;
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFillViewLayout::onLayoutChildren(SkView* parent)
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
258d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView::B2FIter    iter(parent);
259d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkView*            child;
260d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
261d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    while ((child = iter.next()) != NULL)
262d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
263d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        child->setLoc(fMargin.fLeft, fMargin.fTop);
264d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        child->setSize(    parent->width() - fMargin.fRight - fMargin.fLeft,
265d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                        parent->height() - fMargin.fBottom - fMargin.fTop);
266d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFillViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
271d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->INHERITED::onInflate(dom, node);
272d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    (void)dom.findScalars(node, "margin", (SkScalar*)&fMargin, 4);
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
274