gfx/skia/trunk/src/core/SkBitmapDevice.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2013 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkBitmapDevice.h"
     9 #include "SkConfig8888.h"
    10 #include "SkDraw.h"
    11 #include "SkRasterClip.h"
    12 #include "SkShader.h"
    13 #include "SkSurface.h"
    15 #define CHECK_FOR_ANNOTATION(paint) \
    16     do { if (paint.getAnnotation()) { return; } } while (0)
    18 static bool valid_for_bitmap_device(const SkImageInfo& info,
    19                                     SkAlphaType* newAlphaType) {
    20     if (info.width() < 0 || info.height() < 0) {
    21         return false;
    22     }
    24     // TODO: can we stop supporting kUnknown in SkBitmkapDevice?
    25     if (kUnknown_SkColorType == info.colorType()) {
    26         if (newAlphaType) {
    27             *newAlphaType = kIgnore_SkAlphaType;
    28         }
    29         return true;
    30     }
    32     switch (info.alphaType()) {
    33         case kPremul_SkAlphaType:
    34         case kOpaque_SkAlphaType:
    35             break;
    36         default:
    37             return false;
    38     }
    40     SkAlphaType canonicalAlphaType = info.alphaType();
    42     switch (info.colorType()) {
    43         case kAlpha_8_SkColorType:
    44             break;
    45         case kRGB_565_SkColorType:
    46             canonicalAlphaType = kOpaque_SkAlphaType;
    47             break;
    48         case kPMColor_SkColorType:
    49             break;
    50         default:
    51             return false;
    52     }
    54     if (newAlphaType) {
    55         *newAlphaType = canonicalAlphaType;
    56     }
    57     return true;
    58 }
    60 SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) : fBitmap(bitmap) {
    61     SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
    62 }
    64 SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
    65     : SkBaseDevice(deviceProperties)
    66     , fBitmap(bitmap)
    67 {
    68     SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL));
    69 }
    71 #ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
    72 void SkBitmapDevice::init(SkBitmap::Config config, int width, int height, bool isOpaque) {
    73     fBitmap.setConfig(config, width, height, 0, isOpaque ?
    74                       kOpaque_SkAlphaType : kPremul_SkAlphaType);
    76     if (SkBitmap::kNo_Config != config) {
    77         if (!fBitmap.allocPixels()) {
    78             // indicate failure by zeroing our bitmap
    79             fBitmap.setConfig(config, 0, 0, 0, isOpaque ?
    80                               kOpaque_SkAlphaType : kPremul_SkAlphaType);
    81         } else if (!isOpaque) {
    82             fBitmap.eraseColor(SK_ColorTRANSPARENT);
    83         }
    84     }
    85 }
    87 SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
    88     this->init(config, width, height, isOpaque);
    89 }
    91 SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
    92                                const SkDeviceProperties& deviceProperties)
    93     : SkBaseDevice(deviceProperties)
    94 {
    95     this->init(config, width, height, isOpaque);
    96 }
    97 #endif
    98 SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
    99                                        const SkDeviceProperties* props) {
   100     SkImageInfo info = origInfo;
   101     if (!valid_for_bitmap_device(info, &info.fAlphaType)) {
   102         return NULL;
   103     }
   105     SkBitmap bitmap;
   107     if (kUnknown_SkColorType == info.colorType()) {
   108         if (!bitmap.setConfig(info)) {
   109             return NULL;
   110         }
   111     } else {
   112         if (!bitmap.allocPixels(info)) {
   113             return NULL;
   114         }
   115         if (!bitmap.info().isOpaque()) {
   116             bitmap.eraseColor(SK_ColorTRANSPARENT);
   117         }
   118     }
   120     if (props) {
   121         return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props));
   122     } else {
   123         return SkNEW_ARGS(SkBitmapDevice, (bitmap));
   124     }
   125 }
   127 SkImageInfo SkBitmapDevice::imageInfo() const {
   128     return fBitmap.info();
   129 }
   131 void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
   132     SkASSERT(bm.width() == fBitmap.width());
   133     SkASSERT(bm.height() == fBitmap.height());
   134     fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
   135     fBitmap.lockPixels();
   136 }
   138 SkBaseDevice* SkBitmapDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
   139     return SkBitmapDevice::Create(info, &this->getDeviceProperties());
   140 }
   142 void SkBitmapDevice::lockPixels() {
   143     if (fBitmap.lockPixelsAreWritable()) {
   144         fBitmap.lockPixels();
   145     }
   146 }
   148 void SkBitmapDevice::unlockPixels() {
   149     if (fBitmap.lockPixelsAreWritable()) {
   150         fBitmap.unlockPixels();
   151     }
   152 }
   154 void SkBitmapDevice::clear(SkColor color) {
   155     fBitmap.eraseColor(color);
   156 }
   158 const SkBitmap& SkBitmapDevice::onAccessBitmap() {
   159     return fBitmap;
   160 }
   162 bool SkBitmapDevice::canHandleImageFilter(const SkImageFilter*) {
   163     return false;
   164 }
   166 bool SkBitmapDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
   167                                  const SkImageFilter::Context& ctx, SkBitmap* result,
   168                                  SkIPoint* offset) {
   169     return false;
   170 }
   172 bool SkBitmapDevice::allowImageFilter(const SkImageFilter*) {
   173     return true;
   174 }
   176 bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap,
   177                                   int x, int y,
   178                                   SkCanvas::Config8888 config8888) {
   179     SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
   180     SkASSERT(!bitmap.isNull());
   181     SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y,
   182                                                                           bitmap.width(),
   183                                                                           bitmap.height())));
   185     SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height());
   186     const SkBitmap& src = this->accessBitmap(false);
   188     SkBitmap subset;
   189     if (!src.extractSubset(&subset, srcRect)) {
   190         return false;
   191     }
   192     if (kPMColor_SkColorType != subset.colorType()) {
   193         // It'd be preferable to do this directly to bitmap.
   194         subset.copyTo(&subset, kPMColor_SkColorType);
   195     }
   196     SkAutoLockPixels alp(bitmap);
   197     uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
   198     SkCopyBitmapToConfig8888(bmpPixels, bitmap.rowBytes(), config8888, subset);
   199     return true;
   200 }
   202 #ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
   203 void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
   204                                  int x, int y,
   205                                  SkCanvas::Config8888 config8888) {
   206     if (bitmap.isNull() || bitmap.getTexture()) {
   207         return;
   208     }
   209     const SkBitmap* sprite = &bitmap;
   210     // check whether we have to handle a config8888 that doesn't match SkPMColor
   211     if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
   212         SkCanvas::kNative_Premul_Config8888 != config8888 &&
   213         kPMColorAlias != config8888) {
   215         // We're going to have to convert from a config8888 to the native config
   216         // First we clip to the device bounds.
   217         SkBitmap dstBmp = this->accessBitmap(true);
   218         SkIRect spriteRect = SkIRect::MakeXYWH(x, y,
   219                                                bitmap.width(), bitmap.height());
   220         SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height());
   221         if (!spriteRect.intersect(devRect)) {
   222             return;
   223         }
   225         // write directly to the device if it has pixels and is SkPMColor
   226         bool drawSprite;
   227         if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) {
   228             // we can write directly to the dst when doing the conversion
   229             dstBmp.extractSubset(&dstBmp, spriteRect);
   230             drawSprite = false;
   231         } else {
   232             // we convert to a temporary bitmap and draw that as a sprite
   233             if (!dstBmp.allocPixels(SkImageInfo::MakeN32Premul(spriteRect.width(),
   234                                                                spriteRect.height()))) {
   235                 return;
   236             }
   237             drawSprite = true;
   238         }
   240         // copy pixels to dstBmp and convert from config8888 to native config.
   241         SkAutoLockPixels alp(bitmap);
   242         uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x,
   243                                                spriteRect.fTop - y);
   244         SkCopyConfig8888ToBitmap(dstBmp,
   245                                  srcPixels,
   246                                  bitmap.rowBytes(),
   247                                  config8888);
   249         if (drawSprite) {
   250             // we've clipped the sprite when we made a copy
   251             x = spriteRect.fLeft;
   252             y = spriteRect.fTop;
   253             sprite = &dstBmp;
   254         } else {
   255             return;
   256         }
   257     }
   259     SkPaint paint;
   260     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
   261     SkRasterClip clip(SkIRect::MakeWH(fBitmap.width(), fBitmap.height()));
   262     SkDraw  draw;
   263     draw.fRC = &clip;
   264     draw.fClip = &clip.bwRgn();
   265     draw.fBitmap = &fBitmap; // canvas should have already called accessBitmap
   266     draw.fMatrix = &SkMatrix::I();
   267     this->drawSprite(draw, *sprite, x, y, paint);
   268 }
   269 #endif
   271 void* SkBitmapDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) {
   272     if (fBitmap.getPixels()) {
   273         *info = fBitmap.info();
   274         *rowBytes = fBitmap.rowBytes();
   275         return fBitmap.getPixels();
   276     }
   277     return NULL;
   278 }
   280 static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, size_t bytesPerRow,
   281                         int rowCount) {
   282     SkASSERT(bytesPerRow <= srcRB);
   283     SkASSERT(bytesPerRow <= dstRB);
   284     for (int i = 0; i < rowCount; ++i) {
   285         memcpy(dst, src, bytesPerRow);
   286         dst = (char*)dst + dstRB;
   287         src = (const char*)src + srcRB;
   288     }
   289 }
   291 static bool info2config8888(const SkImageInfo& info, SkCanvas::Config8888* config) {
   292     bool pre;
   293     switch (info.alphaType()) {
   294         case kPremul_SkAlphaType:
   295         case kOpaque_SkAlphaType:
   296             pre = true;
   297             break;
   298         case kUnpremul_SkAlphaType:
   299             pre = false;
   300             break;
   301         default:
   302             return false;
   303     }
   304     switch (info.colorType()) {
   305         case kRGBA_8888_SkColorType:
   306             *config = pre ? SkCanvas::kRGBA_Premul_Config8888 : SkCanvas::kRGBA_Unpremul_Config8888;
   307             return true;
   308         case kBGRA_8888_SkColorType:
   309             *config = pre ? SkCanvas::kBGRA_Premul_Config8888 : SkCanvas::kBGRA_Unpremul_Config8888;
   310             return true;
   311         default:
   312             return false;
   313     }
   314 }
   316 // TODO: make this guy real, and not rely on legacy config8888 utility
   317 #include "SkConfig8888.h"
   318 static bool write_pixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
   319                          const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRowBytes) {
   320     if (srcInfo.dimensions() != dstInfo.dimensions()) {
   321         return false;
   322     }
   323     if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) {
   324         SkCanvas::Config8888 srcConfig, dstConfig;
   325         if (!info2config8888(srcInfo, &srcConfig) || !info2config8888(dstInfo, &dstConfig)) {
   326             return false;
   327         }
   328         SkConvertConfig8888Pixels((uint32_t*)dstPixels, dstRowBytes, dstConfig,
   329                                   (const uint32_t*)srcPixels, srcRowBytes, srcConfig,
   330                                   srcInfo.width(), srcInfo.height());
   331         return true;
   332     }
   333     if (srcInfo.colorType() == dstInfo.colorType()) {
   334         switch (srcInfo.colorType()) {
   335             case kRGB_565_SkColorType:
   336             case kAlpha_8_SkColorType:
   337                 break;
   338             case kARGB_4444_SkColorType:
   339                 if (srcInfo.alphaType() != dstInfo.alphaType()) {
   340                     return false;
   341                 }
   342                 break;
   343             default:
   344                 return false;
   345         }
   346         rect_memcpy(dstPixels, dstRowBytes, srcPixels, srcRowBytes,
   347                     srcInfo.width() * srcInfo.bytesPerPixel(), srcInfo.height());
   348     }
   349     // TODO: add support for more conversions as needed
   350     return false;
   351 }
   353 bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels,
   354                                    size_t srcRowBytes, int x, int y) {
   355     // since we don't stop creating un-pixeled devices yet, check for no pixels here
   356     if (NULL == fBitmap.getPixels()) {
   357         return false;
   358     }
   360     SkImageInfo dstInfo = fBitmap.info();
   361     dstInfo.fWidth = srcInfo.width();
   362     dstInfo.fHeight = srcInfo.height();
   364     void* dstPixels = fBitmap.getAddr(x, y);
   365     size_t dstRowBytes = fBitmap.rowBytes();
   367     if (write_pixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) {
   368         fBitmap.notifyPixelsChanged();
   369         return true;
   370     }
   371     return false;
   372 }
   374 ///////////////////////////////////////////////////////////////////////////////
   376 void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
   377     draw.drawPaint(paint);
   378 }
   380 void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
   381                                 const SkPoint pts[], const SkPaint& paint) {
   382     CHECK_FOR_ANNOTATION(paint);
   383     draw.drawPoints(mode, count, pts, paint);
   384 }
   386 void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
   387     CHECK_FOR_ANNOTATION(paint);
   388     draw.drawRect(r, paint);
   389 }
   391 void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
   392     CHECK_FOR_ANNOTATION(paint);
   394     SkPath path;
   395     path.addOval(oval);
   396     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
   397     // required to override drawOval.
   398     this->drawPath(draw, path, paint, NULL, true);
   399 }
   401 void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
   402     CHECK_FOR_ANNOTATION(paint);
   404 #ifdef SK_IGNORE_BLURRED_RRECT_OPT
   405     SkPath  path;
   407     path.addRRect(rrect);
   408     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
   409     // required to override drawRRect.
   410     this->drawPath(draw, path, paint, NULL, true);
   411 #else
   412     draw.drawRRect(rrect, paint);
   413 #endif
   414 }
   416 void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
   417                               const SkPaint& paint, const SkMatrix* prePathMatrix,
   418                               bool pathIsMutable) {
   419     CHECK_FOR_ANNOTATION(paint);
   420     draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
   421 }
   423 void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
   424                                 const SkMatrix& matrix, const SkPaint& paint) {
   425     draw.drawBitmap(bitmap, matrix, paint);
   426 }
   428 void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
   429                                     const SkRect* src, const SkRect& dst,
   430                                     const SkPaint& paint,
   431                                     SkCanvas::DrawBitmapRectFlags flags) {
   432     SkMatrix    matrix;
   433     SkRect      bitmapBounds, tmpSrc, tmpDst;
   434     SkBitmap    tmpBitmap;
   436     bitmapBounds.isetWH(bitmap.width(), bitmap.height());
   438     // Compute matrix from the two rectangles
   439     if (src) {
   440         tmpSrc = *src;
   441     } else {
   442         tmpSrc = bitmapBounds;
   443     }
   444     matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
   446     const SkRect* dstPtr = &dst;
   447     const SkBitmap* bitmapPtr = &bitmap;
   449     // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
   450     // needed (if the src was clipped). No check needed if src==null.
   451     if (src) {
   452         if (!bitmapBounds.contains(*src)) {
   453             if (!tmpSrc.intersect(bitmapBounds)) {
   454                 return; // nothing to draw
   455             }
   456             // recompute dst, based on the smaller tmpSrc
   457             matrix.mapRect(&tmpDst, tmpSrc);
   458             dstPtr = &tmpDst;
   459         }
   461         // since we may need to clamp to the borders of the src rect within
   462         // the bitmap, we extract a subset.
   463         SkIRect srcIR;
   464         tmpSrc.roundOut(&srcIR);
   465         if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
   466             return;
   467         }
   468         bitmapPtr = &tmpBitmap;
   470         // Since we did an extract, we need to adjust the matrix accordingly
   471         SkScalar dx = 0, dy = 0;
   472         if (srcIR.fLeft > 0) {
   473             dx = SkIntToScalar(srcIR.fLeft);
   474         }
   475         if (srcIR.fTop > 0) {
   476             dy = SkIntToScalar(srcIR.fTop);
   477         }
   478         if (dx || dy) {
   479             matrix.preTranslate(dx, dy);
   480         }
   482         SkRect extractedBitmapBounds;
   483         extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
   484         if (extractedBitmapBounds == tmpSrc) {
   485             // no fractional part in src, we can just call drawBitmap
   486             goto USE_DRAWBITMAP;
   487         }
   488     } else {
   489         USE_DRAWBITMAP:
   490         // We can go faster by just calling drawBitmap, which will concat the
   491         // matrix with the CTM, and try to call drawSprite if it can. If not,
   492         // it will make a shader and call drawRect, as we do below.
   493         this->drawBitmap(draw, *bitmapPtr, matrix, paint);
   494         return;
   495     }
   497     // construct a shader, so we can call drawRect with the dst
   498     SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
   499                                                SkShader::kClamp_TileMode,
   500                                                SkShader::kClamp_TileMode);
   501     if (NULL == s) {
   502         return;
   503     }
   504     s->setLocalMatrix(matrix);
   506     SkPaint paintWithShader(paint);
   507     paintWithShader.setStyle(SkPaint::kFill_Style);
   508     paintWithShader.setShader(s)->unref();
   510     // Call ourself, in case the subclass wanted to share this setup code
   511     // but handle the drawRect code themselves.
   512     this->drawRect(draw, *dstPtr, paintWithShader);
   513 }
   515 void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
   516                                 int x, int y, const SkPaint& paint) {
   517     draw.drawSprite(bitmap, x, y, paint);
   518 }
   520 void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
   521                               SkScalar x, SkScalar y, const SkPaint& paint) {
   522     draw.drawText((const char*)text, len, x, y, paint);
   523 }
   525 void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
   526                                  const SkScalar xpos[], SkScalar y,
   527                                  int scalarsPerPos, const SkPaint& paint) {
   528     draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint);
   529 }
   531 void SkBitmapDevice::drawTextOnPath(const SkDraw& draw, const void* text,
   532                                     size_t len, const SkPath& path,
   533                                     const SkMatrix* matrix,
   534                                     const SkPaint& paint) {
   535     draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
   536 }
   538 void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
   539                                   int vertexCount,
   540                                   const SkPoint verts[], const SkPoint textures[],
   541                                   const SkColor colors[], SkXfermode* xmode,
   542                                   const uint16_t indices[], int indexCount,
   543                                   const SkPaint& paint) {
   544     draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
   545                       indices, indexCount, paint);
   546 }
   548 void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
   549                                 int x, int y, const SkPaint& paint) {
   550     const SkBitmap& src = device->accessBitmap(false);
   551     draw.drawSprite(src, x, y, paint);
   552 }
   554 SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info) {
   555     return SkSurface::NewRaster(info);
   556 }
   558 const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) {
   559     if (fBitmap.getPixels() && fBitmap.asImageInfo(info)) {
   560         if (rowBytes) {
   561             *rowBytes = fBitmap.rowBytes();
   562         }
   563         return fBitmap.getPixels();
   564     }
   565     return NULL;
   566 }
   568 ///////////////////////////////////////////////////////////////////////////////
   570 bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
   571     if (!paint.isLCDRenderText() || !paint.isAntiAlias()) {
   572         // we're cool with the paint as is
   573         return false;
   574     }
   576     if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
   577         paint.getRasterizer() ||
   578         paint.getPathEffect() ||
   579         paint.isFakeBoldText() ||
   580         paint.getStyle() != SkPaint::kFill_Style ||
   581         !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) {
   582         // turn off lcd
   583         flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
   584         flags->fHinting = paint.getHinting();
   585         return true;
   586     }
   587     // we're cool with the paint as is
   588     return false;
   589 }

mercurial