1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd.. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef SKPARAGRAPH_SRC_TEXT_TAB_ALIGN_H 17#define SKPARAGRAPH_SRC_TEXT_TAB_ALIGN_H 18 19#include <string> 20#include "include/ParagraphStyle.h" 21#include "include/core/SkSpan.h" 22#include "modules/skparagraph/src/TextLine.h" 23#include "modules/skparagraph/src/TextWrapper.h" 24 25namespace skia { 26namespace textlayout { 27class TextTabAlign { 28public: 29 explicit TextTabAlign(const TextTabs& other) : fTabAlignMode(other.alignment), fTabPosition(other.location) {} 30 void init(SkScalar maxWidth, Cluster* endOfClusters); 31 32 bool processTab(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, Cluster* currentCluster, 33 SkScalar totalFakeSpacing) 34 { 35 if ((fTextTabFuncs != nullptr) && (this->fTextTabFuncs->processTabFunc != nullptr) && 36 (currentCluster != nullptr)) { 37 return (this->*(fTextTabFuncs->processTabFunc))(words, clusters, currentCluster, totalFakeSpacing); 38 } 39 return false; 40 } 41 42 bool processEndofWord(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, Cluster* currentCluster, 43 SkScalar totalFakeSpacing) 44 { 45 if ((fTextTabFuncs != nullptr) && (this->fTextTabFuncs->processEndofWordFunc != nullptr) && 46 (currentCluster != nullptr)) { 47 return (this->*(fTextTabFuncs->processEndofWordFunc))(words, clusters, currentCluster, totalFakeSpacing); 48 } 49 return false; 50 } 51 52 bool processEndofLine(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, Cluster* currentCluster, 53 SkScalar totalFakeSpacing) 54 { 55 if ((fTextTabFuncs != nullptr) && (this->fTextTabFuncs->processEndofLineFunc != nullptr) && 56 (currentCluster != nullptr)) { 57 return (this->*(fTextTabFuncs->processEndofLineFunc))(words, clusters, currentCluster, totalFakeSpacing); 58 } 59 return false; 60 } 61 62 bool processCluster(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, Cluster* currentCluster, 63 SkScalar totalFakeSpacing) 64 { 65 if ((fTextTabFuncs != nullptr) && (this->fTextTabFuncs->processClusterFunc != nullptr) && 66 (currentCluster != nullptr)) { 67 return (this->*(fTextTabFuncs->processClusterFunc))(words, clusters, currentCluster, totalFakeSpacing); 68 } 69 return false; 70 } 71 72private: 73 void expendTabCluster(SkScalar width); 74 75 bool leftAlignProcessTab(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 76 Cluster* currentCluster, SkScalar totalFakeSpacing); 77 bool leftAlignProcessEndofWord(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 78 Cluster* currentCluster, SkScalar totalFakeSpacing); 79 bool leftAlignProcessEndofLine(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 80 Cluster* currentCluster, SkScalar totalFakeSpacing); 81 bool leftAlignProcessCluster(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 82 Cluster* currentCluster, SkScalar totalFakeSpacing); 83 84 void rightAlignProcessTabBlockEnd(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters); 85 bool rightAlignProcessTab(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 86 Cluster* currentCluster, SkScalar totalFakeSpacing); 87 bool rightAlignProcessEndofWord(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 88 Cluster* currentCluster, SkScalar totalFakeSpacing); 89 bool rightAlignProcessEndofLine(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 90 Cluster* currentCluster, SkScalar totalFakeSpacing); 91 bool rightAlignProcessCluster(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 92 Cluster* currentCluster, SkScalar totalFakeSpacing); 93 94 bool centerAlignProcessTabBlockEnd(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters); 95 bool centerAlignProcessTab(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 96 Cluster* currentCluster, SkScalar totalFakeSpacing); 97 bool centerAlignProcessEndofWord(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 98 Cluster* currentCluster, SkScalar totalFakeSpacing); 99 bool centerAlignProcessEndofLine(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 100 Cluster* currentCluster, SkScalar totalFakeSpacing); 101 bool centerAlignProcessCluster(TextWrapper::TextStretch& words, TextWrapper::TextStretch& clusters, 102 Cluster* currentCluster, SkScalar totalFakeSpacing); 103 104 TextAlign fTabAlignMode; 105 SkScalar fTabPosition = 0.0; 106 bool fAlreadyInTab = false; 107 SkScalar fTabStartPos = 0.0; 108 SkScalar fTabEndPos = 0.0; 109 SkScalar fTabShift = 0.0; 110 int fTabIndex = 0; 111 int fMaxTabIndex = 0; 112 Cluster* fTabBlockEnd = nullptr; 113 Cluster* fEndOfClusters = nullptr; 114 SkScalar fMaxWidth; 115 Cluster* fTabCluster = nullptr; 116 117 using TextTabFunc = bool (TextTabAlign::*)(TextWrapper::TextStretch&, TextWrapper::TextStretch&, Cluster*, SkScalar); 118 struct TextTabFuncs { 119 TextTabFunc processTabFunc; 120 TextTabFunc processEndofWordFunc; 121 TextTabFunc processEndofLineFunc; 122 TextTabFunc processClusterFunc; 123 }; 124 constexpr static size_t textAlignCount = static_cast<size_t>(TextAlign::kCenter) + 1; 125 static TextTabFuncs fTextTabFuncsTable[textAlignCount]; 126 TextTabFuncs* fTextTabFuncs = nullptr; 127 128}; 129} // namespace textlayout 130} // namespace skia 131 132#endif // SKPARAGRAPH_SRC_TEXT_TAB_ALIGN_H