| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2010 Google Inc. |    2  * Copyright 2010 Google Inc. | 
|    3  * |    3  * | 
|    4  * Use of this source code is governed by a BSD-style license that can be |    4  * Use of this source code is governed by a BSD-style license that can be | 
|    5  * found in the LICENSE file. |    5  * found in the LICENSE file. | 
|    6  */ |    6  */ | 
|    7  |    7  | 
|    8 #include "GrTextContext.h" |    8 #include "GrTextContext.h" | 
|    9 #include "GrBlurUtils.h" |  | 
|   10 #include "GrContext.h" |    9 #include "GrContext.h" | 
|   11 #include "GrDrawContext.h" |  | 
|   12 #include "GrFontScaler.h" |   10 #include "GrFontScaler.h" | 
 |   11 #include "GrTextUtils.h" | 
|   13  |   12  | 
|   14 #include "SkAutoKern.h" |  | 
|   15 #include "SkDrawFilter.h" |   13 #include "SkDrawFilter.h" | 
|   16 #include "SkDrawProcs.h" |  | 
|   17 #include "SkGlyphCache.h" |   14 #include "SkGlyphCache.h" | 
|   18 #include "SkGpuDevice.h" |  | 
|   19 #include "SkGrPriv.h" |   15 #include "SkGrPriv.h" | 
|   20 #include "SkTextBlobRunIterator.h" |   16 #include "SkTextBlobRunIterator.h" | 
|   21 #include "SkTextMapStateProc.h" |  | 
|   22 #include "SkTextToPathIter.h" |  | 
|   23  |   17  | 
|   24 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr
     ops) |   18 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr
     ops) | 
|   25     : fFallbackTextContext(nullptr) |   19     : fFallbackTextContext(nullptr) | 
|   26     , fContext(context) |   20     , fContext(context) | 
|   27     , fSurfaceProps(surfaceProps) { |   21     , fSurfaceProps(surfaceProps) { | 
|   28 } |   22 } | 
|   29  |   23  | 
|   30 GrTextContext::~GrTextContext() { |   24 GrTextContext::~GrTextContext() { | 
|   31     delete fFallbackTextContext; |   25     delete fFallbackTextContext; | 
|   32 } |   26 } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   44     do { |   38     do { | 
|   45         if (textContext->canDraw(skPaint, viewMatrix)) { |   39         if (textContext->canDraw(skPaint, viewMatrix)) { | 
|   46             textContext->onDrawText(dc, clip, paint, skPaint, viewMatrix, |   40             textContext->onDrawText(dc, clip, paint, skPaint, viewMatrix, | 
|   47                                     text, byteLength, x, y, clipBounds); |   41                                     text, byteLength, x, y, clipBounds); | 
|   48             return; |   42             return; | 
|   49         } |   43         } | 
|   50         textContext = textContext->fFallbackTextContext; |   44         textContext = textContext->fFallbackTextContext; | 
|   51     } while (textContext); |   45     } while (textContext); | 
|   52  |   46  | 
|   53     // fall back to drawing as a path |   47     // fall back to drawing as a path | 
|   54     this->drawTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, x, y, 
     clipBounds); |   48     GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, b
     yteLength, x, y, | 
 |   49                                 clipBounds); | 
