Flutter Engine
The Flutter Engine
Functions
shape.cpp File Reference
#include "modules/skplaintexteditor/src/shape.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTFitsIn.h"
#include "modules/skplaintexteditor/src/word_boundaries.h"
#include "modules/skshaper/include/SkShaper.h"
#include "src/base/SkUTF.h"
#include "src/core/SkTextBlobPriv.h"
#include <cfloat>
#include <climits>
#include <cstring>

Go to the source code of this file.

Functions

static SkRect selection_box (const SkFontMetrics &metrics, float advance, SkPoint pos)
 
static void set_character_bounds (void *context, const char *utf8Text, size_t utf8TextBytes, size_t glyphCount, const SkGlyphID *glyphs, const SkPoint *positions, const uint32_t *clusters, const SkFont &font)
 

Function Documentation

◆ selection_box()

static SkRect selection_box ( const SkFontMetrics metrics,
float  advance,
SkPoint  pos 
)
static

Definition at line 213 of file shape.cpp.

215 {
216 if (fabsf(advance) < 1.0f) {
217 advance = copysignf(1.0f, advance);
218 }
219 return SkRect{pos.x(),
220 pos.y() + metrics.fAscent,
221 pos.x() + advance,
222 pos.y() + metrics.fDescent}.makeSorted();
223}
SkPoint pos
SkScalar fAscent
distance to reserve above baseline, typically negative
Definition: SkFontMetrics.h:54
SkScalar fDescent
distance to reserve below baseline, typically positive
Definition: SkFontMetrics.h:55
constexpr float y() const
Definition: SkPoint_impl.h:187
constexpr float x() const
Definition: SkPoint_impl.h:181

◆ set_character_bounds()

static void set_character_bounds ( void *  context,
const char *  utf8Text,
size_t  utf8TextBytes,
size_t  glyphCount,
const SkGlyphID glyphs,
const SkPoint positions,
const uint32_t *  clusters,
const SkFont font 
)
static

Definition at line 225 of file shape.cpp.

233{
234 SkASSERT(context);
235 SkASSERT(glyphCount > 0);
236 SkRect* cursors = (SkRect*)context;
237
238 SkFontMetrics metrics;
239 font.getMetrics(&metrics);
240 std::unique_ptr<float[]> advances(new float[glyphCount]);
241 font.getWidths(glyphs, glyphCount, advances.get());
242
243 // Loop over each cluster in this run.
244 size_t clusterStart = 0;
245 for (size_t glyphIndex = 0; glyphIndex < glyphCount; ++glyphIndex) {
246 if (glyphIndex + 1 < glyphCount // more glyphs
247 && clusters[glyphIndex] == clusters[glyphIndex + 1]) {
248 continue; // multi-glyph cluster
249 }
250 unsigned textBegin = clusters[glyphIndex];
251 unsigned textEnd = utf8TextBytes;
252 for (size_t i = 0; i < glyphCount; ++i) {
253 if (clusters[i] >= textEnd) {
254 textEnd = clusters[i] + 1;
255 }
256 }
257 for (size_t i = 0; i < glyphCount; ++i) {
258 if (clusters[i] > textBegin && clusters[i] < textEnd) {
259 textEnd = clusters[i];
260 if (textEnd == textBegin + 1) { break; }
261 }
262 }
263 SkASSERT(glyphIndex + 1 > clusterStart);
264 unsigned clusterGlyphCount = glyphIndex + 1 - clusterStart;
265 const SkPoint* clusterGlyphPositions = &positions[clusterStart];
266 const float* clusterAdvances = &advances[clusterStart];
267 clusterStart = glyphIndex + 1; // for next loop
268
269 SkRect clusterBox = selection_box(metrics, clusterAdvances[0], clusterGlyphPositions[0]);
270 for (unsigned i = 1; i < clusterGlyphCount; ++i) { // multiple glyphs
271 clusterBox.join(selection_box(metrics, clusterAdvances[i], clusterGlyphPositions[i]));
272 }
273 if (textBegin + 1 == textEnd) { // single byte, fast path.
274 cursors[textBegin] = clusterBox;
275 continue;
276 }
277 int textCount = textEnd - textBegin;
278 int codePointCount = SkUTF::CountUTF8(utf8Text + textBegin, textCount);
279 if (codePointCount == 1) { // single codepoint, fast path.
280 cursors[textBegin] = clusterBox;
281 continue;
282 }
283
284 float width = clusterBox.width() / codePointCount;
285 SkASSERT(width > 0);
286 const char* ptr = utf8Text + textBegin;
287 const char* end = utf8Text + textEnd;
288 float x = clusterBox.left();
289 while (ptr < end) { // for each codepoint in cluster
290 const char* nextPtr = ptr;
291 SkUTF::NextUTF8(&nextPtr, end);
292 int firstIndex = ptr - utf8Text;
293 float nextX = x + width;
294 cursors[firstIndex] = SkRect{x, clusterBox.top(), nextX, clusterBox.bottom()};
295 x = nextX;
296 ptr = nextPtr;
297 }
298 }
299}
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
#define SkASSERT(cond)
Definition: SkAssert.h:116
glong glong end
double x
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
Definition: SkUTF.cpp:118
SK_SPI int CountUTF8(const char *utf8, size_t byteLength)
Definition: SkUTF.cpp:47
font
Font Metadata and Metrics.
int32_t width
static SkRect selection_box(const SkFontMetrics &metrics, float advance, SkPoint pos)
Definition: shape.cpp:213
constexpr float left() const
Definition: SkRect.h:734
constexpr float top() const
Definition: SkRect.h:741
constexpr float width() const
Definition: SkRect.h:762
void join(const SkRect &r)
Definition: SkRect.cpp:126
constexpr float bottom() const
Definition: SkRect.h:755