1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Minikin" 18#include "minikin/MeasuredText.h" 19 20#include "minikin/Layout.h" 21 22#include "LayoutUtils.h" 23#include "LineBreakerUtil.h" 24 25namespace minikin { 26 27void MeasuredText::measure(const U16StringPiece& textBuf, bool computeHyphenation, 28 bool computeLayout) { 29 if (textBuf.size() == 0) { 30 return; 31 } 32 LayoutPieces* piecesOut = computeLayout ? &layoutPieces : nullptr; 33 CharProcessor proc(textBuf); 34 for (const auto& run : runs) { 35 const Range& range = run->getRange(); 36 const uint32_t runOffset = range.getStart(); 37 run->getMetrics(textBuf, widths.data() + runOffset, extents.data() + runOffset, piecesOut); 38 39 if (!computeHyphenation || !run->canHyphenate()) { 40 continue; 41 } 42 43 proc.updateLocaleIfNecessary(*run); 44 for (uint32_t i = range.getStart(); i < range.getEnd(); ++i) { 45 proc.feedChar(i, textBuf[i], widths[i]); 46 47 const uint32_t nextCharOffset = i + 1; 48 if (nextCharOffset != proc.nextWordBreak) { 49 continue; // Wait until word break point. 50 } 51 52 populateHyphenationPoints(textBuf, *run, *proc.hyphenator, proc.contextRange(), 53 proc.wordRange(), &hyphenBreaks, piecesOut); 54 } 55 } 56} 57 58void MeasuredText::buildLayout(const U16StringPiece& textBuf, const Range& range, 59 const MinikinPaint& paint, Bidi bidiFlags, 60 StartHyphenEdit startHyphen, EndHyphenEdit endHyphen, 61 Layout* layout) { 62 layout->doLayoutWithPrecomputedPieces(textBuf, range, bidiFlags, paint, startHyphen, endHyphen, 63 layoutPieces); 64} 65 66MinikinRect MeasuredText::getBounds(const U16StringPiece& textBuf, const Range& range) { 67 MinikinRect rect; 68 float advance = 0.0f; 69 for (const auto& run : runs) { 70 const Range& runRange = run->getRange(); 71 if (!Range::intersects(range, runRange)) { 72 continue; 73 } 74 std::pair<float, MinikinRect> next = 75 run->getBounds(textBuf, Range::intersection(runRange, range), layoutPieces); 76 MinikinRect nextRect = next.second; 77 nextRect.offset(advance, 0); 78 rect.join(nextRect); 79 advance += next.first; 80 } 81 return rect; 82} 83 84} // namespace minikin 85