|   55 } |   50 } | 
|   56  |   51  | 
|   57 void GrTextContext::drawPosText(GrDrawContext* dc, |   52 void GrTextContext::drawPosText(GrDrawContext* dc, | 
|   58                                 const GrClip& clip, const GrPaint& paint, |   53                                 const GrClip& clip, const GrPaint& paint, | 
|   59                                 const SkPaint& skPaint, const SkMatrix& viewMatr
     ix, |   54                                 const SkPaint& skPaint, const SkMatrix& viewMatr
     ix, | 
|   60                                 const char text[], size_t byteLength, |   55                                 const char text[], size_t byteLength, | 
|   61                                 const SkScalar pos[], int scalarsPerPosition, |   56                                 const SkScalar pos[], int scalarsPerPosition, | 
|   62                                 const SkPoint& offset, const SkIRect& clipBounds
     ) { |   57                                 const SkPoint& offset, const SkIRect& clipBounds
     ) { | 
|   63     if (fContext->abandoned()) { |   58     if (fContext->abandoned()) { | 
|   64         return; |   59         return; | 
|   65     } |   60     } | 
|   66  |   61  | 
|   67     GrTextContext* textContext = this; |   62     GrTextContext* textContext = this; | 
|   68     do { |   63     do { | 
|   69         if (textContext->canDraw(skPaint, viewMatrix)) { |   64         if (textContext->canDraw(skPaint, viewMatrix)) { | 
|   70             textContext->onDrawPosText(dc, clip, paint, skPaint, viewMatrix, |   65             textContext->onDrawPosText(dc, clip, paint, skPaint, viewMatrix, | 
|   71                                        text, byteLength, pos, |   66                                        text, byteLength, pos, | 
|   72                                        scalarsPerPosition, offset, clipBounds); |   67                                        scalarsPerPosition, offset, clipBounds); | 
|   73             return; |   68             return; | 
|   74         } |   69         } | 
|   75         textContext = textContext->fFallbackTextContext; |   70         textContext = textContext->fFallbackTextContext; | 
|   76     } while (textContext); |   71     } while (textContext); | 
|   77  |   72  | 
|   78     // fall back to drawing as a path |   73     // fall back to drawing as a path | 
|   79     this->drawPosTextAsPath(dc, clip, skPaint, viewMatrix, text, byteLength, pos
     , |   74     GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, v
     iewMatrix, text, | 
|   80                             scalarsPerPosition, offset, clipBounds); |   75                                    byteLength, pos, scalarsPerPosition, offset, 
     clipBounds); | 
|   81 } |   76 } | 
|   82  |   77  | 
|   83 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { |   78 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { | 
|   84     if (!SkXfermode::AsMode(paint.getXfermode(), nullptr) || |   79     if (!SkXfermode::AsMode(paint.getXfermode(), nullptr) || | 
|   85         paint.getMaskFilter() || |   80         paint.getMaskFilter() || | 
|   86         paint.getRasterizer() || |   81         paint.getRasterizer() || | 
|   87         paint.getPathEffect() || |   82         paint.getPathEffect() || | 
|   88         paint.isFakeBoldText() || |   83         paint.isFakeBoldText() || | 
|   89         paint.getStyle() != SkPaint::kFill_Style) |   84         paint.getStyle() != SkPaint::kFill_Style) | 
|   90     { |   85     { | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  153             SkFAIL("unhandled positioning mode"); |  148             SkFAIL("unhandled positioning mode"); | 
|  154         } |  149         } | 
|  155  |  150  | 
|  156         if (drawFilter) { |  151         if (drawFilter) { | 
|  157             // A draw filter may change the paint arbitrarily, so we must re-see
     d in this case. |  152             // A draw filter may change the paint arbitrarily, so we must re-see
     d in this case. | 
|  158             runPaint = skPaint; |  153             runPaint = skPaint; | 
|  159         } |  154         } | 
|  160     } |  155     } | 
|  161 } |  156 } | 
|  162  |  157  | 
|  163 void GrTextContext::drawTextAsPath(GrDrawContext* dc, |  | 
|  164                                    const GrClip& clip, |  | 
|  165                                    const SkPaint& skPaint, const SkMatrix& viewM
     atrix, |  | 
|  166                                    const char text[], size_t byteLength, SkScala
     r x, SkScalar y, |  | 
|  167                                    const SkIRect& clipBounds) { |  | 
|  168     SkTextToPathIter iter(text, byteLength, skPaint, true); |  | 
|  169  |  | 
|  170     SkMatrix    matrix; |  | 
|  171     matrix.setScale(iter.getPathScale(), iter.getPathScale()); |  | 
|  172     matrix.postTranslate(x, y); |  | 
|  173  |  | 
|  174     const SkPath* iterPath; |  | 
|  175     SkScalar xpos, prevXPos = 0; |  | 
|  176  |  | 
|  177     while (iter.next(&iterPath, &xpos)) { |  | 
|  178         matrix.postTranslate(xpos - prevXPos, 0); |  | 
|  179         if (iterPath) { |  | 
|  180             const SkPaint& pnt = iter.getPaint(); |  | 
|  181             GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *iterPath, |  | 
|  182                                                 pnt, viewMatrix, &matrix, clipBo
     unds, false); |  | 
|  183         } |  | 
|  184         prevXPos = xpos; |  | 
|  185     } |  | 
|  186 } |  | 
|  187  |  | 
|  188 void GrTextContext::drawPosTextAsPath(GrDrawContext* dc, |  | 
|  189                                       const GrClip& clip, |  | 
|  190                                       const SkPaint& origPaint, const SkMatrix& 
     viewMatrix, |  | 
|  191                                       const char text[], size_t byteLength, |  | 
|  192                                       const SkScalar pos[], int scalarsPerPositi
     on, |  | 
|  193                                       const SkPoint& offset, const SkIRect& clip
     Bounds) { |  | 
|  194     // setup our std paint, in hopes of getting hits in the cache |  | 
|  195     SkPaint paint(origPaint); |  | 
|  196     SkScalar matrixScale = paint.setupForAsPaths(); |  | 
|  197  |  | 
|  198     SkMatrix matrix; |  | 
|  199     matrix.setScale(matrixScale, matrixScale); |  | 
|  200  |  | 
|  201     // Temporarily jam in kFill, so we only ever ask for the raw outline from th
     e cache. |  | 
|  202     paint.setStyle(SkPaint::kFill_Style); |  | 
|  203     paint.setPathEffect(nullptr); |  | 
|  204  |  | 
|  205     SkDrawCacheProc     glyphCacheProc = paint.getDrawCacheProc(); |  | 
|  206     SkAutoGlyphCache    autoCache(paint, &fSurfaceProps, nullptr); |  | 
|  207     SkGlyphCache*       cache = autoCache.getCache(); |  | 
|  208  |  | 
|  209     const char*        stop = text + byteLength; |  | 
|  210     SkTextAlignProc    alignProc(paint.getTextAlign()); |  | 
|  211     SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); |  | 
|  212  |  | 
|  213     // Now restore the original settings, so we "draw" with whatever style/strok
     ing. |  | 
