1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkTextToPathIter_DEFINED
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkTextToPathIter_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkAutoKern.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkGlyphCache;
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkTextBaseIter {
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTextBaseIter(const char text[], size_t length, const SkPaint& paint,
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   bool applyStrokeAndPathEffects);
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkTextBaseIter();
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkGlyphCache*   fCache;
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint         fPaint;
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        fScale;
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        fPrevAdvance;
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char*     fText;
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char*     fStop;
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint::GlyphCacheProc fGlyphCacheProc;
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        fXPos;      // accumulated xpos, returned in next
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkAutoKern      fAutoKern;
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int             fXYIndex;   // cache for horizontal -vs- vertical text
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkTextToPathIter : SkTextBaseIter {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     bool applyStrokeAndPathEffects)
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     : SkTextBaseIter(text, length, paint, applyStrokeAndPathEffects) {
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkPaint&  getPaint() const { return fPaint; }
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        getPathScale() const { return fScale; }
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Returns false when all of the text has been consumed
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool next(const SkPath** path, SkScalar* xpos);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SkTextInterceptsIter : SkTextBaseIter {
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class TextType {
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kText,
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPosText
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTextInterceptsIter(const char text[], size_t length, const SkPaint& paint,
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         const SkScalar bounds[2], SkScalar x, SkScalar y, TextType textType)
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         : SkTextBaseIter(text, length, paint, false)
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         , fTextType(textType) {
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBoundsBase[0] = bounds[0];
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fBoundsBase[1] = bounds[1];
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setPosition(x, y);
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /**
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     *  Returns false when all of the text has been consumed
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     */
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool next(SkScalar* array, int* count);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setPosition(SkScalar x, SkScalar y) {
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar xOffset = TextType::kText == fTextType && fXYIndex ? fXPos : 0;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (TextType::kPosText == fTextType
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                && fPaint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const char* text = fText;
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const SkGlyph& glyph = fGlyphCacheProc(fCache, &text);
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar width = (&glyph.fAdvanceX)[0] * fScale;
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fPaint.getTextAlign() == SkPaint::kCenter_Align) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                width = SkScalarHalf(width);
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            xOffset = width;
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < (int) SK_ARRAY_COUNT(fBounds); ++i) {
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkScalar bound = fBoundsBase[i] - (fXYIndex ? x : y);
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (fXYIndex) {
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                bound += xOffset;
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fBounds[i] = bound / fScale;
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fXPos = xOffset + (fXYIndex ? y : x);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPrevAdvance = 0;
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fBounds[2];
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar fBoundsBase[2];
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TextType fTextType;
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
104