11db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger/* 21db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * Copyright (C) 2015 The Android Open Source Project 31db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * 41db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License"); 51db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * you may not use this file except in compliance with the License. 61db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * You may obtain a copy of the License at 71db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * 81db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * http://www.apache.org/licenses/LICENSE-2.0 91db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * 101db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * Unless required by applicable law or agreed to in writing, software 111db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS, 121db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * See the License for the specific language governing permissions and 141db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * limitations under the License. 151db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger */ 161db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 171db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger#include "SkiaCanvasProxy.h" 181db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 1952eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <memory> 2052eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn 2152eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h> 22aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv 23770e0b500793bce45442b5f403913d14017df4e8Stan Iliev#include <SkLatticeIter.h> 24a11ee3c4131d889d57b7d2cf30faa7c105b23b10Ben Wagner#include <SkPaint.h> 251bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include <SkPatchUtils.h> 26a11ee3c4131d889d57b7d2cf30faa7c105b23b10Ben Wagner#include <SkPath.h> 2717c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson#include <SkPixelRef.h> 28a11ee3c4131d889d57b7d2cf30faa7c105b23b10Ben Wagner#include <SkRRect.h> 29afc221499d943386256feb9db46c119ff834bf79Yuqian Li#include <SkRSXform.h> 301bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include <SkRect.h> 3179fc3b1f1675364dbb739ffa511a68ed5a80f357Matt Sarett#include <SkSurface.h> 3209bd6c201dd7b5dfaae45ebf413fe0a779eb0268Derek Sollenberger#include <SkTextBlobRunIterator.h> 33871cd2dd6074544bd41a84ff38255d81a392546aMike Reed#include <SkVertices.h> 341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#include "hwui/Bitmap.h" 351db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 361db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergernamespace android { 371db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergernamespace uirenderer { 381db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 39b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom HudsonSkiaCanvasProxy::SkiaCanvasProxy(Canvas* canvas, bool filterHwuiCalls) 401db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger : INHERITED(canvas->width(), canvas->height()) 41b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson , mCanvas(canvas) 42b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson , mFilterHwuiCalls(filterHwuiCalls) {} 431db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 441db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPaint(const SkPaint& paint) { 451db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawPaint(paint); 461db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 471db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 481db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPoints(PointMode pointMode, size_t count, const SkPoint pts[], 491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 50b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson if (!pts || count == 0) { 51b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson return; 52b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson } 53b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson 541db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // convert the SkPoints into floats 551bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); 561db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger const size_t floatCount = count << 1; 571db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger const float* floatArray = &pts[0].fX; 581db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 591db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger switch (pointMode) { 601db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger case kPoints_PointMode: { 611db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawPoints(floatArray, floatCount, paint); 621db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger break; 631db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 641db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger case kLines_PointMode: { 651db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawLines(floatArray, floatCount, paint); 661db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger break; 671db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 681db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger case kPolygon_PointMode: { 691db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPaint strokedPaint(paint); 701db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger strokedPaint.setStyle(SkPaint::kStroke_Style); 711db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 721db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPath path; 731db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger for (size_t i = 0; i < count - 1; i++) { 741db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.moveTo(pts[i]); 751bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck path.lineTo(pts[i + 1]); 761db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger this->drawPath(path, strokedPaint); 771db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.rewind(); 781db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 791db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger break; 801db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 811db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger default: 821db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger LOG_ALWAYS_FATAL("Unknown point type"); 831db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 841db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 851db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 861db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawOval(const SkRect& rect, const SkPaint& paint) { 871db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawOval(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint); 881db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 891db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 901db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawRect(const SkRect& rect, const SkPaint& paint) { 911db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, paint); 921db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 931db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 941db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawRRect(const SkRRect& roundRect, const SkPaint& paint) { 951db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (!roundRect.isComplex()) { 961db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger const SkRect& rect = roundRect.rect(); 971db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkVector radii = roundRect.getSimpleRadii(); 981bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawRoundRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, radii.fX, radii.fY, 991bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck paint); 1001db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } else { 1011db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPath path; 1021db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.addRRect(roundRect); 1031db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawPath(path, paint); 1041db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 1051db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1061db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 1079969111d9c8017cdd439edbb2c54ef9678b24a59Yuqian Livoid SkiaCanvasProxy::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, 1089969111d9c8017cdd439edbb2c54ef9678b24a59Yuqian Li bool useCenter, const SkPaint& paint) { 1091bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawArc(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, startAngle, sweepAngle, 1101bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck useCenter, paint); 1119969111d9c8017cdd439edbb2c54ef9678b24a59Yuqian Li} 1129969111d9c8017cdd439edbb2c54ef9678b24a59Yuqian Li 1131db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPath(const SkPath& path, const SkPaint& paint) { 1141db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->drawPath(path, paint); 1151db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1161db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 1171db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 1181bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint* paint) { 119fc9999505a36c66892d7ccce85187936105f4f36sergeyv sk_sp<Bitmap> hwuiBitmap = Bitmap::createFrom(bitmap.info(), *bitmap.pixelRef()); 12017c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson // HWUI doesn't support extractSubset(), so convert any subsetted bitmap into 12117c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson // a drawBitmapRect(); pass through an un-subsetted bitmap. 122fc9999505a36c66892d7ccce85187936105f4f36sergeyv if (hwuiBitmap && bitmap.dimensions() != hwuiBitmap->info().dimensions()) { 12317c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson SkIPoint origin = bitmap.pixelRefOrigin(); 1241bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawBitmap( 1251bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck *hwuiBitmap, origin.fX, origin.fY, origin.fX + bitmap.dimensions().width(), 1261bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck origin.fY + bitmap.dimensions().height(), left, top, 1271bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck left + bitmap.dimensions().width(), top + bitmap.dimensions().height(), paint); 12817c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson } else { 129aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv mCanvas->drawBitmap(*hwuiBitmap, left, top, paint); 13017c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson } 1311db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1321db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 133fc9999505a36c66892d7ccce85187936105f4f36sergeyvvoid SkiaCanvasProxy::onDrawBitmapRect(const SkBitmap& skBitmap, const SkRect* srcPtr, 1341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkRect& dst, const SkPaint* paint, SrcRectConstraint) { 135fc9999505a36c66892d7ccce85187936105f4f36sergeyv SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(skBitmap.width(), skBitmap.height()); 13617c5adfa63872fbb6a903a5941e3c6455995b92dTom Hudson // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src? 1371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck Bitmap* bitmap = reinterpret_cast<Bitmap*>(skBitmap.pixelRef()); 1381bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, dst.fTop, 1391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck dst.fRight, dst.fBottom, paint); 1401db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1411db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 1421db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 1431bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkRect& dst, const SkPaint*) { 1441bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck // TODO make nine-patch drawing a method on Canvas.h 1451db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkDEBUGFAIL("SkiaCanvasProxy::onDrawBitmapNine is not yet supported"); 1461db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1471db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 148770e0b500793bce45442b5f403913d14017df4e8Stan Ilievvoid SkiaCanvasProxy::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, 1491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint* paint) { 150770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkBitmap skiaBitmap; 1510a3ff952a6ba9ce15f8165632e606587fabd3feaStan Iliev SkPixmap pixmap; 1520a3ff952a6ba9ce15f8165632e606587fabd3feaStan Iliev if (image->peekPixels(&pixmap) && skiaBitmap.installPixels(pixmap)) { 153770e0b500793bce45442b5f403913d14017df4e8Stan Iliev onDrawBitmap(skiaBitmap, left, top, paint); 154770e0b500793bce45442b5f403913d14017df4e8Stan Iliev } 155770e0b500793bce45442b5f403913d14017df4e8Stan Iliev} 156770e0b500793bce45442b5f403913d14017df4e8Stan Iliev 157770e0b500793bce45442b5f403913d14017df4e8Stan Ilievvoid SkiaCanvasProxy::onDrawImageRect(const SkImage* image, const SkRect* srcPtr, const SkRect& dst, 1581bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint* paint, SrcRectConstraint constraint) { 159770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkBitmap skiaBitmap; 1600a3ff952a6ba9ce15f8165632e606587fabd3feaStan Iliev SkPixmap pixmap; 1610a3ff952a6ba9ce15f8165632e606587fabd3feaStan Iliev if (image->peekPixels(&pixmap) && skiaBitmap.installPixels(pixmap)) { 162770e0b500793bce45442b5f403913d14017df4e8Stan Iliev sk_sp<Bitmap> bitmap = Bitmap::createFrom(skiaBitmap.info(), *skiaBitmap.pixelRef()); 163770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkRect src = (srcPtr) ? *srcPtr : SkRect::MakeWH(image->width(), image->height()); 1641bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawBitmap(*bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, 1651bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck dst.fTop, dst.fRight, dst.fBottom, paint); 166770e0b500793bce45442b5f403913d14017df4e8Stan Iliev } 167770e0b500793bce45442b5f403913d14017df4e8Stan Iliev} 168770e0b500793bce45442b5f403913d14017df4e8Stan Iliev 169770e0b500793bce45442b5f403913d14017df4e8Stan Ilievvoid SkiaCanvasProxy::onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, 1701bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint*) { 171770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkDEBUGFAIL("SkiaCanvasProxy::onDrawImageNine is not yet supported"); 172770e0b500793bce45442b5f403913d14017df4e8Stan Iliev} 173770e0b500793bce45442b5f403913d14017df4e8Stan Iliev 174770e0b500793bce45442b5f403913d14017df4e8Stan Ilievvoid SkiaCanvasProxy::onDrawImageLattice(const SkImage* image, const Lattice& lattice, 1751bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkRect& dst, const SkPaint* paint) { 176770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkLatticeIter iter(lattice, dst); 177770e0b500793bce45442b5f403913d14017df4e8Stan Iliev SkRect srcR, dstR; 178770e0b500793bce45442b5f403913d14017df4e8Stan Iliev while (iter.next(&srcR, &dstR)) { 1796c2a9e2bc1759ae7eefc973941e8a6fc6b3e912cDerek Sollenberger onDrawImageRect(image, &srcR, dstR, paint, SkCanvas::kFast_SrcRectConstraint); 180770e0b500793bce45442b5f403913d14017df4e8Stan Iliev } 181770e0b500793bce45442b5f403913d14017df4e8Stan Iliev} 182770e0b500793bce45442b5f403913d14017df4e8Stan Iliev 183871cd2dd6074544bd41a84ff38255d81a392546aMike Reedvoid SkiaCanvasProxy::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 1841bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 185b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson if (mFilterHwuiCalls) { 186b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson return; 187b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson } 188826deefda55ead0036cdb0924bc14f17d2a85420Mike Reed mCanvas->drawVertices(vertices, bmode, paint); 1891db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1901db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 19179fc3b1f1675364dbb739ffa511a68ed5a80f357Matt Sarettsk_sp<SkSurface> SkiaCanvasProxy::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) { 1921db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkDEBUGFAIL("SkiaCanvasProxy::onNewSurface is not supported"); 1931db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger return NULL; 1941db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 1951db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 1961db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::willSave() { 197eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita mCanvas->save(android::SaveFlags::MatrixClip); 198eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita} 199eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita 200eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malitastatic inline SaveFlags::Flags saveFlags(SkCanvas::SaveLayerFlags layerFlags) { 201eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita SaveFlags::Flags saveFlags = 0; 202eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita 203eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita if (!(layerFlags & SkCanvas::kDontClipToLayer_Legacy_SaveLayerFlag)) { 204eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita saveFlags |= SaveFlags::ClipToLayer; 205eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita } 206eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita 207eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita return saveFlags; 2081db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2091db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2101bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John ReckSkCanvas::SaveLayerStrategy SkiaCanvasProxy::getSaveLayerStrategy( 2111bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SaveLayerRec& saveLayerRec) { 2121db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkRect rect; 2135518e7cbd4e8d7a7cb3d60a4251eccc3b7fb82dbLeon Scroggins III if (saveLayerRec.fBounds) { 2145518e7cbd4e8d7a7cb3d60a4251eccc3b7fb82dbLeon Scroggins III rect = *saveLayerRec.fBounds; 2155518e7cbd4e8d7a7cb3d60a4251eccc3b7fb82dbLeon Scroggins III } else if (!mCanvas->getClipBounds(&rect)) { 2161db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger rect = SkRect::MakeEmpty(); 2171db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 2185518e7cbd4e8d7a7cb3d60a4251eccc3b7fb82dbLeon Scroggins III mCanvas->saveLayer(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, saveLayerRec.fPaint, 219eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita saveFlags(saveLayerRec.fSaveLayerFlags)); 2201db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger return SkCanvas::kNoLayer_SaveLayerStrategy; 2211db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2221db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2231db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::willRestore() { 2241db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->restore(); 2251db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2261db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2271db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::didConcat(const SkMatrix& matrix) { 2281db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->concat(matrix); 2291db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2301db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2311db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) { 2326daa13c5fa7577fa1d8371deca446f6ca911f38fChris Craik mCanvas->setMatrix(matrix); 2331db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2341db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2351db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2361bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 2371db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPath path; 2381db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.addRRect(outer); 2391db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.addRRect(inner); 2401db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.setFillType(SkPath::kEvenOdd_FillType); 2411db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger this->drawPath(path, paint); 2421db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 2431db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2441db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger/** 2451db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * Utility class that converts the incoming text & paint from the given encoding 2461db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger * into glyphIDs. 2471db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger */ 2481db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergerclass GlyphIDConverter { 2491db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergerpublic: 2501db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger GlyphIDConverter(const void* text, size_t byteLength, const SkPaint& origPaint) { 2511db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger paint = origPaint; 2521db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding) { 2531db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger glyphIDs = (uint16_t*)text; 2541db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger count = byteLength >> 1; 2551db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } else { 2561bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck // ensure space for one glyph per ID given UTF8 encoding. 2576bbf68d05a9deb335fc693b4a64651aea1b4e9e0Ben Wagner storage.reset(new uint16_t[byteLength]); 2581db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger glyphIDs = storage.get(); 2591db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger count = paint.textToGlyphs(text, byteLength, storage.get()); 2601db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 2611db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 2621db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 2631db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2641db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPaint paint; 2651db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger uint16_t* glyphIDs; 2661db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger int count; 2671bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck 2681db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergerprivate: 2696bbf68d05a9deb335fc693b4a64651aea1b4e9e0Ben Wagner std::unique_ptr<uint16_t[]> storage; 2701db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger}; 2711db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2721db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2731bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& origPaint) { 2741db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // convert to glyphIDs if necessary 2751db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger GlyphIDConverter glyphs(text, byteLength, origPaint); 2761db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2771db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // compute the glyph positions 2786bbf68d05a9deb335fc693b4a64651aea1b4e9e0Ben Wagner std::unique_ptr<SkScalar[]> glyphWidths(new SkScalar[glyphs.count]); 2791db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger glyphs.paint.getTextWidths(glyphs.glyphIDs, glyphs.count << 1, glyphWidths.get()); 2801db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2811db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // compute conservative bounds 2821db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // NOTE: We could call the faster paint.getFontBounds for a less accurate, 2831db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // but even more conservative bounds if this is too slow. 2841db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkRect bounds; 2851db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds); 2861db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 2871db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // adjust for non-left alignment 2881db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (glyphs.paint.getTextAlign() != SkPaint::kLeft_Align) { 2891db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkScalar stop = 0; 2901db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger for (int i = 0; i < glyphs.count; i++) { 2911db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger stop += glyphWidths[i]; 2921db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 2931db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (glyphs.paint.getTextAlign() == SkPaint::kCenter_Align) { 2941db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger stop = SkScalarHalf(stop); 2951db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 2961db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (glyphs.paint.isVerticalText()) { 2971db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger y -= stop; 2981db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } else { 2991db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger x -= stop; 3001db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 3011db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 3021db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3031db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // setup the first glyph position and adjust bounds if needed 304806a6f07a37c16b37631d8707dd1f2b41276fafcTom Hudson int xBaseline = 0; 305806a6f07a37c16b37631d8707dd1f2b41276fafcTom Hudson int yBaseline = 0; 3061db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (mCanvas->drawTextAbsolutePos()) { 3071bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bounds.offset(x, y); 308806a6f07a37c16b37631d8707dd1f2b41276fafcTom Hudson xBaseline = x; 309806a6f07a37c16b37631d8707dd1f2b41276fafcTom Hudson yBaseline = y; 3101db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 3111db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3121bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); 3131bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck auto glyphFunc = [&](uint16_t* text, float* positions) { 3141bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck memcpy(text, glyphs.glyphIDs, glyphs.count * sizeof(uint16_t)); 3150b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev size_t posIndex = 0; 3160b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev // setup the first glyph position 3170b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = xBaseline; 3180b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = yBaseline; 3190b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev // setup the remaining glyph positions 3200b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev if (glyphs.paint.isVerticalText()) { 3210b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev float yPosition = yBaseline; 3220b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev for (int i = 1; i < glyphs.count; i++) { 3230b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = xBaseline; 3241bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck yPosition += glyphWidths[i - 1]; 3250b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = yPosition; 3260b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } 3270b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } else { 3280b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev float xPosition = xBaseline; 3290b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev for (int i = 1; i < glyphs.count; i++) { 3301bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck xPosition += glyphWidths[i - 1]; 3310b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = xPosition; 3320b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = yBaseline; 3330b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } 3340b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } 3350b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev }; 3360b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, 3371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bounds.fRight, bounds.fBottom, 0); 3381db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 3391db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3401db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 3411bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& origPaint) { 3421db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // convert to glyphIDs if necessary 3431db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger GlyphIDConverter glyphs(text, byteLength, origPaint); 3441db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3451db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger // convert to relative positions if necessary 3461db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger int x, y; 3471db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger if (mCanvas->drawTextAbsolutePos()) { 3481db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger x = 0; 3491db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger y = 0; 3501db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } else { 3511db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger x = pos[0].fX; 3521db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger y = pos[0].fY; 3531db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 3541db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 35535934cccabf72879603ef37222da2195445f027eDerek Sollenberger // Compute conservative bounds. If the content has already been processed 35635934cccabf72879603ef37222da2195445f027eDerek Sollenberger // by Minikin then it had already computed these bounds. Unfortunately, 35735934cccabf72879603ef37222da2195445f027eDerek Sollenberger // there is no way to capture those bounds as part of the Skia drawPosText 35835934cccabf72879603ef37222da2195445f027eDerek Sollenberger // API so we need to do that computation again here. 359d84d2ee3359af8478afd3f891d5d316af1a562edStan Iliev SkRect bounds = SkRect::MakeEmpty(); 36035934cccabf72879603ef37222da2195445f027eDerek Sollenberger for (int i = 0; i < glyphs.count; i++) { 361d84d2ee3359af8478afd3f891d5d316af1a562edStan Iliev SkRect glyphBounds = SkRect::MakeEmpty(); 36235934cccabf72879603ef37222da2195445f027eDerek Sollenberger glyphs.paint.measureText(&glyphs.glyphIDs[i], sizeof(uint16_t), &glyphBounds); 36335934cccabf72879603ef37222da2195445f027eDerek Sollenberger glyphBounds.offset(pos[i].fX, pos[i].fY); 36435934cccabf72879603ef37222da2195445f027eDerek Sollenberger bounds.join(glyphBounds); 36535934cccabf72879603ef37222da2195445f027eDerek Sollenberger } 3661db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3671bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck static_assert(sizeof(SkPoint) == sizeof(float) * 2, "SkPoint is no longer two floats"); 3681bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck auto glyphFunc = [&](uint16_t* text, float* positions) { 3691bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck memcpy(text, glyphs.glyphIDs, glyphs.count * sizeof(uint16_t)); 3700b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev if (mCanvas->drawTextAbsolutePos()) { 3711bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck memcpy(positions, pos, 2 * glyphs.count * sizeof(float)); 3720b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } else { 3730b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev for (int i = 0, posIndex = 0; i < glyphs.count; i++) { 3740b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = pos[i].fX - x; 3750b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev positions[posIndex++] = pos[i].fY - y; 3760b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } 3770b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev } 3780b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev }; 3790b58d9928309e2c64c7cafad287e55a8151ab19aStan Iliev mCanvas->drawGlyphs(glyphFunc, glyphs.count, glyphs.paint, x, y, bounds.fLeft, bounds.fTop, 3801bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bounds.fRight, bounds.fBottom, 0); 3811db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 3821db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3831db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 3841bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck SkScalar constY, const SkPaint& paint) { 3851db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger const size_t pointCount = byteLength >> 1; 3866bbf68d05a9deb335fc693b4a64651aea1b4e9e0Ben Wagner std::unique_ptr<SkPoint[]> pts(new SkPoint[pointCount]); 3871db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger for (size_t i = 0; i < pointCount; i++) { 3881db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger pts[i].set(xpos[i], constY); 3891db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger } 3906bbf68d05a9deb335fc693b4a64651aea1b4e9e0Ben Wagner this->onDrawPosText(text, byteLength, pts.get(), paint); 3911db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 3921db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 3931db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 3941bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkMatrix* matrix, const SkPaint& origPaint) { 395afc221499d943386256feb9db46c119ff834bf79Yuqian Li SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextOnPath is not supported"); 3961db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 3971db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 398afc221499d943386256feb9db46c119ff834bf79Yuqian Livoid SkiaCanvasProxy::onDrawTextRSXform(const void* text, size_t byteLength, 3991bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkRSXform xform[], const SkRect* cullRect, 4001bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 4011bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck GlyphIDConverter glyphs(text, byteLength, paint); // Just get count 402afc221499d943386256feb9db46c119ff834bf79Yuqian Li SkMatrix localM, currM, origM; 403afc221499d943386256feb9db46c119ff834bf79Yuqian Li mCanvas->getMatrix(&currM); 404afc221499d943386256feb9db46c119ff834bf79Yuqian Li origM = currM; 405afc221499d943386256feb9db46c119ff834bf79Yuqian Li for (int i = 0; i < glyphs.count; i++) { 406afc221499d943386256feb9db46c119ff834bf79Yuqian Li localM.setRSXform(*xform++); 407afc221499d943386256feb9db46c119ff834bf79Yuqian Li currM.setConcat(origM, localM); 408afc221499d943386256feb9db46c119ff834bf79Yuqian Li mCanvas->setMatrix(currM); 4091bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck this->onDrawText((char*)text + (byteLength / glyphs.count * i), byteLength / glyphs.count, 4101bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck 0, 0, paint); 411afc221499d943386256feb9db46c119ff834bf79Yuqian Li } 412afc221499d943386256feb9db46c119ff834bf79Yuqian Li mCanvas->setMatrix(origM); 413afc221499d943386256feb9db46c119ff834bf79Yuqian Li} 414afc221499d943386256feb9db46c119ff834bf79Yuqian Li 4151db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 4161bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 41709bd6c201dd7b5dfaae45ebf413fe0a779eb0268Derek Sollenberger SkPaint runPaint = paint; 41809bd6c201dd7b5dfaae45ebf413fe0a779eb0268Derek Sollenberger 4191bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck SkTextBlobRunIterator it(blob); 4201bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck for (; !it.done(); it.next()) { 4211bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck size_t textLen = it.glyphCount() * sizeof(uint16_t); 4221bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPoint& offset = it.offset(); 4231bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck // applyFontToPaint() always overwrites the exact same attributes, 4241bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck // so it is safe to not re-seed the paint for this reason. 4251bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck it.applyFontToPaint(&runPaint); 4261bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck 4271bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck switch (it.positioning()) { 4281bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck case SkTextBlob::kDefault_Positioning: 4291bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint); 4301bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck break; 4311bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck case SkTextBlob::kHorizontal_Positioning: { 4321bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); 4331bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck for (size_t i = 0; i < it.glyphCount(); i++) { 4341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck pts[i].set(x + offset.x() + it.pos()[i], y + offset.y()); 4351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4361bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); 4371bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck break; 4381bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck case SkTextBlob::kFull_Positioning: { 4401bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]); 4411bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck for (size_t i = 0; i < it.glyphCount(); i++) { 4421bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const size_t xIndex = i * 2; 4431bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const size_t yIndex = xIndex + 1; 4441bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck pts[i].set(x + offset.x() + it.pos()[xIndex], 4451bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck y + offset.y() + it.pos()[yIndex]); 4461bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4471bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint); 4481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck break; 4491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4501bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck default: 4511bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck SK_ABORT("unhandled positioning mode"); 4521bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4531bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 4541db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 4551db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4561db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenbergervoid SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 4571bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPoint texCoords[4], SkBlendMode bmode, 4581bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const SkPaint& paint) { 459b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson if (mFilterHwuiCalls) { 460b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson return; 461b1476ae7d515d6c406b4367cfb4ada8ce2d116e1Tom Hudson } 4621db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkMatrix matrix; 4631db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->getMatrix(&matrix); 4641db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix); 4651db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4661bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck mCanvas->drawVertices( 4671bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height()).get(), 4681bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bmode, paint); 4691db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 4701db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4716e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedvoid SkiaCanvasProxy::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle) { 4721db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->clipRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, op); 4731db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 4741db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4756e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedvoid SkiaCanvasProxy::onClipRRect(const SkRRect& roundRect, SkClipOp op, ClipEdgeStyle) { 4761db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger SkPath path; 4771db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger path.addRRect(roundRect); 4781db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->clipPath(&path, op); 4791db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 4801db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4816e49c9f007c879f05b035c40c0ba543c00f9d0d0Mike Reedvoid SkiaCanvasProxy::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle) { 4821db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger mCanvas->clipPath(&path, op); 4831db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger} 4841db141f93c4fe79a4669440c3d14f63bc87b2e34Derek Sollenberger 4851bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace uirenderer 4861bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace android 487