1e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com/*
2e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com * Copyright 2012 Google Inc.
3e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com *
4e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com * Use of this source code is governed by a BSD-style license that can be
5e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com * found in the LICENSE file.
6e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com */
7e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
8e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#ifndef SkTextToPathIter_DEFINED
9e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#define SkTextToPathIter_DEFINED
10e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
11e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#include "SkAutoKern.h"
12e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#include "SkPaint.h"
13e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
14e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.comclass SkGlyphCache;
15e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
160449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkclass SkTextBaseIter {
170449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkprotected:
180449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkTextBaseIter(const char text[], size_t length, const SkPaint& paint,
190449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                   bool applyStrokeAndPathEffects);
200449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    ~SkTextBaseIter();
210449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
220449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkGlyphCache*   fCache;
230449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkPaint         fPaint;
240449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkScalar        fScale;
256b3eacb0dfaeb3374d410c8c041bd39cd066e1eabenjaminwagner    SkScalar        fPrevAdvance;
260449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    const char*     fText;
270449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    const char*     fStop;
28d936f63c35fb7dfb2b6c20802206adbfc3cc48d0benjaminwagner    SkPaint::GlyphCacheProc fGlyphCacheProc;
290449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
300449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkScalar        fXPos;      // accumulated xpos, returned in next
310449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkAutoKern      fAutoKern;
320449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    int             fXYIndex;   // cache for horizontal -vs- vertical text
330449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark};
340449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
350449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkclass SkTextToPathIter : SkTextBaseIter {
36e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.compublic:
37e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com    SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
380449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                     bool applyStrokeAndPathEffects)
390449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                     : SkTextBaseIter(text, length, paint, applyStrokeAndPathEffects) {
400449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    }
41e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
42e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com    const SkPaint&  getPaint() const { return fPaint; }
43e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com    SkScalar        getPathScale() const { return fScale; }
44e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
450449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    /**
460449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark     *  Returns false when all of the text has been consumed
470449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark     */
480449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    bool next(const SkPath** path, SkScalar* xpos);
490449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark};
500449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
510449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkclass SkTextInterceptsIter : SkTextBaseIter {
520449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkpublic:
530449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    enum class TextType {
540449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        kText,
550449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        kPosText
567b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com    };
577b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com
580449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkTextInterceptsIter(const char text[], size_t length, const SkPaint& paint,
590449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                         const SkScalar bounds[2], SkScalar x, SkScalar y, TextType textType)
600449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                         : SkTextBaseIter(text, length, paint, false)
610449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                         , fTextType(textType) {
620449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        fBoundsBase[0] = bounds[0];
630449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        fBoundsBase[1] = bounds[1];
640449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        this->setPosition(x, y);
650449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    }
660449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
677b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com    /**
687b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com     *  Returns false when all of the text has been consumed
697b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com     */
700449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    bool next(SkScalar* array, int* count);
71e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
720449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    void setPosition(SkScalar x, SkScalar y) {
730449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        SkScalar xOffset = TextType::kText == fTextType && fXYIndex ? fXPos : 0;
740449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        if (TextType::kPosText == fTextType
750449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                && fPaint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first
760449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            const char* text = fText;
770449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            const SkGlyph& glyph = fGlyphCacheProc(fCache, &text);
78a99b6ceff92183b424634f2e7276b9ea1d59e69dMike Reed            SkScalar width = (&glyph.fAdvanceX)[0] * fScale;
790449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            if (fPaint.getTextAlign() == SkPaint::kCenter_Align) {
800449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                width = SkScalarHalf(width);
810449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            }
820449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            xOffset = width;
830449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        }
84e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
850449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        for (int i = 0; i < (int) SK_ARRAY_COUNT(fBounds); ++i) {
860449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            SkScalar bound = fBoundsBase[i] - (fXYIndex ? x : y);
870449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            if (fXYIndex) {
880449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark                bound += xOffset;
890449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            }
900449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark            fBounds[i] = bound / fScale;
910449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        }
920449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
930449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        fXPos = xOffset + (fXYIndex ? y : x);
940449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark        fPrevAdvance = 0;
950449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    }
960449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark
970449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclarkprivate:
980449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkScalar fBounds[2];
990449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    SkScalar fBoundsBase[2];
1000449bcfb2fa1dd33cb3a4c0c8b17960d17edf01acaryclark    TextType fTextType;
101e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com};
102e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com
103e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#endif
104