|  214     paint.setStyle(origPaint.getStyle()); |  | 
|  215     paint.setPathEffect(origPaint.getPathEffect()); |  | 
|  216  |  | 
|  217     while (text < stop) { |  | 
|  218         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |  | 
|  219         if (glyph.fWidth) { |  | 
|  220             const SkPath* path = cache->findPath(glyph); |  | 
|  221             if (path) { |  | 
|  222                 SkPoint tmsLoc; |  | 
|  223                 tmsProc(pos, &tmsLoc); |  | 
|  224                 SkPoint loc; |  | 
|  225                 alignProc(tmsLoc, glyph, &loc); |  | 
|  226  |  | 
|  227                 matrix[SkMatrix::kMTransX] = loc.fX; |  | 
|  228                 matrix[SkMatrix::kMTransY] = loc.fY; |  | 
|  229                 GrBlurUtils::drawPathWithMaskFilter(fContext, dc, clip, *path, p
     aint, |  | 
|  230                                                     viewMatrix, &matrix, clipBou
     nds, false); |  | 
|  231             } |  | 
|  232         } |  | 
|  233         pos += scalarsPerPosition; |  | 
|  234     } |  | 
|  235 } |  | 
|  236  |  | 
|  237 // *** change to output positions? |  | 
|  238 int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCachePr
     oc, |  | 
|  239                                 const char text[], size_t byteLength, SkVector* 
     stopVector) { |  | 
|  240     SkFixed     x = 0, y = 0; |  | 
|  241     const char* stop = text + byteLength; |  | 
|  242  |  | 
|  243     SkAutoKern  autokern; |  | 
|  244  |  | 
|  245     int numGlyphs = 0; |  | 
|  246     while (text < stop) { |  | 
|  247         // don't need x, y here, since all subpixel variants will have the |  | 
|  248         // same advance |  | 
|  249         const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |  | 
|  250  |  | 
|  251         x += autokern.adjust(glyph) + glyph.fAdvanceX; |  | 
|  252         y += glyph.fAdvanceY; |  | 
|  253         ++numGlyphs; |  | 
|  254     } |  | 
|  255     stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); |  | 
|  256  |  | 
|  257     SkASSERT(text == stop); |  | 
|  258      |  | 
|  259     return numGlyphs; |  | 
|  260 } |  | 
|  261  |  | 
|  262 static void GlyphCacheAuxProc(void* data) { |  158 static void GlyphCacheAuxProc(void* data) { | 
|  263     GrFontScaler* scaler = (GrFontScaler*)data; |  159     GrFontScaler* scaler = (GrFontScaler*)data; | 
|  264     SkSafeUnref(scaler); |  160     SkSafeUnref(scaler); | 
|  265 } |  161 } | 
|  266  |  162  | 
|  267 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { |  163 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { | 
|  268     void* auxData; |  164     void* auxData; | 
|  269     GrFontScaler* scaler = nullptr; |  165     GrFontScaler* scaler = nullptr; | 
|  270  |  166  | 
|  271     if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { |  167     if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { | 
|  272         scaler = (GrFontScaler*)auxData; |  168         scaler = (GrFontScaler*)auxData; | 
|  273     } |  169     } | 
|  274     if (nullptr == scaler) { |  170     if (nullptr == scaler) { | 
|  275         scaler = new GrFontScaler(cache); |  171         scaler = new GrFontScaler(cache); | 
|  276         cache->setAuxProc(GlyphCacheAuxProc, scaler); |  172         cache->setAuxProc(GlyphCacheAuxProc, scaler); | 
|  277     } |  173     } | 
|  278  |  174  | 
|  279     return scaler; |  175     return scaler; | 
|  280 } |  176 } | 
| OLD | NEW |