1 /* 2 * 3 * Copyright 2019, The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #ifndef LIBTEEUI_LABEL_H_ 19 #define LIBTEEUI_LABEL_H_ 20 21 #include "utf8range.h" 22 #include "utils.h" 23 24 // #define DRAW_DEBUG_MARKERS 25 26 namespace teeui { 27 28 enum class Alignment : int8_t { LEFT, CENTER, RIGHT, TOP, BOTTOM }; 29 30 class FontBuffer { 31 const uint8_t* data_; 32 size_t size_; 33 34 public: FontBuffer()35 constexpr FontBuffer() : data_(nullptr), size_(0) {} FontBuffer(const uint8_t * data,size_t size)36 constexpr FontBuffer(const uint8_t* data, size_t size) noexcept : data_(data), size_(size) {} 37 template <size_t size> FontBuffer(const uint8_t (& data)[size])38 explicit constexpr FontBuffer(const uint8_t (&data)[size]) noexcept 39 : data_(&data[0]), size_(size) {} 40 constexpr FontBuffer(const FontBuffer&) noexcept = default; 41 constexpr FontBuffer(FontBuffer&&) noexcept = default; 42 FontBuffer& operator=(FontBuffer&&) noexcept = default; 43 FontBuffer& operator=(const FontBuffer&) noexcept = default; 44 45 constexpr operator bool() const { return data_ != nullptr; } 46 data()47 const uint8_t* data() const { return data_; } size()48 size_t size() const { return size_; } 49 }; 50 51 class LabelImpl { 52 using text_t = UTF8Range<const char*>; 53 54 public: 55 struct LineInfo { 56 struct info_t { 57 Point<pxs> lineStart; 58 text_t lineText; 59 }; 60 size_t size_; 61 info_t* info_; beginLineInfo62 info_t* begin() { return &info_[0]; } endLineInfo63 info_t* end() { return &info_[size_]; } beginLineInfo64 const info_t* begin() const { return &info_[0]; } endLineInfo65 const info_t* end() const { return &info_[size_]; } 66 }; 67 LabelImpl()68 LabelImpl() 69 : fontSize_(10_px), lineHeight_(12_px), text_{}, horizontalTextAlignment_(Alignment::LEFT), 70 verticalTextAlignment_(Alignment::TOP), textColor_(0), font_{}, textId_(0) {} LabelImpl(pxs fontSize,pxs lineHeight,text_t text,Alignment horizontal,Alignment verticalJustified,Color textColor,FontBuffer font,uint64_t textId)71 LabelImpl(pxs fontSize, pxs lineHeight, text_t text, Alignment horizontal, 72 Alignment verticalJustified, Color textColor, FontBuffer font, uint64_t textId) 73 : fontSize_(fontSize), lineHeight_(lineHeight), text_(text), 74 horizontalTextAlignment_(horizontal), verticalTextAlignment_(verticalJustified), 75 textColor_(textColor), font_(font), textId_(textId) {} 76 fontSize()77 pxs fontSize() const { return fontSize_; } 78 setText(text_t text)79 void setText(text_t text) { text_ = text; } setTextColor(Color color)80 void setTextColor(Color color) { textColor_ = color; } 81 text()82 text_t text() const { return text_; } textId()83 uint64_t textId() const { return textId_; } 84 85 Error draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds, LineInfo* lineInfo); setCB(CallbackEvent cbEvent)86 void setCB(CallbackEvent cbEvent) { cbEvent_ = std::move(cbEvent); } getCB()87 optional<CallbackEvent> getCB() { return cbEvent_; } 88 Error hit(const Event& event, const Box<pxs>& bounds); 89 90 private: 91 pxs fontSize_; 92 pxs lineHeight_; 93 text_t text_; 94 Alignment horizontalTextAlignment_; 95 Alignment verticalTextAlignment_; 96 Color textColor_; 97 FontBuffer font_; 98 uint64_t textId_; 99 optional<CallbackEvent> cbEvent_; 100 }; 101 102 /** 103 * Label is a LayoutElement and should be used as second argument in the BEGIN_ELEMENT() macro. 104 * The template argument Derived is the new class derived from Label, that is created by the 105 * BEGIN_ELEMENT() macro. 106 */ 107 template <typename Derived> class Label : public LayoutElement<Derived>, public LabelImpl { 108 public: 109 static const constexpr Alignment label_horizontal_text_alignment = Alignment::LEFT; 110 static const constexpr Alignment label_vertical_text_alignment = Alignment::TOP; 111 static const constexpr Color label_text_color = 0xff000000; 112 static const constexpr int label_font = 0; 113 static const constexpr uint64_t text_id = 0; 114 115 Label() = default; 116 template <typename Context> Label(const Context & context)117 Label(const Context& context) 118 : LayoutElement<Derived>(context), 119 LabelImpl( 120 context = Derived::label_font_size, context = Derived::label_line_height, 121 {&Derived::label_text[0], &Derived::label_text[sizeof(Derived::label_text) - 1]}, 122 Derived::label_horizontal_text_alignment, Derived::label_vertical_text_alignment, 123 context = Derived::label_text_color, getFont(Derived::label_font), Derived::text_id) { 124 } 125 draw(const PixelDrawer & drawPixel)126 Error draw(const PixelDrawer& drawPixel) { 127 LabelImpl::LineInfo::info_t lines[Derived::label_number_of_lines]; 128 LabelImpl::LineInfo lineInfo = {Derived::label_number_of_lines, lines}; 129 return LabelImpl::draw(drawPixel, this->bounds_, &lineInfo); 130 } 131 hit(const Event & event)132 Error hit(const Event& event) { return LabelImpl::hit(event, this->bounds_); } 133 }; 134 135 } // namespace teeui 136 137 #define FontSize(fs) static const constexpr auto label_font_size = fs 138 139 #define DefaultText(text) static const constexpr char label_text[] = text 140 141 #define LineHeight(height) static const constexpr auto label_line_height = height 142 143 #define NumberOfLines(lines) static const constexpr auto label_number_of_lines = lines 144 145 #define HeightFromLines (label_line_height * pxs(label_number_of_lines)) 146 147 #define HorizontalTextAlignment(horizontalAligment) \ 148 static const constexpr Alignment label_horizontal_text_alignment = horizontalAligment; 149 150 #define RightJustified HorizontalTextAlignment(Alignment::RIGHT) 151 152 #define VerticalTextAlignment(verticalAligment) \ 153 static const constexpr Alignment label_vertical_text_alignment = verticalAligment; 154 155 #define VerticallyCentered VerticalTextAlignment(Alignment::CENTER) 156 157 #define TextColor(color) static const constexpr auto label_text_color = color 158 159 #define FONT(name) TEEUI_FONT_##name() 160 161 #define DECLARE_FONT_BUFFER(name, buffer, ...) \ 162 struct TEEUI_FONT_##name {}; \ 163 inline FontBuffer getFont(TEEUI_FONT_##name) { return FontBuffer(buffer, ##__VA_ARGS__); } 164 165 #define Font(fontbuffer) static const constexpr auto label_font = fontbuffer 166 167 #define TextID(tid) static const constexpr uint64_t text_id = tid 168 169 #endif // LIBTEEUI_LABEL_H_ 170