|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 #include "SkWidgetViews.h" |
|
9 #include "SkTextBox.h" |
|
10 |
|
11 #ifdef SK_DEBUG |
|
12 static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[]) |
|
13 { |
|
14 const char* value = dom.findAttr(node, attr); |
|
15 if (value) |
|
16 SkDebugf("unknown attribute %s=\"%s\"\n", attr, value); |
|
17 } |
|
18 #else |
|
19 #define assert_no_attr(dom, node, attr) |
|
20 #endif |
|
21 |
|
22 SkStaticTextView::SkStaticTextView() |
|
23 { |
|
24 fMargin.set(0, 0); |
|
25 fMode = kFixedSize_Mode; |
|
26 fSpacingAlign = SkTextBox::kStart_SpacingAlign; |
|
27 |
|
28 // init_skin_paint(kStaticText_SkinEnum, &fPaint); |
|
29 } |
|
30 |
|
31 SkStaticTextView::~SkStaticTextView() |
|
32 { |
|
33 } |
|
34 |
|
35 void SkStaticTextView::computeSize() |
|
36 { |
|
37 if (fMode == kAutoWidth_Mode) |
|
38 { |
|
39 SkScalar width = fPaint.measureText(fText.c_str(), fText.size()); |
|
40 this->setWidth(width + fMargin.fX * 2); |
|
41 } |
|
42 else if (fMode == kAutoHeight_Mode) |
|
43 { |
|
44 SkScalar width = this->width() - fMargin.fX * 2; |
|
45 int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0; |
|
46 |
|
47 this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2); |
|
48 } |
|
49 } |
|
50 |
|
51 void SkStaticTextView::setMode(Mode mode) |
|
52 { |
|
53 SkASSERT((unsigned)mode < kModeCount); |
|
54 |
|
55 if (fMode != mode) |
|
56 { |
|
57 fMode = SkToU8(mode); |
|
58 this->computeSize(); |
|
59 } |
|
60 } |
|
61 |
|
62 void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align) |
|
63 { |
|
64 fSpacingAlign = SkToU8(align); |
|
65 this->inval(NULL); |
|
66 } |
|
67 |
|
68 void SkStaticTextView::getMargin(SkPoint* margin) const |
|
69 { |
|
70 if (margin) |
|
71 *margin = fMargin; |
|
72 } |
|
73 |
|
74 void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy) |
|
75 { |
|
76 if (fMargin.fX != dx || fMargin.fY != dy) |
|
77 { |
|
78 fMargin.set(dx, dy); |
|
79 this->computeSize(); |
|
80 this->inval(NULL); |
|
81 } |
|
82 } |
|
83 |
|
84 size_t SkStaticTextView::getText(SkString* text) const |
|
85 { |
|
86 if (text) |
|
87 *text = fText; |
|
88 return fText.size(); |
|
89 } |
|
90 |
|
91 size_t SkStaticTextView::getText(char text[]) const |
|
92 { |
|
93 if (text) |
|
94 memcpy(text, fText.c_str(), fText.size()); |
|
95 return fText.size(); |
|
96 } |
|
97 |
|
98 void SkStaticTextView::setText(const SkString& text) |
|
99 { |
|
100 this->setText(text.c_str(), text.size()); |
|
101 } |
|
102 |
|
103 void SkStaticTextView::setText(const char text[]) |
|
104 { |
|
105 if (text == NULL) |
|
106 text = ""; |
|
107 this->setText(text, strlen(text)); |
|
108 } |
|
109 |
|
110 void SkStaticTextView::setText(const char text[], size_t len) |
|
111 { |
|
112 if (!fText.equals(text, len)) |
|
113 { |
|
114 fText.set(text, len); |
|
115 this->computeSize(); |
|
116 this->inval(NULL); |
|
117 } |
|
118 } |
|
119 |
|
120 void SkStaticTextView::getPaint(SkPaint* paint) const |
|
121 { |
|
122 if (paint) |
|
123 *paint = fPaint; |
|
124 } |
|
125 |
|
126 void SkStaticTextView::setPaint(const SkPaint& paint) |
|
127 { |
|
128 if (fPaint != paint) |
|
129 { |
|
130 fPaint = paint; |
|
131 this->computeSize(); |
|
132 this->inval(NULL); |
|
133 } |
|
134 } |
|
135 |
|
136 void SkStaticTextView::onDraw(SkCanvas* canvas) |
|
137 { |
|
138 this->INHERITED::onDraw(canvas); |
|
139 |
|
140 if (fText.isEmpty()) |
|
141 return; |
|
142 |
|
143 SkTextBox box; |
|
144 |
|
145 box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode); |
|
146 box.setSpacingAlign(this->getSpacingAlign()); |
|
147 box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY); |
|
148 box.draw(canvas, fText.c_str(), fText.size(), fPaint); |
|
149 } |
|
150 |
|
151 void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node) |
|
152 { |
|
153 if (false) { // avoid bit rot, suppress warning |
|
154 this->INHERITED::onInflate(dom, node); |
|
155 |
|
156 int index; |
|
157 if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0) { |
|
158 this->setMode((Mode)index); |
|
159 } else { |
|
160 assert_no_attr(dom, node, "mode"); |
|
161 } |
|
162 |
|
163 if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0) { |
|
164 this->setSpacingAlign((SkTextBox::SpacingAlign)index); |
|
165 } else { |
|
166 assert_no_attr(dom, node, "spacing-align"); |
|
167 } |
|
168 |
|
169 SkScalar s[2]; |
|
170 if (dom.findScalars(node, "margin", s, 2)) { |
|
171 this->setMargin(s[0], s[1]); |
|
172 } else { |
|
173 assert_no_attr(dom, node, "margin"); |
|
174 } |
|
175 |
|
176 const char* text = dom.findAttr(node, "text"); |
|
177 if (text) { |
|
178 this->setText(text); |
|
179 } |
|
180 |
|
181 if ((node = dom.getFirstChild(node, "paint")) != NULL && |
|
182 (node = dom.getFirstChild(node, "screenplay")) != NULL) |
|
183 { |
|
184 // FIXME: Including inflate_paint causes Windows build to fail -- it complains |
|
185 // that SKListView::SkListView is undefined. |
|
186 #if 0 |
|
187 inflate_paint(dom, node, &fPaint); |
|
188 #endif |
|
189 } |
|
190 } |
|
191 } |