| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "ppapi/c/dev/ppb_cursor_control_dev.h" | 10 #include "ppapi/c/dev/ppb_cursor_control_dev.h" |
| 11 #include "ppapi/c/ppb_console.h" | 11 #include "ppapi/c/ppb_console.h" |
| 12 #include "ppapi/cpp/completion_callback.h" | 12 #include "ppapi/cpp/completion_callback.h" |
| 13 #include "ppapi/cpp/dev/font_dev.h" | |
| 14 #include "ppapi/cpp/graphics_2d.h" | 13 #include "ppapi/cpp/graphics_2d.h" |
| 15 #include "ppapi/cpp/image_data.h" | 14 #include "ppapi/cpp/image_data.h" |
| 16 #include "ppapi/cpp/input_event.h" | 15 #include "ppapi/cpp/input_event.h" |
| 17 #include "ppapi/cpp/instance.h" | 16 #include "ppapi/cpp/instance.h" |
| 18 #include "ppapi/cpp/module.h" | 17 #include "ppapi/cpp/module.h" |
| 19 #include "ppapi/cpp/rect.h" | 18 #include "ppapi/cpp/rect.h" |
| 20 #include "ppapi/cpp/size.h" | 19 #include "ppapi/cpp/size.h" |
| 21 #include "ppapi/cpp/text_input_controller.h" | 20 #include "ppapi/cpp/text_input_controller.h" |
| 21 #include "ppapi/cpp/trusted/browser_font_trusted.h" |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // Extracted from: ui/events/keycodes/keyboard_codes.h | 25 // Extracted from: ui/events/keycodes/keyboard_codes.h |
| 26 enum { | 26 enum { |
| 27 VKEY_BACK = 0x08, | 27 VKEY_BACK = 0x08, |
| 28 VKEY_SHIFT = 0x10, | 28 VKEY_SHIFT = 0x10, |
| 29 VKEY_DELETE = 0x2E, | 29 VKEY_DELETE = 0x2E, |
| 30 VKEY_LEFT = 0x25, | 30 VKEY_LEFT = 0x25, |
| 31 VKEY_UP = 0x26, | 31 VKEY_UP = 0x26, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 void FillRect(pp::ImageData* image, const pp::Rect& rect, uint32_t color) { | 57 void FillRect(pp::ImageData* image, const pp::Rect& rect, uint32_t color) { |
| 58 FillRect(image, rect.x(), rect.y(), rect.width(), rect.height(), color); | 58 FillRect(image, rect.x(), rect.y(), rect.width(), rect.height(), color); |
| 59 } | 59 } |
| 60 | 60 |
| 61 size_t GetPrevCharOffsetUtf8(const std::string& str, size_t current_pos) { | 61 size_t GetPrevCharOffsetUtf8(const std::string& str, size_t current_pos) { |
| 62 size_t i = current_pos; | 62 size_t i = current_pos; |
| 63 if (i > 0) { | 63 if (i > 0) { |
| 64 do | 64 do { |
| 65 --i; | 65 --i; |
| 66 while (i > 0 && (str[i] & 0xc0) == 0x80); | 66 } while (i > 0 && (str[i] & 0xc0) == 0x80); |
| 67 } | 67 } |
| 68 return i; | 68 return i; |
| 69 } | 69 } |
| 70 | 70 |
| 71 size_t GetNextCharOffsetUtf8(const std::string& str, size_t current_pos) { | 71 size_t GetNextCharOffsetUtf8(const std::string& str, size_t current_pos) { |
| 72 size_t i = current_pos; | 72 size_t i = current_pos; |
| 73 if (i < str.size()) { | 73 if (i < str.size()) { |
| 74 do | 74 do { |
| 75 ++i; | 75 ++i; |
| 76 while (i < str.size() && (str[i] & 0xc0) == 0x80); | 76 } while (i < str.size() && (str[i] & 0xc0) == 0x80); |
| 77 } | 77 } |
| 78 return i; | 78 return i; |
| 79 } | 79 } |
| 80 | 80 |
| 81 size_t GetNthCharOffsetUtf8(const std::string& str, size_t n) { | 81 size_t GetNthCharOffsetUtf8(const std::string& str, size_t n) { |
| 82 size_t i = 0; | 82 size_t i = 0; |
| 83 for (size_t step = 0; step < n; ++step) | 83 for (size_t step = 0; step < n; ++step) |
| 84 i = GetNextCharOffsetUtf8(str, i); | 84 i = GetNextCharOffsetUtf8(str, i); |
| 85 return i; | 85 return i; |
| 86 } | 86 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 public: | 125 public: |
| 126 MyTextField(pp::Instance* instance, TextFieldStatusHandler* handler, | 126 MyTextField(pp::Instance* instance, TextFieldStatusHandler* handler, |
| 127 int x, int y, int width, int height) | 127 int x, int y, int width, int height) |
| 128 : instance_(instance), | 128 : instance_(instance), |
| 129 status_handler_(handler), | 129 status_handler_(handler), |
| 130 area_(x, y, width, height), | 130 area_(x, y, width, height), |
| 131 font_size_(height - 2), | 131 font_size_(height - 2), |
| 132 caret_pos_(std::string::npos), | 132 caret_pos_(std::string::npos), |
| 133 anchor_pos_(std::string::npos), | 133 anchor_pos_(std::string::npos), |
| 134 target_segment_(0) { | 134 target_segment_(0) { |
| 135 pp::FontDescription_Dev desc; | 135 pp::BrowserFontDescription desc; |
| 136 desc.set_family(PP_FONTFAMILY_SANSSERIF); | 136 desc.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF); |
| 137 desc.set_size(font_size_); | 137 desc.set_size(font_size_); |
| 138 font_ = pp::Font_Dev(instance_, desc); | 138 font_ = pp::BrowserFont_Trusted(instance_, desc); |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Paint on the specified ImageData. | 141 // Paint on the specified ImageData. |
| 142 void PaintOn(pp::ImageData* image, pp::Rect clip) { | 142 void PaintOn(pp::ImageData* image, pp::Rect clip) { |
| 143 clip = clip.Intersect(area_); | 143 clip = clip.Intersect(area_); |
| 144 FillRect(image, clip, kTextfieldBgColor); | 144 FillRect(image, clip, kTextfieldBgColor); |
| 145 | 145 |
| 146 if (caret_pos_ != std::string::npos) { | 146 if (caret_pos_ != std::string::npos) { |
| 147 int offset = area_.x(); | 147 int offset = area_.x(); |
| 148 // selection (for the case without composition text) | 148 // selection (for the case without composition text) |
| 149 if (composition_.empty() && HasSelection()) { | 149 if (composition_.empty() && HasSelection()) { |
| 150 int left_x = font_.MeasureSimpleText( | 150 int left_x = font_.MeasureSimpleText( |
| 151 utf8_text_.substr(0, SelectionLeft())); | 151 utf8_text_.substr(0, SelectionLeft())); |
| 152 int right_x = font_.MeasureSimpleText( | 152 int right_x = font_.MeasureSimpleText( |
| 153 utf8_text_.substr(0, SelectionRight())); | 153 utf8_text_.substr(0, SelectionRight())); |
| 154 FillRect(image, offset + left_x, area_.y(), right_x - left_x, | 154 FillRect(image, offset + left_x, area_.y(), right_x - left_x, |
| 155 area_.height(), kTextfieldSelectionBackgroundColor); | 155 area_.height(), kTextfieldSelectionBackgroundColor); |
| 156 } | 156 } |
| 157 // before caret | 157 // before caret |
| 158 { | 158 { |
| 159 std::string str = utf8_text_.substr(0, caret_pos_); | 159 std::string str = utf8_text_.substr(0, caret_pos_); |
| 160 font_.DrawTextAt( | 160 font_.DrawTextAt( |
| 161 image, | 161 image, |
| 162 pp::TextRun_Dev(str.c_str(), false, false), | 162 pp::BrowserFontTextRun(str.c_str(), false, false), |
| 163 pp::Point(offset, area_.y() + font_size_), | 163 pp::Point(offset, area_.y() + font_size_), |
| 164 kTextfieldTextColor, | 164 kTextfieldTextColor, |
| 165 clip, | 165 clip, |
| 166 false); | 166 false); |
| 167 offset += font_.MeasureSimpleText(str); | 167 offset += font_.MeasureSimpleText(str); |
| 168 } | 168 } |
| 169 // composition | 169 // composition |
| 170 { | 170 { |
| 171 const std::string& str = composition_; | 171 const std::string& str = composition_; |
| 172 // selection | 172 // selection |
| 173 if (composition_selection_.first != composition_selection_.second) { | 173 if (composition_selection_.first != composition_selection_.second) { |
| 174 int left_x = font_.MeasureSimpleText( | 174 int left_x = font_.MeasureSimpleText( |
| 175 str.substr(0, composition_selection_.first)); | 175 str.substr(0, composition_selection_.first)); |
| 176 int right_x = font_.MeasureSimpleText( | 176 int right_x = font_.MeasureSimpleText( |
| 177 str.substr(0, composition_selection_.second)); | 177 str.substr(0, composition_selection_.second)); |
| 178 FillRect(image, offset + left_x, area_.y(), right_x - left_x, | 178 FillRect(image, offset + left_x, area_.y(), right_x - left_x, |
| 179 area_.height(), kTextfieldSelectionBackgroundColor); | 179 area_.height(), kTextfieldSelectionBackgroundColor); |
| 180 } | 180 } |
| 181 // composition text | 181 // composition text |
| 182 font_.DrawTextAt( | 182 font_.DrawTextAt( |
| 183 image, | 183 image, |
| 184 pp::TextRun_Dev(str.c_str(), false, false), | 184 pp::BrowserFontTextRun(str.c_str(), false, false), |
| 185 pp::Point(offset, area_.y() + font_size_), | 185 pp::Point(offset, area_.y() + font_size_), |
| 186 kTextfieldPreeditTextColor, | 186 kTextfieldPreeditTextColor, |
| 187 clip, | 187 clip, |
| 188 false); | 188 false); |
| 189 for (size_t i = 0; i < segments_.size(); ++i) { | 189 for (size_t i = 0; i < segments_.size(); ++i) { |
| 190 size_t l = segments_[i].first; | 190 size_t l = segments_[i].first; |
| 191 size_t r = segments_[i].second; | 191 size_t r = segments_[i].second; |
| 192 if (l != r) { | 192 if (l != r) { |
| 193 int lx = font_.MeasureSimpleText(str.substr(0, l)); | 193 int lx = font_.MeasureSimpleText(str.substr(0, l)); |
| 194 int rx = font_.MeasureSimpleText(str.substr(0, r)); | 194 int rx = font_.MeasureSimpleText(str.substr(0, r)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 206 FillRect(image, | 206 FillRect(image, |
| 207 pp::Rect(offset + caretx, area_.y(), 2, area_.height()), | 207 pp::Rect(offset + caretx, area_.y(), 2, area_.height()), |
| 208 kTextfieldCaretColor); | 208 kTextfieldCaretColor); |
| 209 offset += font_.MeasureSimpleText(str); | 209 offset += font_.MeasureSimpleText(str); |
| 210 } | 210 } |
| 211 // after caret | 211 // after caret |
| 212 { | 212 { |
| 213 std::string str = utf8_text_.substr(caret_pos_); | 213 std::string str = utf8_text_.substr(caret_pos_); |
| 214 font_.DrawTextAt( | 214 font_.DrawTextAt( |
| 215 image, | 215 image, |
| 216 pp::TextRun_Dev(str.c_str(), false, false), | 216 pp::BrowserFontTextRun(str.c_str(), false, false), |
| 217 pp::Point(offset, area_.y() + font_size_), | 217 pp::Point(offset, area_.y() + font_size_), |
| 218 kTextfieldTextColor, | 218 kTextfieldTextColor, |
| 219 clip, | 219 clip, |
| 220 false); | 220 false); |
| 221 } | 221 } |
| 222 } else { | 222 } else { |
| 223 font_.DrawTextAt( | 223 font_.DrawTextAt( |
| 224 image, | 224 image, |
| 225 pp::TextRun_Dev(utf8_text_.c_str(), false, false), | 225 pp::BrowserFontTextRun(utf8_text_.c_str(), false, false), |
| 226 pp::Point(area_.x(), area_.y() + font_size_), | 226 pp::Point(area_.x(), area_.y() + font_size_), |
| 227 kTextfieldTextColor, | 227 kTextfieldTextColor, |
| 228 clip, | 228 clip, |
| 229 false); | 229 false); |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 | 232 |
| 233 // Update current composition text. | 233 // Update current composition text. |
| 234 void SetComposition( | 234 void SetComposition( |
| 235 const std::string& text, | 235 const std::string& text, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 // Handles mouse click event and changes the focus state. | 277 // Handles mouse click event and changes the focus state. |
| 278 bool RefocusByMouseClick(int x, int y) { | 278 bool RefocusByMouseClick(int x, int y) { |
| 279 if (!Contains(x, y)) { | 279 if (!Contains(x, y)) { |
| 280 // The text field is unfocused. | 280 // The text field is unfocused. |
| 281 caret_pos_ = anchor_pos_ = std::string::npos; | 281 caret_pos_ = anchor_pos_ = std::string::npos; |
| 282 return false; | 282 return false; |
| 283 } | 283 } |
| 284 | 284 |
| 285 // The text field is focused. | 285 // The text field is focused. |
| 286 size_t n = font_.CharacterOffsetForPixel( | 286 size_t n = font_.CharacterOffsetForPixel( |
| 287 pp::TextRun_Dev(utf8_text_.c_str()), x - area_.x()); | 287 pp::BrowserFontTextRun(utf8_text_.c_str()), x - area_.x()); |
| 288 caret_pos_ = anchor_pos_ = GetNthCharOffsetUtf8(utf8_text_, n); | 288 caret_pos_ = anchor_pos_ = GetNthCharOffsetUtf8(utf8_text_, n); |
| 289 CaretPosChanged(); | 289 CaretPosChanged(); |
| 290 return true; | 290 return true; |
| 291 } | 291 } |
| 292 | 292 |
| 293 void MouseDrag(int x, int y) { | 293 void MouseDrag(int x, int y) { |
| 294 if (!Focused()) | 294 if (!Focused()) |
| 295 return; | 295 return; |
| 296 size_t n = font_.CharacterOffsetForPixel( | 296 size_t n = font_.CharacterOffsetForPixel( |
| 297 pp::TextRun_Dev(utf8_text_.c_str()), x - area_.x()); | 297 pp::BrowserFontTextRun(utf8_text_.c_str()), x - area_.x()); |
| 298 caret_pos_ = GetNthCharOffsetUtf8(utf8_text_, n); | 298 caret_pos_ = GetNthCharOffsetUtf8(utf8_text_, n); |
| 299 } | 299 } |
| 300 | 300 |
| 301 void MouseUp(int x, int y) { | 301 void MouseUp(int x, int y) { |
| 302 if (!Focused()) | 302 if (!Focused()) |
| 303 return; | 303 return; |
| 304 CaretPosChanged(); | 304 CaretPosChanged(); |
| 305 } | 305 } |
| 306 | 306 |
| 307 void KeyLeft(bool shift) { | 307 void KeyLeft(bool shift) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 } | 380 } |
| 381 bool HasSelection() const { | 381 bool HasSelection() const { |
| 382 return caret_pos_ != anchor_pos_; | 382 return caret_pos_ != anchor_pos_; |
| 383 } | 383 } |
| 384 | 384 |
| 385 pp::Instance* instance_; | 385 pp::Instance* instance_; |
| 386 TextFieldStatusHandler* status_handler_; | 386 TextFieldStatusHandler* status_handler_; |
| 387 | 387 |
| 388 pp::Rect area_; | 388 pp::Rect area_; |
| 389 int font_size_; | 389 int font_size_; |
| 390 pp::Font_Dev font_; | 390 pp::BrowserFont_Trusted font_; |
| 391 std::string utf8_text_; | 391 std::string utf8_text_; |
| 392 size_t caret_pos_; | 392 size_t caret_pos_; |
| 393 size_t anchor_pos_; | 393 size_t anchor_pos_; |
| 394 std::string composition_; | 394 std::string composition_; |
| 395 std::vector< std::pair<uint32_t, uint32_t> > segments_; | 395 std::vector< std::pair<uint32_t, uint32_t> > segments_; |
| 396 std::pair<uint32_t, uint32_t> composition_selection_; | 396 std::pair<uint32_t, uint32_t> composition_selection_; |
| 397 int target_segment_; | 397 int target_segment_; |
| 398 }; | 398 }; |
| 399 | 399 |
| 400 class MyInstance : public pp::Instance { | 400 class MyInstance : public pp::Instance { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 } | 725 } |
| 726 }; | 726 }; |
| 727 | 727 |
| 728 namespace pp { | 728 namespace pp { |
| 729 | 729 |
| 730 Module* CreateModule() { | 730 Module* CreateModule() { |
| 731 return new MyModule(); | 731 return new MyModule(); |
| 732 } | 732 } |
| 733 | 733 |
| 734 } // namespace pp | 734 } // namespace pp |
| OLD | NEW |