180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkWidgetViews.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTextBox.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[]) 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* value = dom.findAttr(node, attr); 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("unknown attribute %s=\"%s\"\n", attr, value); 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define assert_no_attr(dom, node, attr) 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkStaticTextView::SkStaticTextView() 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMargin.set(0, 0); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMode = kFixedSize_Mode; 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSpacingAlign = SkTextBox::kStart_SpacingAlign; 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// init_skin_paint(kStaticText_SkinEnum, &fPaint); 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkStaticTextView::~SkStaticTextView() 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::computeSize() 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMode == kAutoWidth_Mode) 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar width = fPaint.measureText(fText.c_str(), fText.size()); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setWidth(width + fMargin.fX * 2); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else if (fMode == kAutoHeight_Mode) 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar width = this->width() - fMargin.fX * 2; 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0; 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2); 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setMode(Mode mode) 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)mode < kModeCount); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMode != mode) 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMode = SkToU8(mode); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->computeSize(); 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align) 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSpacingAlign = SkToU8(align); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval(NULL); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::getMargin(SkPoint* margin) const 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (margin) 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *margin = fMargin; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setMargin(SkScalar dx, SkScalar dy) 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMargin.fX != dx || fMargin.fY != dy) 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMargin.set(dx, dy); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->computeSize(); 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval(NULL); 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkStaticTextView::getText(SkString* text) const 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (text) 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *text = fText; 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fText.size(); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkStaticTextView::getText(char text[]) const 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (text) 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(text, fText.c_str(), fText.size()); 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fText.size(); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setText(const SkString& text) 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setText(text.c_str(), text.size()); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setText(const char text[]) 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (text == NULL) 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru text = ""; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setText(text, strlen(text)); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setText(const char text[], size_t len) 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fText.equals(text, len)) 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fText.set(text, len); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->computeSize(); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval(NULL); 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::getPaint(SkPaint* paint) const 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint) 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *paint = fPaint; 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::setPaint(const SkPaint& paint) 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fPaint != paint) 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fPaint = paint; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->computeSize(); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->inval(NULL); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::onDraw(SkCanvas* canvas) 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::onDraw(canvas); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fText.isEmpty()) 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTextBox box; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode); 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru box.setSpacingAlign(this->getSpacingAlign()); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY); 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru box.draw(canvas, fText.c_str(), fText.size(), fPaint); 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node) 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruif (false) { // avoid bit rot, suppress warning 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::onInflate(dom, node); 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int index; 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0) { 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setMode((Mode)index); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru assert_no_attr(dom, node, "mode"); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0) { 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setSpacingAlign((SkTextBox::SpacingAlign)index); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru assert_no_attr(dom, node, "spacing-align"); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar s[2]; 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dom.findScalars(node, "margin", s, 2)) { 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setMargin(s[0], s[1]); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru assert_no_attr(dom, node, "margin"); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* text = dom.findAttr(node, "text"); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (text) { 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setText(text); 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((node = dom.getFirstChild(node, "paint")) != NULL && 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (node = dom.getFirstChild(node, "screenplay")) != NULL) 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// FIXME: Including inflate_paint causes Windows build to fail -- it complains 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// that SKListView::SkListView is undefined. 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inflate_paint(dom, node, &fPaint); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 192