DrawCommand.cpp 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129
  1. /*
  2. * Copyright 2012 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. */
  7. #include "tools/debugger/DrawCommand.h"
  8. #include <algorithm>
  9. #include "include/core/SkColorFilter.h"
  10. #include "include/core/SkDrawable.h"
  11. #include "include/core/SkImageFilter.h"
  12. #include "include/core/SkPathEffect.h"
  13. #include "include/core/SkPicture.h"
  14. #include "include/core/SkTypeface.h"
  15. #include "include/effects/SkDashPathEffect.h"
  16. #include "include/encode/SkPngEncoder.h"
  17. #include "include/private/SkShadowFlags.h"
  18. #include "include/private/SkTHash.h"
  19. #include "src/core/SkAutoMalloc.h"
  20. #include "src/core/SkCanvasPriv.h"
  21. #include "src/core/SkClipOpPriv.h"
  22. #include "src/core/SkLatticeIter.h"
  23. #include "src/core/SkMaskFilterBase.h"
  24. #include "src/core/SkPaintDefaults.h"
  25. #include "src/core/SkReadBuffer.h"
  26. #include "src/core/SkRectPriv.h"
  27. #include "src/core/SkTextBlobPriv.h"
  28. #include "src/core/SkWriteBuffer.h"
  29. #include "tools/debugger/JsonWriteBuffer.h"
  30. #define DEBUGCANVAS_ATTRIBUTE_COMMAND "command"
  31. #define DEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
  32. #define DEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
  33. #define DEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
  34. #define DEBUGCANVAS_ATTRIBUTE_COORDS "coords"
  35. #define DEBUGCANVAS_ATTRIBUTE_EDGING "edging"
  36. #define DEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
  37. #define DEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
  38. #define DEBUGCANVAS_ATTRIBUTE_PAINT "paint"
  39. #define DEBUGCANVAS_ATTRIBUTE_OUTER "outer"
  40. #define DEBUGCANVAS_ATTRIBUTE_INNER "inner"
  41. #define DEBUGCANVAS_ATTRIBUTE_MODE "mode"
  42. #define DEBUGCANVAS_ATTRIBUTE_POINTS "points"
  43. #define DEBUGCANVAS_ATTRIBUTE_PATH "path"
  44. #define DEBUGCANVAS_ATTRIBUTE_TEXT "text"
  45. #define DEBUGCANVAS_ATTRIBUTE_COLOR "color"
  46. #define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
  47. #define DEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
  48. #define DEBUGCANVAS_ATTRIBUTE_STYLE "style"
  49. #define DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
  50. #define DEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
  51. #define DEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
  52. #define DEBUGCANVAS_ATTRIBUTE_CAP "cap"
  53. #define DEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
  54. #define DEBUGCANVAS_ATTRIBUTE_DITHER "dither"
  55. #define DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
  56. #define DEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
  57. #define DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
  58. #define DEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
  59. #define DEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
  60. #define DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
  61. #define DEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
  62. #define DEBUGCANVAS_ATTRIBUTE_REGION "region"
  63. #define DEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
  64. #define DEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
  65. #define DEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
  66. #define DEBUGCANVAS_ATTRIBUTE_BLUR "blur"
  67. #define DEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
  68. #define DEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
  69. #define DEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
  70. #define DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
  71. #define DEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
  72. #define DEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
  73. #define DEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
  74. #define DEBUGCANVAS_ATTRIBUTE_PHASE "phase"
  75. #define DEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
  76. #define DEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
  77. #define DEBUGCANVAS_ATTRIBUTE_NAME "name"
  78. #define DEBUGCANVAS_ATTRIBUTE_DATA "data"
  79. #define DEBUGCANVAS_ATTRIBUTE_VALUES "values"
  80. #define DEBUGCANVAS_ATTRIBUTE_SHADER "shader"
  81. #define DEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
  82. #define DEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
  83. #define DEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
  84. #define DEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
  85. #define DEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
  86. #define DEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
  87. #define DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
  88. #define DEBUGCANVAS_ATTRIBUTE_IMAGE "image"
  89. #define DEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
  90. #define DEBUGCANVAS_ATTRIBUTE_SRC "src"
  91. #define DEBUGCANVAS_ATTRIBUTE_DST "dst"
  92. #define DEBUGCANVAS_ATTRIBUTE_CENTER "center"
  93. #define DEBUGCANVAS_ATTRIBUTE_STRICT "strict"
  94. #define DEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
  95. #define DEBUGCANVAS_ATTRIBUTE_X "x"
  96. #define DEBUGCANVAS_ATTRIBUTE_Y "y"
  97. #define DEBUGCANVAS_ATTRIBUTE_RUNS "runs"
  98. #define DEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
  99. #define DEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
  100. #define DEBUGCANVAS_ATTRIBUTE_FONT "font"
  101. #define DEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
  102. #define DEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
  103. #define DEBUGCANVAS_ATTRIBUTE_COLORS "colors"
  104. #define DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
  105. #define DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
  106. #define DEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
  107. #define DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
  108. #define DEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
  109. #define DEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
  110. #define DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
  111. #define DEBUGCANVAS_ATTRIBUTE_WIDTH "width"
  112. #define DEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
  113. #define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
  114. #define DEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
  115. #define DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
  116. #define DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
  117. #define DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
  118. #define DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
  119. #define DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
  120. #define DEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
  121. #define DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
  122. #define DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
  123. #define DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
  124. #define DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
  125. #define DEBUGCANVAS_VERB_MOVE "move"
  126. #define DEBUGCANVAS_VERB_LINE "line"
  127. #define DEBUGCANVAS_VERB_QUAD "quad"
  128. #define DEBUGCANVAS_VERB_CUBIC "cubic"
  129. #define DEBUGCANVAS_VERB_CONIC "conic"
  130. #define DEBUGCANVAS_VERB_CLOSE "close"
  131. #define DEBUGCANVAS_STYLE_FILL "fill"
  132. #define DEBUGCANVAS_STYLE_STROKE "stroke"
  133. #define DEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
  134. #define DEBUGCANVAS_POINTMODE_POINTS "points"
  135. #define DEBUGCANVAS_POINTMODE_LINES "lines"
  136. #define DEBUGCANVAS_POINTMODE_POLYGON "polygon"
  137. #define DEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
  138. #define DEBUGCANVAS_REGIONOP_INTERSECT "intersect"
  139. #define DEBUGCANVAS_REGIONOP_UNION "union"
  140. #define DEBUGCANVAS_REGIONOP_XOR "xor"
  141. #define DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
  142. #define DEBUGCANVAS_REGIONOP_REPLACE "replace"
  143. #define DEBUGCANVAS_BLURSTYLE_NORMAL "normal"
  144. #define DEBUGCANVAS_BLURSTYLE_SOLID "solid"
  145. #define DEBUGCANVAS_BLURSTYLE_OUTER "outer"
  146. #define DEBUGCANVAS_BLURSTYLE_INNER "inner"
  147. #define DEBUGCANVAS_BLURQUALITY_LOW "low"
  148. #define DEBUGCANVAS_BLURQUALITY_HIGH "high"
  149. #define DEBUGCANVAS_FILLTYPE_WINDING "winding"
  150. #define DEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
  151. #define DEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
  152. #define DEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
  153. #define DEBUGCANVAS_CAP_BUTT "butt"
  154. #define DEBUGCANVAS_CAP_ROUND "round"
  155. #define DEBUGCANVAS_CAP_SQUARE "square"
  156. #define DEBUGCANVAS_MITER_JOIN "miter"
  157. #define DEBUGCANVAS_ROUND_JOIN "round"
  158. #define DEBUGCANVAS_BEVEL_JOIN "bevel"
  159. #define DEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
  160. #define DEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
  161. #define DEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
  162. #define DEBUGCANVAS_COLORTYPE_565 "565"
  163. #define DEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
  164. #define DEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
  165. #define DEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
  166. #define DEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
  167. #define DEBUGCANVAS_ALPHATYPE_PREMUL "premul"
  168. #define DEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
  169. #define DEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
  170. #define DEBUGCANVAS_FILTERQUALITY_NONE "none"
  171. #define DEBUGCANVAS_FILTERQUALITY_LOW "low"
  172. #define DEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
  173. #define DEBUGCANVAS_FILTERQUALITY_HIGH "high"
  174. #define DEBUGCANVAS_HINTING_NONE "none"
  175. #define DEBUGCANVAS_HINTING_SLIGHT "slight"
  176. #define DEBUGCANVAS_HINTING_NORMAL "normal"
  177. #define DEBUGCANVAS_HINTING_FULL "full"
  178. #define DEBUGCANVAS_EDGING_ALIAS "alias"
  179. #define DEBUGCANVAS_EDGING_ANTIALIAS "antialias"
  180. #define DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS "subpixelantialias"
  181. #define DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
  182. #define DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"
  183. static SkString* str_append(SkString* str, const SkRect& r) {
  184. str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
  185. return str;
  186. }
  187. DrawCommand::DrawCommand(OpType type) : fOpType(type), fVisible(true) {}
  188. const char* DrawCommand::GetCommandString(OpType type) {
  189. switch (type) {
  190. case kBeginDrawPicture_OpType: return "BeginDrawPicture";
  191. case kClear_OpType: return "DrawClear";
  192. case kClipPath_OpType: return "ClipPath";
  193. case kClipRegion_OpType: return "ClipRegion";
  194. case kClipRect_OpType: return "ClipRect";
  195. case kClipRRect_OpType: return "ClipRRect";
  196. case kConcat_OpType: return "Concat";
  197. case kDrawAnnotation_OpType: return "DrawAnnotation";
  198. case kDrawBitmap_OpType: return "DrawBitmap";
  199. case kDrawBitmapLattice_OpType: return "DrawBitmapLattice";
  200. case kDrawBitmapNine_OpType: return "DrawBitmapNine";
  201. case kDrawBitmapRect_OpType: return "DrawBitmapRect";
  202. case kDrawDRRect_OpType: return "DrawDRRect";
  203. case kDrawImage_OpType: return "DrawImage";
  204. case kDrawImageLattice_OpType: return "DrawImageLattice";
  205. case kDrawImageNine_OpType: return "DrawImageNine";
  206. case kDrawImageRect_OpType: return "DrawImageRect";
  207. case kDrawOval_OpType: return "DrawOval";
  208. case kDrawPaint_OpType: return "DrawPaint";
  209. case kDrawPatch_OpType: return "DrawPatch";
  210. case kDrawPath_OpType: return "DrawPath";
  211. case kDrawArc_OpType: return "DrawArc";
  212. case kDrawPoints_OpType: return "DrawPoints";
  213. case kDrawRect_OpType: return "DrawRect";
  214. case kDrawRRect_OpType: return "DrawRRect";
  215. case kDrawRegion_OpType: return "DrawRegion";
  216. case kDrawShadow_OpType: return "DrawShadow";
  217. case kDrawTextBlob_OpType: return "DrawTextBlob";
  218. case kDrawVertices_OpType: return "DrawVertices";
  219. case kDrawAtlas_OpType: return "DrawAtlas";
  220. case kDrawDrawable_OpType: return "DrawDrawable";
  221. case kDrawEdgeAAQuad_OpType: return "DrawEdgeAAQuad";
  222. case kDrawEdgeAAImageSet_OpType: return "DrawEdgeAAImageSet";
  223. case kEndDrawPicture_OpType: return "EndDrawPicture";
  224. case kRestore_OpType: return "Restore";
  225. case kSave_OpType: return "Save";
  226. case kSaveLayer_OpType: return "SaveLayer";
  227. case kSetMatrix_OpType: return "SetMatrix";
  228. default:
  229. SkDebugf("OpType error 0x%08x\n", type);
  230. SkASSERT(0);
  231. break;
  232. }
  233. SkDEBUGFAIL("DrawType UNUSED\n");
  234. return nullptr;
  235. }
  236. void DrawCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  237. writer.appendString(DEBUGCANVAS_ATTRIBUTE_COMMAND, this->GetCommandString(fOpType));
  238. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_VISIBLE, this->isVisible());
  239. }
  240. namespace {
  241. void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
  242. const SkISize& size = canvas->getBaseLayerSize();
  243. static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
  244. canvas->translate(size.fWidth / 2.0f, size.fHeight / 2.0f);
  245. if (bounds.width() > bounds.height()) {
  246. canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.width()),
  247. SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.width()));
  248. } else {
  249. canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.height()),
  250. SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.height()));
  251. }
  252. canvas->translate(-bounds.centerX(), -bounds.centerY());
  253. }
  254. void render_path(SkCanvas* canvas, const SkPath& path) {
  255. canvas->clear(0xFFFFFFFF);
  256. const SkRect& bounds = path.getBounds();
  257. if (bounds.isEmpty()) {
  258. return;
  259. }
  260. SkAutoCanvasRestore acr(canvas, true);
  261. xlate_and_scale_to_bounds(canvas, bounds);
  262. SkPaint p;
  263. p.setColor(SK_ColorBLACK);
  264. p.setStyle(SkPaint::kStroke_Style);
  265. canvas->drawPath(path, p);
  266. }
  267. void render_region(SkCanvas* canvas, const SkRegion& region) {
  268. canvas->clear(0xFFFFFFFF);
  269. const SkIRect& bounds = region.getBounds();
  270. if (bounds.isEmpty()) {
  271. return;
  272. }
  273. SkAutoCanvasRestore acr(canvas, true);
  274. xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
  275. SkPaint p;
  276. p.setColor(SK_ColorBLACK);
  277. p.setStyle(SkPaint::kStroke_Style);
  278. canvas->drawRegion(region, p);
  279. }
  280. void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
  281. const SkISize& size = canvas->getBaseLayerSize();
  282. SkScalar xScale = SkIntToScalar(size.fWidth - 2) / input.width();
  283. SkScalar yScale = SkIntToScalar(size.fHeight - 2) / input.height();
  284. if (input.width() > input.height()) {
  285. yScale *= input.height() / (float)input.width();
  286. } else {
  287. xScale *= input.width() / (float)input.height();
  288. }
  289. SkRect dst = SkRect::MakeXYWH(
  290. SK_Scalar1, SK_Scalar1, xScale * input.width(), yScale * input.height());
  291. static const int kNumBlocks = 8;
  292. canvas->clear(0xFFFFFFFF);
  293. SkISize block = {canvas->imageInfo().width() / kNumBlocks,
  294. canvas->imageInfo().height() / kNumBlocks};
  295. for (int y = 0; y < kNumBlocks; ++y) {
  296. for (int x = 0; x < kNumBlocks; ++x) {
  297. SkPaint paint;
  298. paint.setColor((x + y) % 2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
  299. SkRect r = SkRect::MakeXYWH(SkIntToScalar(x * block.width()),
  300. SkIntToScalar(y * block.height()),
  301. SkIntToScalar(block.width()),
  302. SkIntToScalar(block.height()));
  303. canvas->drawRect(r, paint);
  304. }
  305. }
  306. canvas->drawBitmapRect(input, dst, nullptr);
  307. if (srcRect) {
  308. SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
  309. srcRect->fTop * yScale + SK_Scalar1,
  310. srcRect->fRight * xScale + SK_Scalar1,
  311. srcRect->fBottom * yScale + SK_Scalar1);
  312. SkPaint p;
  313. p.setColor(SK_ColorRED);
  314. p.setStyle(SkPaint::kStroke_Style);
  315. canvas->drawRect(r, p);
  316. }
  317. }
  318. void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
  319. canvas->clear(0xFFFFFFFF);
  320. canvas->save();
  321. const SkRect& bounds = rrect.getBounds();
  322. xlate_and_scale_to_bounds(canvas, bounds);
  323. SkPaint p;
  324. p.setColor(SK_ColorBLACK);
  325. p.setStyle(SkPaint::kStroke_Style);
  326. canvas->drawRRect(rrect, p);
  327. canvas->restore();
  328. }
  329. void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
  330. canvas->clear(0xFFFFFFFF);
  331. canvas->save();
  332. const SkRect& bounds = outer.getBounds();
  333. xlate_and_scale_to_bounds(canvas, bounds);
  334. SkPaint p;
  335. p.setColor(SK_ColorBLACK);
  336. p.setStyle(SkPaint::kStroke_Style);
  337. canvas->drawDRRect(outer, inner, p);
  338. canvas->restore();
  339. }
  340. void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
  341. canvas->clear(0xFFFFFFFF);
  342. const SkRect& bounds = path.getBounds();
  343. if (bounds.isEmpty()) {
  344. return;
  345. }
  346. SkAutoCanvasRestore acr(canvas, true);
  347. xlate_and_scale_to_bounds(canvas, bounds);
  348. rec.fAmbientColor = SK_ColorBLACK;
  349. rec.fSpotColor = SK_ColorBLACK;
  350. canvas->private_draw_shadow_rec(path, rec);
  351. }
  352. static const char* const gBlendModeMap[] = {
  353. "clear", "src", "dst", "srcOver", "dstOver", "srcIn", "dstIn",
  354. "srcOut", "dstOut", "srcATop", "dstATop", "xor", "plus", "modulate",
  355. "screen",
  356. "overlay", "darken", "lighten", "colorDodge", "colorBurn", "hardLight", "softLight",
  357. "difference", "exclusion", "multiply",
  358. "hue", "saturation", "color", "luminosity",
  359. };
  360. static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
  361. "blendMode mismatch");
  362. static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
  363. "blendMode mismatch");
  364. void apply_paint_blend_mode(const SkPaint& paint, SkJSONWriter& writer) {
  365. const auto mode = paint.getBlendMode();
  366. if (mode != SkBlendMode::kSrcOver) {
  367. SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
  368. writer.appendString(DEBUGCANVAS_ATTRIBUTE_BLENDMODE,
  369. gBlendModeMap[static_cast<size_t>(mode)]);
  370. }
  371. }
  372. }; // namespace
  373. void DrawCommand::MakeJsonColor(SkJSONWriter& writer, const SkColor color) {
  374. writer.beginArray(nullptr, false);
  375. writer.appendS32(SkColorGetA(color));
  376. writer.appendS32(SkColorGetR(color));
  377. writer.appendS32(SkColorGetG(color));
  378. writer.appendS32(SkColorGetB(color));
  379. writer.endArray();
  380. }
  381. void DrawCommand::MakeJsonColor4f(SkJSONWriter& writer, const SkColor4f& color) {
  382. writer.beginArray(nullptr, false);
  383. writer.appendFloat(color.fA);
  384. writer.appendFloat(color.fR);
  385. writer.appendFloat(color.fG);
  386. writer.appendFloat(color.fB);
  387. writer.endArray();
  388. }
  389. void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, const SkPoint& point) {
  390. writer.beginArray(nullptr, false);
  391. writer.appendFloat(point.x());
  392. writer.appendFloat(point.y());
  393. writer.endArray();
  394. }
  395. void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, SkScalar x, SkScalar y) {
  396. writer.beginArray(nullptr, false);
  397. writer.appendFloat(x);
  398. writer.appendFloat(y);
  399. writer.endArray();
  400. }
  401. void DrawCommand::MakeJsonPoint3(SkJSONWriter& writer, const SkPoint3& point) {
  402. writer.beginArray(nullptr, false);
  403. writer.appendFloat(point.x());
  404. writer.appendFloat(point.y());
  405. writer.appendFloat(point.z());
  406. writer.endArray();
  407. }
  408. void DrawCommand::MakeJsonRect(SkJSONWriter& writer, const SkRect& rect) {
  409. writer.beginArray(nullptr, false);
  410. writer.appendFloat(rect.left());
  411. writer.appendFloat(rect.top());
  412. writer.appendFloat(rect.right());
  413. writer.appendFloat(rect.bottom());
  414. writer.endArray();
  415. }
  416. void DrawCommand::MakeJsonIRect(SkJSONWriter& writer, const SkIRect& rect) {
  417. writer.beginArray(nullptr, false);
  418. writer.appendS32(rect.left());
  419. writer.appendS32(rect.top());
  420. writer.appendS32(rect.right());
  421. writer.appendS32(rect.bottom());
  422. writer.endArray();
  423. }
  424. static void make_json_rrect(SkJSONWriter& writer, const SkRRect& rrect) {
  425. writer.beginArray(nullptr, false);
  426. DrawCommand::MakeJsonRect(writer, rrect.rect());
  427. DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperLeft_Corner));
  428. DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperRight_Corner));
  429. DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerRight_Corner));
  430. DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerLeft_Corner));
  431. writer.endArray();
  432. }
  433. void DrawCommand::MakeJsonMatrix(SkJSONWriter& writer, const SkMatrix& matrix) {
  434. writer.beginArray();
  435. for (int r = 0; r < 3; ++r) {
  436. writer.beginArray(nullptr, false);
  437. for (int c = 0; c < 3; ++c) {
  438. writer.appendFloat(matrix[r * 3 + c]);
  439. }
  440. writer.endArray();
  441. }
  442. writer.endArray();
  443. }
  444. void DrawCommand::MakeJsonPath(SkJSONWriter& writer, const SkPath& path) {
  445. writer.beginObject();
  446. switch (path.getFillType()) {
  447. case SkPath::kWinding_FillType:
  448. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_WINDING);
  449. break;
  450. case SkPath::kEvenOdd_FillType:
  451. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_EVENODD);
  452. break;
  453. case SkPath::kInverseWinding_FillType:
  454. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
  455. DEBUGCANVAS_FILLTYPE_INVERSEWINDING);
  456. break;
  457. case SkPath::kInverseEvenOdd_FillType:
  458. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
  459. DEBUGCANVAS_FILLTYPE_INVERSEEVENODD);
  460. break;
  461. }
  462. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_VERBS);
  463. SkPath::Iter iter(path, false);
  464. SkPoint pts[4];
  465. SkPath::Verb verb;
  466. while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
  467. if (verb == SkPath::kClose_Verb) {
  468. writer.appendString(DEBUGCANVAS_VERB_CLOSE);
  469. continue;
  470. }
  471. writer.beginObject(); // verb
  472. switch (verb) {
  473. case SkPath::kLine_Verb: {
  474. writer.appendName(DEBUGCANVAS_VERB_LINE);
  475. MakeJsonPoint(writer, pts[1]);
  476. break;
  477. }
  478. case SkPath::kQuad_Verb: {
  479. writer.beginArray(DEBUGCANVAS_VERB_QUAD);
  480. MakeJsonPoint(writer, pts[1]);
  481. MakeJsonPoint(writer, pts[2]);
  482. writer.endArray(); // quad coords
  483. break;
  484. }
  485. case SkPath::kCubic_Verb: {
  486. writer.beginArray(DEBUGCANVAS_VERB_CUBIC);
  487. MakeJsonPoint(writer, pts[1]);
  488. MakeJsonPoint(writer, pts[2]);
  489. MakeJsonPoint(writer, pts[3]);
  490. writer.endArray(); // cubic coords
  491. break;
  492. }
  493. case SkPath::kConic_Verb: {
  494. writer.beginArray(DEBUGCANVAS_VERB_CONIC);
  495. MakeJsonPoint(writer, pts[1]);
  496. MakeJsonPoint(writer, pts[2]);
  497. writer.appendFloat(iter.conicWeight());
  498. writer.endArray(); // conic coords
  499. break;
  500. }
  501. case SkPath::kMove_Verb: {
  502. writer.appendName(DEBUGCANVAS_VERB_MOVE);
  503. MakeJsonPoint(writer, pts[0]);
  504. break;
  505. }
  506. case SkPath::kClose_Verb:
  507. case SkPath::kDone_Verb:
  508. // Unreachable
  509. break;
  510. }
  511. writer.endObject(); // verb
  512. }
  513. writer.endArray(); // verbs
  514. writer.endObject(); // path
  515. }
  516. void DrawCommand::MakeJsonRegion(SkJSONWriter& writer, const SkRegion& region) {
  517. // TODO: Actually serialize the rectangles, rather than just devolving to path
  518. SkPath path;
  519. region.getBoundaryPath(&path);
  520. MakeJsonPath(writer, path);
  521. }
  522. static const char* regionop_name(SkClipOp op) {
  523. switch (op) {
  524. case kDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_DIFFERENCE;
  525. case kIntersect_SkClipOp: return DEBUGCANVAS_REGIONOP_INTERSECT;
  526. case kUnion_SkClipOp: return DEBUGCANVAS_REGIONOP_UNION;
  527. case kXOR_SkClipOp: return DEBUGCANVAS_REGIONOP_XOR;
  528. case kReverseDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE;
  529. case kReplace_SkClipOp: return DEBUGCANVAS_REGIONOP_REPLACE;
  530. default: SkASSERT(false); return "<invalid region op>";
  531. }
  532. }
  533. static const char* pointmode_name(SkCanvas::PointMode mode) {
  534. switch (mode) {
  535. case SkCanvas::kPoints_PointMode: return DEBUGCANVAS_POINTMODE_POINTS;
  536. case SkCanvas::kLines_PointMode: return DEBUGCANVAS_POINTMODE_LINES;
  537. case SkCanvas::kPolygon_PointMode: return DEBUGCANVAS_POINTMODE_POLYGON;
  538. default: SkASSERT(false); return "<invalid point mode>";
  539. }
  540. }
  541. static void store_scalar(SkJSONWriter& writer,
  542. const char* key,
  543. SkScalar value,
  544. SkScalar defaultValue) {
  545. if (value != defaultValue) {
  546. writer.appendFloat(key, value);
  547. }
  548. }
  549. static void store_bool(SkJSONWriter& writer, const char* key, bool value, bool defaultValue) {
  550. if (value != defaultValue) {
  551. writer.appendBool(key, value);
  552. }
  553. }
  554. static SkString encode_data(const void* bytes,
  555. size_t count,
  556. const char* contentType,
  557. UrlDataManager& urlDataManager) {
  558. sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
  559. return urlDataManager.addData(data.get(), contentType);
  560. }
  561. void DrawCommand::flatten(const SkFlattenable* flattenable,
  562. SkJSONWriter& writer,
  563. UrlDataManager& urlDataManager) {
  564. SkBinaryWriteBuffer buffer;
  565. flattenable->flatten(buffer);
  566. void* data = sk_malloc_throw(buffer.bytesWritten());
  567. buffer.writeToMemory(data);
  568. SkString url =
  569. encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
  570. writer.appendString(DEBUGCANVAS_ATTRIBUTE_NAME, flattenable->getTypeName());
  571. writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
  572. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_VALUES);
  573. JsonWriteBuffer jsonBuffer(&writer, &urlDataManager);
  574. flattenable->flatten(jsonBuffer);
  575. writer.endObject(); // values
  576. sk_free(data);
  577. }
  578. void DrawCommand::WritePNG(SkBitmap bitmap, SkWStream& out) {
  579. SkPixmap pm;
  580. SkAssertResult(bitmap.peekPixels(&pm));
  581. SkPngEncoder::Options options;
  582. options.fZLibLevel = 1;
  583. options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
  584. SkPngEncoder::Encode(&out, pm, options);
  585. }
  586. bool DrawCommand::flatten(const SkImage& image,
  587. SkJSONWriter& writer,
  588. UrlDataManager& urlDataManager) {
  589. size_t rowBytes = 4 * image.width();
  590. SkAutoMalloc buffer(rowBytes * image.height());
  591. SkImageInfo dstInfo =
  592. SkImageInfo::Make(image.width(), image.height(), kN32_SkColorType, kPremul_SkAlphaType);
  593. if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
  594. SkDebugf("readPixels failed\n");
  595. return false;
  596. }
  597. SkBitmap bm;
  598. bm.installPixels(dstInfo, buffer.get(), rowBytes);
  599. SkDynamicMemoryWStream out;
  600. DrawCommand::WritePNG(bm, out);
  601. sk_sp<SkData> encoded = out.detachAsData();
  602. SkString url = encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager);
  603. writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
  604. return true;
  605. }
  606. static const char* color_type_name(SkColorType colorType) {
  607. switch (colorType) {
  608. case kARGB_4444_SkColorType: return DEBUGCANVAS_COLORTYPE_ARGB4444;
  609. case kRGBA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_RGBA8888;
  610. case kBGRA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_BGRA8888;
  611. case kRGB_565_SkColorType: return DEBUGCANVAS_COLORTYPE_565;
  612. case kGray_8_SkColorType: return DEBUGCANVAS_COLORTYPE_GRAY8;
  613. case kAlpha_8_SkColorType: return DEBUGCANVAS_COLORTYPE_ALPHA8;
  614. default: SkASSERT(false); return DEBUGCANVAS_COLORTYPE_RGBA8888;
  615. }
  616. }
  617. static const char* alpha_type_name(SkAlphaType alphaType) {
  618. switch (alphaType) {
  619. case kOpaque_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_OPAQUE;
  620. case kPremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_PREMUL;
  621. case kUnpremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_UNPREMUL;
  622. default: SkASSERT(false); return DEBUGCANVAS_ALPHATYPE_OPAQUE;
  623. }
  624. }
  625. bool DrawCommand::flatten(const SkBitmap& bitmap,
  626. SkJSONWriter& writer,
  627. UrlDataManager& urlDataManager) {
  628. sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
  629. writer.appendString(DEBUGCANVAS_ATTRIBUTE_COLOR, color_type_name(bitmap.colorType()));
  630. writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, alpha_type_name(bitmap.alphaType()));
  631. bool success = flatten(*image, writer, urlDataManager);
  632. return success;
  633. }
  634. static void apply_font_hinting(const SkFont& font, SkJSONWriter& writer) {
  635. SkFontHinting hinting = font.getHinting();
  636. if (hinting != SkPaintDefaults_Hinting) {
  637. switch (hinting) {
  638. case SkFontHinting::kNone:
  639. writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NONE);
  640. break;
  641. case SkFontHinting::kSlight:
  642. writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_SLIGHT);
  643. break;
  644. case SkFontHinting::kNormal:
  645. writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NORMAL);
  646. break;
  647. case SkFontHinting::kFull:
  648. writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_FULL);
  649. break;
  650. }
  651. }
  652. }
  653. static void apply_font_edging(const SkFont& font, SkJSONWriter& writer) {
  654. switch (font.getEdging()) {
  655. case SkFont::Edging::kAlias:
  656. writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ALIAS);
  657. break;
  658. case SkFont::Edging::kAntiAlias:
  659. writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ANTIALIAS);
  660. break;
  661. case SkFont::Edging::kSubpixelAntiAlias:
  662. writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS);
  663. break;
  664. }
  665. }
  666. static void apply_paint_color(const SkPaint& paint, SkJSONWriter& writer) {
  667. SkColor color = paint.getColor();
  668. if (color != SK_ColorBLACK) {
  669. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
  670. DrawCommand::MakeJsonColor(writer, color);
  671. }
  672. }
  673. static void apply_paint_style(const SkPaint& paint, SkJSONWriter& writer) {
  674. SkPaint::Style style = paint.getStyle();
  675. if (style != SkPaint::kFill_Style) {
  676. switch (style) {
  677. case SkPaint::kStroke_Style: {
  678. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKE);
  679. break;
  680. }
  681. case SkPaint::kStrokeAndFill_Style: {
  682. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKEANDFILL);
  683. break;
  684. }
  685. default: SkASSERT(false);
  686. }
  687. }
  688. }
  689. static void apply_paint_cap(const SkPaint& paint, SkJSONWriter& writer) {
  690. SkPaint::Cap cap = paint.getStrokeCap();
  691. if (cap != SkPaint::kDefault_Cap) {
  692. switch (cap) {
  693. case SkPaint::kButt_Cap:
  694. writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_BUTT);
  695. break;
  696. case SkPaint::kRound_Cap:
  697. writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_ROUND);
  698. break;
  699. case SkPaint::kSquare_Cap:
  700. writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_SQUARE);
  701. break;
  702. default: SkASSERT(false);
  703. }
  704. }
  705. }
  706. static void apply_paint_join(const SkPaint& paint, SkJSONWriter& writer) {
  707. SkPaint::Join join = paint.getStrokeJoin();
  708. if (join != SkPaint::kDefault_Join) {
  709. switch (join) {
  710. case SkPaint::kMiter_Join:
  711. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_MITER_JOIN);
  712. break;
  713. case SkPaint::kRound_Join:
  714. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_ROUND_JOIN);
  715. break;
  716. case SkPaint::kBevel_Join:
  717. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_BEVEL_JOIN);
  718. break;
  719. default: SkASSERT(false);
  720. }
  721. }
  722. }
  723. static void apply_paint_filterquality(const SkPaint& paint, SkJSONWriter& writer) {
  724. SkFilterQuality quality = paint.getFilterQuality();
  725. switch (quality) {
  726. case kNone_SkFilterQuality: break;
  727. case kLow_SkFilterQuality:
  728. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY, DEBUGCANVAS_FILTERQUALITY_LOW);
  729. break;
  730. case kMedium_SkFilterQuality:
  731. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
  732. DEBUGCANVAS_FILTERQUALITY_MEDIUM);
  733. break;
  734. case kHigh_SkFilterQuality:
  735. writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
  736. DEBUGCANVAS_FILTERQUALITY_HIGH);
  737. break;
  738. }
  739. }
  740. static void apply_paint_maskfilter(const SkPaint& paint,
  741. SkJSONWriter& writer,
  742. UrlDataManager& urlDataManager) {
  743. SkMaskFilter* maskFilter = paint.getMaskFilter();
  744. if (maskFilter != nullptr) {
  745. SkMaskFilterBase::BlurRec blurRec;
  746. if (as_MFB(maskFilter)->asABlur(&blurRec)) {
  747. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BLUR);
  748. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SIGMA, blurRec.fSigma);
  749. switch (blurRec.fStyle) {
  750. case SkBlurStyle::kNormal_SkBlurStyle:
  751. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_NORMAL);
  752. break;
  753. case SkBlurStyle::kSolid_SkBlurStyle:
  754. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_SOLID);
  755. break;
  756. case SkBlurStyle::kOuter_SkBlurStyle:
  757. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_OUTER);
  758. break;
  759. case SkBlurStyle::kInner_SkBlurStyle:
  760. writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_INNER);
  761. break;
  762. default: SkASSERT(false);
  763. }
  764. writer.endObject(); // blur
  765. } else {
  766. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_MASKFILTER);
  767. DrawCommand::flatten(maskFilter, writer, urlDataManager);
  768. writer.endObject(); // maskFilter
  769. }
  770. }
  771. }
  772. static void apply_paint_patheffect(const SkPaint& paint,
  773. SkJSONWriter& writer,
  774. UrlDataManager& urlDataManager) {
  775. SkPathEffect* pathEffect = paint.getPathEffect();
  776. if (pathEffect != nullptr) {
  777. SkPathEffect::DashInfo dashInfo;
  778. SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
  779. if (dashType == SkPathEffect::kDash_DashType) {
  780. dashInfo.fIntervals = (SkScalar*)sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
  781. pathEffect->asADash(&dashInfo);
  782. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_DASHING);
  783. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_INTERVALS, false);
  784. for (int32_t i = 0; i < dashInfo.fCount; i++) {
  785. writer.appendFloat(dashInfo.fIntervals[i]);
  786. }
  787. writer.endArray(); // intervals
  788. sk_free(dashInfo.fIntervals);
  789. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_PHASE, dashInfo.fPhase);
  790. writer.endObject(); // dashing
  791. } else {
  792. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_PATHEFFECT);
  793. DrawCommand::flatten(pathEffect, writer, urlDataManager);
  794. writer.endObject(); // pathEffect
  795. }
  796. }
  797. }
  798. static void apply_font_typeface(const SkFont& font,
  799. SkJSONWriter& writer,
  800. UrlDataManager& urlDataManager) {
  801. SkTypeface* typeface = font.getTypefaceOrDefault();
  802. if (typeface != nullptr) {
  803. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_TYPEFACE);
  804. SkDynamicMemoryWStream buffer;
  805. typeface->serialize(&buffer);
  806. void* data = sk_malloc_throw(buffer.bytesWritten());
  807. buffer.copyTo(data);
  808. SkString url = encode_data(
  809. data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
  810. writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
  811. sk_free(data);
  812. writer.endObject();
  813. }
  814. }
  815. static void apply_flattenable(const char* key,
  816. SkFlattenable* flattenable,
  817. SkJSONWriter& writer,
  818. UrlDataManager& urlDataManager) {
  819. if (flattenable != nullptr) {
  820. writer.beginObject(key);
  821. DrawCommand::flatten(flattenable, writer, urlDataManager);
  822. writer.endObject();
  823. }
  824. }
  825. void DrawCommand::MakeJsonPaint(SkJSONWriter& writer,
  826. const SkPaint& paint,
  827. UrlDataManager& urlDataManager) {
  828. writer.beginObject();
  829. store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
  830. store_scalar(writer,
  831. DEBUGCANVAS_ATTRIBUTE_STROKEMITER,
  832. paint.getStrokeMiter(),
  833. SkPaintDefaults_MiterLimit);
  834. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
  835. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
  836. apply_paint_color(paint, writer);
  837. apply_paint_style(paint, writer);
  838. apply_paint_blend_mode(paint, writer);
  839. apply_paint_cap(paint, writer);
  840. apply_paint_join(paint, writer);
  841. apply_paint_filterquality(paint, writer);
  842. apply_paint_patheffect(paint, writer, urlDataManager);
  843. apply_paint_maskfilter(paint, writer, urlDataManager);
  844. apply_flattenable(DEBUGCANVAS_ATTRIBUTE_SHADER, paint.getShader(), writer, urlDataManager);
  845. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  846. apply_flattenable(DEBUGCANVAS_ATTRIBUTE_LOOPER, paint.getLooper(), writer, urlDataManager);
  847. #endif
  848. apply_flattenable(
  849. DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER, paint.getImageFilter(), writer, urlDataManager);
  850. apply_flattenable(
  851. DEBUGCANVAS_ATTRIBUTE_COLORFILTER, paint.getColorFilter(), writer, urlDataManager);
  852. writer.endObject(); // paint
  853. }
  854. static void MakeJsonFont(const SkFont& font, SkJSONWriter& writer, UrlDataManager& urlDataManager) {
  855. writer.beginObject();
  856. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, font.isEmbolden(), false);
  857. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_LINEARTEXT, font.isLinearMetrics(), false);
  858. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, font.isSubpixel(), false);
  859. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, font.isEmbeddedBitmaps(), false);
  860. store_bool(writer, DEBUGCANVAS_ATTRIBUTE_AUTOHINTING, font.isForceAutoHinting(), false);
  861. store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSIZE, font.getSize(), SkPaintDefaults_TextSize);
  862. store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getScaleX(), SK_Scalar1);
  863. store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getSkewX(), 0.0f);
  864. apply_font_edging(font, writer);
  865. apply_font_hinting(font, writer);
  866. apply_font_typeface(font, writer, urlDataManager);
  867. writer.endObject(); // font
  868. }
  869. void DrawCommand::MakeJsonLattice(SkJSONWriter& writer, const SkCanvas::Lattice& lattice) {
  870. writer.beginObject();
  871. writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT, lattice.fXCount);
  872. writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT, lattice.fYCount);
  873. if (nullptr != lattice.fBounds) {
  874. writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
  875. MakeJsonIRect(writer, *lattice.fBounds);
  876. }
  877. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS);
  878. for (int i = 0; i < lattice.fXCount; i++) {
  879. writer.appendS32(lattice.fXDivs[i]);
  880. }
  881. writer.endArray(); // xdivs
  882. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS);
  883. for (int i = 0; i < lattice.fYCount; i++) {
  884. writer.appendS32(lattice.fYDivs[i]);
  885. }
  886. writer.endArray(); // ydivs
  887. if (nullptr != lattice.fRectTypes) {
  888. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS);
  889. int flagCount = 0;
  890. for (int row = 0; row < lattice.fYCount + 1; row++) {
  891. writer.beginArray();
  892. for (int column = 0; column < lattice.fXCount + 1; column++) {
  893. writer.appendS32(lattice.fRectTypes[flagCount++]);
  894. }
  895. writer.endArray(); // row
  896. }
  897. writer.endArray();
  898. }
  899. writer.endObject();
  900. }
  901. ClearCommand::ClearCommand(SkColor color) : INHERITED(kClear_OpType) { fColor = color; }
  902. void ClearCommand::execute(SkCanvas* canvas) const { canvas->clear(fColor); }
  903. void ClearCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  904. INHERITED::toJSON(writer, urlDataManager);
  905. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
  906. MakeJsonColor(writer, fColor);
  907. }
  908. ClipPathCommand::ClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
  909. : INHERITED(kClipPath_OpType) {
  910. fPath = path;
  911. fOp = op;
  912. fDoAA = doAA;
  913. }
  914. void ClipPathCommand::execute(SkCanvas* canvas) const { canvas->clipPath(fPath, fOp, fDoAA); }
  915. bool ClipPathCommand::render(SkCanvas* canvas) const {
  916. render_path(canvas, fPath);
  917. return true;
  918. }
  919. void ClipPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  920. INHERITED::toJSON(writer, urlDataManager);
  921. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
  922. MakeJsonPath(writer, fPath);
  923. writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
  924. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
  925. }
  926. ClipRegionCommand::ClipRegionCommand(const SkRegion& region, SkClipOp op)
  927. : INHERITED(kClipRegion_OpType) {
  928. fRegion = region;
  929. fOp = op;
  930. }
  931. void ClipRegionCommand::execute(SkCanvas* canvas) const { canvas->clipRegion(fRegion, fOp); }
  932. void ClipRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  933. INHERITED::toJSON(writer, urlDataManager);
  934. writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
  935. MakeJsonRegion(writer, fRegion);
  936. writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
  937. }
  938. ClipRectCommand::ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
  939. : INHERITED(kClipRect_OpType) {
  940. fRect = rect;
  941. fOp = op;
  942. fDoAA = doAA;
  943. }
  944. void ClipRectCommand::execute(SkCanvas* canvas) const { canvas->clipRect(fRect, fOp, fDoAA); }
  945. void ClipRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  946. INHERITED::toJSON(writer, urlDataManager);
  947. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  948. MakeJsonRect(writer, fRect);
  949. writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
  950. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
  951. SkString desc;
  952. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
  953. }
  954. ClipRRectCommand::ClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
  955. : INHERITED(kClipRRect_OpType) {
  956. fRRect = rrect;
  957. fOp = op;
  958. fDoAA = doAA;
  959. }
  960. void ClipRRectCommand::execute(SkCanvas* canvas) const { canvas->clipRRect(fRRect, fOp, fDoAA); }
  961. bool ClipRRectCommand::render(SkCanvas* canvas) const {
  962. render_rrect(canvas, fRRect);
  963. return true;
  964. }
  965. void ClipRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  966. INHERITED::toJSON(writer, urlDataManager);
  967. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  968. make_json_rrect(writer, fRRect);
  969. writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
  970. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
  971. }
  972. ConcatCommand::ConcatCommand(const SkMatrix& matrix) : INHERITED(kConcat_OpType) {
  973. fMatrix = matrix;
  974. }
  975. void ConcatCommand::execute(SkCanvas* canvas) const { canvas->concat(fMatrix); }
  976. void ConcatCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  977. INHERITED::toJSON(writer, urlDataManager);
  978. writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
  979. MakeJsonMatrix(writer, fMatrix);
  980. }
  981. ////
  982. DrawAnnotationCommand::DrawAnnotationCommand(const SkRect& rect,
  983. const char key[],
  984. sk_sp<SkData> value)
  985. : INHERITED(kDrawAnnotation_OpType), fRect(rect), fKey(key), fValue(std::move(value)) {}
  986. void DrawAnnotationCommand::execute(SkCanvas* canvas) const {
  987. canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
  988. }
  989. void DrawAnnotationCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  990. INHERITED::toJSON(writer, urlDataManager);
  991. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  992. MakeJsonRect(writer, fRect);
  993. writer.appendString("key", fKey.c_str());
  994. if (fValue.get()) {
  995. // TODO: dump out the "value"
  996. }
  997. SkString desc;
  998. str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
  999. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, desc.c_str());
  1000. }
  1001. ////
  1002. DrawBitmapCommand::DrawBitmapCommand(const SkBitmap& bitmap,
  1003. SkScalar left,
  1004. SkScalar top,
  1005. const SkPaint* paint)
  1006. : INHERITED(kDrawBitmap_OpType), fBitmap(bitmap), fLeft(left), fTop(top), fPaint(paint) {}
  1007. void DrawBitmapCommand::execute(SkCanvas* canvas) const {
  1008. canvas->drawBitmap(fBitmap, fLeft, fTop, fPaint.getMaybeNull());
  1009. }
  1010. bool DrawBitmapCommand::render(SkCanvas* canvas) const {
  1011. render_bitmap(canvas, fBitmap);
  1012. return true;
  1013. }
  1014. void DrawBitmapCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1015. INHERITED::toJSON(writer, urlDataManager);
  1016. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
  1017. flatten(fBitmap, writer, urlDataManager);
  1018. writer.endObject();
  1019. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1020. MakeJsonPoint(writer, fLeft, fTop);
  1021. if (fPaint.isValid()) {
  1022. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1023. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1024. }
  1025. }
  1026. DrawBitmapLatticeCommand::DrawBitmapLatticeCommand(const SkBitmap& bitmap,
  1027. const SkCanvas::Lattice& lattice,
  1028. const SkRect& dst,
  1029. const SkPaint* paint)
  1030. : INHERITED(kDrawBitmapLattice_OpType)
  1031. , fBitmap(bitmap)
  1032. , fLattice(lattice)
  1033. , fDst(dst)
  1034. , fPaint(paint) {}
  1035. void DrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
  1036. canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
  1037. }
  1038. bool DrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
  1039. SkAutoCanvasRestore acr(canvas, true);
  1040. canvas->clear(0xFFFFFFFF);
  1041. xlate_and_scale_to_bounds(canvas, fDst);
  1042. this->execute(canvas);
  1043. return true;
  1044. }
  1045. void DrawBitmapLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1046. INHERITED::toJSON(writer, urlDataManager);
  1047. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
  1048. flatten(fBitmap, writer, urlDataManager);
  1049. writer.endObject(); // bitmap
  1050. writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
  1051. MakeJsonLattice(writer, fLattice);
  1052. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1053. MakeJsonRect(writer, fDst);
  1054. if (fPaint.isValid()) {
  1055. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1056. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1057. }
  1058. SkString desc;
  1059. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
  1060. }
  1061. DrawBitmapNineCommand::DrawBitmapNineCommand(const SkBitmap& bitmap,
  1062. const SkIRect& center,
  1063. const SkRect& dst,
  1064. const SkPaint* paint)
  1065. : INHERITED(kDrawBitmapNine_OpType)
  1066. , fBitmap(bitmap)
  1067. , fCenter(center)
  1068. , fDst(dst)
  1069. , fPaint(paint) {}
  1070. void DrawBitmapNineCommand::execute(SkCanvas* canvas) const {
  1071. canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaint.getMaybeNull());
  1072. }
  1073. bool DrawBitmapNineCommand::render(SkCanvas* canvas) const {
  1074. SkRect tmp = SkRect::Make(fCenter);
  1075. render_bitmap(canvas, fBitmap, &tmp);
  1076. return true;
  1077. }
  1078. void DrawBitmapNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1079. INHERITED::toJSON(writer, urlDataManager);
  1080. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
  1081. flatten(fBitmap, writer, urlDataManager);
  1082. writer.endObject(); // bitmap
  1083. writer.appendName(DEBUGCANVAS_ATTRIBUTE_CENTER);
  1084. MakeJsonIRect(writer, fCenter);
  1085. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1086. MakeJsonRect(writer, fDst);
  1087. if (fPaint.isValid()) {
  1088. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1089. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1090. }
  1091. }
  1092. DrawBitmapRectCommand::DrawBitmapRectCommand(const SkBitmap& bitmap,
  1093. const SkRect* src,
  1094. const SkRect& dst,
  1095. const SkPaint* paint,
  1096. SkCanvas::SrcRectConstraint constraint)
  1097. : INHERITED(kDrawBitmapRect_OpType)
  1098. , fBitmap(bitmap)
  1099. , fSrc(src)
  1100. , fDst(dst)
  1101. , fPaint(paint)
  1102. , fConstraint(constraint) {}
  1103. void DrawBitmapRectCommand::execute(SkCanvas* canvas) const {
  1104. canvas->legacy_drawBitmapRect(
  1105. fBitmap, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
  1106. }
  1107. bool DrawBitmapRectCommand::render(SkCanvas* canvas) const {
  1108. render_bitmap(canvas, fBitmap, fSrc.getMaybeNull());
  1109. return true;
  1110. }
  1111. void DrawBitmapRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1112. INHERITED::toJSON(writer, urlDataManager);
  1113. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
  1114. flatten(fBitmap, writer, urlDataManager);
  1115. writer.endObject(); // bitmap
  1116. if (fSrc.isValid()) {
  1117. writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
  1118. MakeJsonRect(writer, *fSrc);
  1119. }
  1120. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1121. MakeJsonRect(writer, fDst);
  1122. if (fPaint.isValid()) {
  1123. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1124. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1125. }
  1126. if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
  1127. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
  1128. }
  1129. SkString desc;
  1130. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
  1131. }
  1132. DrawImageCommand::DrawImageCommand(const SkImage* image,
  1133. SkScalar left,
  1134. SkScalar top,
  1135. const SkPaint* paint)
  1136. : INHERITED(kDrawImage_OpType)
  1137. , fImage(SkRef(image))
  1138. , fLeft(left)
  1139. , fTop(top)
  1140. , fPaint(paint) {}
  1141. void DrawImageCommand::execute(SkCanvas* canvas) const {
  1142. canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
  1143. }
  1144. bool DrawImageCommand::render(SkCanvas* canvas) const {
  1145. SkAutoCanvasRestore acr(canvas, true);
  1146. canvas->clear(0xFFFFFFFF);
  1147. xlate_and_scale_to_bounds(
  1148. canvas,
  1149. SkRect::MakeXYWH(
  1150. fLeft, fTop, SkIntToScalar(fImage->width()), SkIntToScalar(fImage->height())));
  1151. this->execute(canvas);
  1152. return true;
  1153. }
  1154. void DrawImageCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1155. INHERITED::toJSON(writer, urlDataManager);
  1156. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
  1157. flatten(*fImage, writer, urlDataManager);
  1158. writer.endObject(); // image
  1159. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1160. MakeJsonPoint(writer, fLeft, fTop);
  1161. if (fPaint.isValid()) {
  1162. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1163. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1164. }
  1165. writer.appendU32(DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID, fImage->uniqueID());
  1166. writer.appendS32(DEBUGCANVAS_ATTRIBUTE_WIDTH, fImage->width());
  1167. writer.appendS32(DEBUGCANVAS_ATTRIBUTE_HEIGHT, fImage->height());
  1168. switch (fImage->alphaType()) {
  1169. case kOpaque_SkAlphaType:
  1170. writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_OPAQUE);
  1171. break;
  1172. case kPremul_SkAlphaType:
  1173. writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_PREMUL);
  1174. break;
  1175. case kUnpremul_SkAlphaType:
  1176. writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNPREMUL);
  1177. break;
  1178. default:
  1179. writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNKNOWN);
  1180. break;
  1181. }
  1182. }
  1183. DrawImageLatticeCommand::DrawImageLatticeCommand(const SkImage* image,
  1184. const SkCanvas::Lattice& lattice,
  1185. const SkRect& dst,
  1186. const SkPaint* paint)
  1187. : INHERITED(kDrawImageLattice_OpType)
  1188. , fImage(SkRef(image))
  1189. , fLattice(lattice)
  1190. , fDst(dst)
  1191. , fPaint(paint) {}
  1192. void DrawImageLatticeCommand::execute(SkCanvas* canvas) const {
  1193. canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
  1194. }
  1195. bool DrawImageLatticeCommand::render(SkCanvas* canvas) const {
  1196. SkAutoCanvasRestore acr(canvas, true);
  1197. canvas->clear(0xFFFFFFFF);
  1198. xlate_and_scale_to_bounds(canvas, fDst);
  1199. this->execute(canvas);
  1200. return true;
  1201. }
  1202. void DrawImageLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1203. INHERITED::toJSON(writer, urlDataManager);
  1204. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
  1205. flatten(*fImage, writer, urlDataManager);
  1206. writer.endObject(); // image
  1207. writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
  1208. MakeJsonLattice(writer, fLattice);
  1209. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1210. MakeJsonRect(writer, fDst);
  1211. if (fPaint.isValid()) {
  1212. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1213. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1214. }
  1215. SkString desc;
  1216. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
  1217. }
  1218. DrawImageRectCommand::DrawImageRectCommand(const SkImage* image,
  1219. const SkRect* src,
  1220. const SkRect& dst,
  1221. const SkPaint* paint,
  1222. SkCanvas::SrcRectConstraint constraint)
  1223. : INHERITED(kDrawImageRect_OpType)
  1224. , fImage(SkRef(image))
  1225. , fSrc(src)
  1226. , fDst(dst)
  1227. , fPaint(paint)
  1228. , fConstraint(constraint) {}
  1229. void DrawImageRectCommand::execute(SkCanvas* canvas) const {
  1230. canvas->legacy_drawImageRect(
  1231. fImage.get(), fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
  1232. }
  1233. bool DrawImageRectCommand::render(SkCanvas* canvas) const {
  1234. SkAutoCanvasRestore acr(canvas, true);
  1235. canvas->clear(0xFFFFFFFF);
  1236. xlate_and_scale_to_bounds(canvas, fDst);
  1237. this->execute(canvas);
  1238. return true;
  1239. }
  1240. void DrawImageRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1241. INHERITED::toJSON(writer, urlDataManager);
  1242. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
  1243. flatten(*fImage, writer, urlDataManager);
  1244. writer.endObject(); // image
  1245. if (fSrc.isValid()) {
  1246. writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
  1247. MakeJsonRect(writer, *fSrc);
  1248. }
  1249. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1250. MakeJsonRect(writer, fDst);
  1251. if (fPaint.isValid()) {
  1252. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1253. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1254. }
  1255. if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
  1256. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
  1257. }
  1258. SkString desc;
  1259. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
  1260. }
  1261. DrawImageNineCommand::DrawImageNineCommand(const SkImage* image,
  1262. const SkIRect& center,
  1263. const SkRect& dst,
  1264. const SkPaint* paint)
  1265. : INHERITED(kDrawImageNine_OpType)
  1266. , fImage(SkRef(image))
  1267. , fCenter(center)
  1268. , fDst(dst)
  1269. , fPaint(paint) {}
  1270. void DrawImageNineCommand::execute(SkCanvas* canvas) const {
  1271. canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaint.getMaybeNull());
  1272. }
  1273. bool DrawImageNineCommand::render(SkCanvas* canvas) const {
  1274. SkAutoCanvasRestore acr(canvas, true);
  1275. canvas->clear(0xFFFFFFFF);
  1276. xlate_and_scale_to_bounds(canvas, fDst);
  1277. this->execute(canvas);
  1278. return true;
  1279. }
  1280. void DrawImageNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1281. INHERITED::toJSON(writer, urlDataManager);
  1282. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
  1283. flatten(*fImage, writer, urlDataManager);
  1284. writer.endObject(); // image
  1285. writer.appendName(DEBUGCANVAS_ATTRIBUTE_CENTER);
  1286. MakeJsonIRect(writer, fCenter);
  1287. writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
  1288. MakeJsonRect(writer, fDst);
  1289. if (fPaint.isValid()) {
  1290. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1291. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1292. }
  1293. }
  1294. DrawOvalCommand::DrawOvalCommand(const SkRect& oval, const SkPaint& paint)
  1295. : INHERITED(kDrawOval_OpType) {
  1296. fOval = oval;
  1297. fPaint = paint;
  1298. }
  1299. void DrawOvalCommand::execute(SkCanvas* canvas) const { canvas->drawOval(fOval, fPaint); }
  1300. bool DrawOvalCommand::render(SkCanvas* canvas) const {
  1301. canvas->clear(0xFFFFFFFF);
  1302. canvas->save();
  1303. xlate_and_scale_to_bounds(canvas, fOval);
  1304. SkPaint p;
  1305. p.setColor(SK_ColorBLACK);
  1306. p.setStyle(SkPaint::kStroke_Style);
  1307. canvas->drawOval(fOval, p);
  1308. canvas->restore();
  1309. return true;
  1310. }
  1311. void DrawOvalCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1312. INHERITED::toJSON(writer, urlDataManager);
  1313. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1314. MakeJsonRect(writer, fOval);
  1315. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1316. MakeJsonPaint(writer, fPaint, urlDataManager);
  1317. }
  1318. DrawArcCommand::DrawArcCommand(const SkRect& oval,
  1319. SkScalar startAngle,
  1320. SkScalar sweepAngle,
  1321. bool useCenter,
  1322. const SkPaint& paint)
  1323. : INHERITED(kDrawArc_OpType) {
  1324. fOval = oval;
  1325. fStartAngle = startAngle;
  1326. fSweepAngle = sweepAngle;
  1327. fUseCenter = useCenter;
  1328. fPaint = paint;
  1329. }
  1330. void DrawArcCommand::execute(SkCanvas* canvas) const {
  1331. canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
  1332. }
  1333. bool DrawArcCommand::render(SkCanvas* canvas) const {
  1334. canvas->clear(0xFFFFFFFF);
  1335. canvas->save();
  1336. xlate_and_scale_to_bounds(canvas, fOval);
  1337. SkPaint p;
  1338. p.setColor(SK_ColorBLACK);
  1339. p.setStyle(SkPaint::kStroke_Style);
  1340. canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
  1341. canvas->restore();
  1342. return true;
  1343. }
  1344. void DrawArcCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1345. INHERITED::toJSON(writer, urlDataManager);
  1346. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1347. MakeJsonRect(writer, fOval);
  1348. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_STARTANGLE, fStartAngle);
  1349. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE, fSweepAngle);
  1350. writer.appendBool(DEBUGCANVAS_ATTRIBUTE_USECENTER, fUseCenter);
  1351. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1352. MakeJsonPaint(writer, fPaint, urlDataManager);
  1353. }
  1354. DrawPaintCommand::DrawPaintCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
  1355. fPaint = paint;
  1356. }
  1357. void DrawPaintCommand::execute(SkCanvas* canvas) const { canvas->drawPaint(fPaint); }
  1358. bool DrawPaintCommand::render(SkCanvas* canvas) const {
  1359. canvas->clear(0xFFFFFFFF);
  1360. canvas->drawPaint(fPaint);
  1361. return true;
  1362. }
  1363. void DrawPaintCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1364. INHERITED::toJSON(writer, urlDataManager);
  1365. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1366. MakeJsonPaint(writer, fPaint, urlDataManager);
  1367. }
  1368. DrawBehindCommand::DrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
  1369. fPaint = paint;
  1370. }
  1371. void DrawBehindCommand::execute(SkCanvas* canvas) const {
  1372. SkCanvasPriv::DrawBehind(canvas, fPaint);
  1373. }
  1374. bool DrawBehindCommand::render(SkCanvas* canvas) const {
  1375. canvas->clear(0xFFFFFFFF);
  1376. SkCanvasPriv::DrawBehind(canvas, fPaint);
  1377. return true;
  1378. }
  1379. void DrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1380. INHERITED::toJSON(writer, urlDataManager);
  1381. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1382. MakeJsonPaint(writer, fPaint, urlDataManager);
  1383. }
  1384. DrawPathCommand::DrawPathCommand(const SkPath& path, const SkPaint& paint)
  1385. : INHERITED(kDrawPath_OpType) {
  1386. fPath = path;
  1387. fPaint = paint;
  1388. }
  1389. void DrawPathCommand::execute(SkCanvas* canvas) const { canvas->drawPath(fPath, fPaint); }
  1390. bool DrawPathCommand::render(SkCanvas* canvas) const {
  1391. render_path(canvas, fPath);
  1392. return true;
  1393. }
  1394. void DrawPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1395. INHERITED::toJSON(writer, urlDataManager);
  1396. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
  1397. MakeJsonPath(writer, fPath);
  1398. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1399. MakeJsonPaint(writer, fPaint, urlDataManager);
  1400. }
  1401. DrawRegionCommand::DrawRegionCommand(const SkRegion& region, const SkPaint& paint)
  1402. : INHERITED(kDrawRegion_OpType) {
  1403. fRegion = region;
  1404. fPaint = paint;
  1405. }
  1406. void DrawRegionCommand::execute(SkCanvas* canvas) const { canvas->drawRegion(fRegion, fPaint); }
  1407. bool DrawRegionCommand::render(SkCanvas* canvas) const {
  1408. render_region(canvas, fRegion);
  1409. return true;
  1410. }
  1411. void DrawRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1412. INHERITED::toJSON(writer, urlDataManager);
  1413. writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
  1414. MakeJsonRegion(writer, fRegion);
  1415. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1416. MakeJsonPaint(writer, fPaint, urlDataManager);
  1417. }
  1418. BeginDrawPictureCommand::BeginDrawPictureCommand(const SkPicture* picture,
  1419. const SkMatrix* matrix,
  1420. const SkPaint* paint)
  1421. : INHERITED(kBeginDrawPicture_OpType)
  1422. , fPicture(SkRef(picture))
  1423. , fMatrix(matrix)
  1424. , fPaint(paint) {}
  1425. void BeginDrawPictureCommand::execute(SkCanvas* canvas) const {
  1426. if (fPaint.isValid()) {
  1427. SkRect bounds = fPicture->cullRect();
  1428. if (fMatrix.isValid()) {
  1429. fMatrix->mapRect(&bounds);
  1430. }
  1431. canvas->saveLayer(&bounds, fPaint.get());
  1432. }
  1433. if (fMatrix.isValid()) {
  1434. if (!fPaint.isValid()) {
  1435. canvas->save();
  1436. }
  1437. canvas->concat(*fMatrix);
  1438. }
  1439. }
  1440. bool BeginDrawPictureCommand::render(SkCanvas* canvas) const {
  1441. canvas->clear(0xFFFFFFFF);
  1442. canvas->save();
  1443. xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
  1444. canvas->drawPicture(fPicture.get());
  1445. canvas->restore();
  1446. return true;
  1447. }
  1448. EndDrawPictureCommand::EndDrawPictureCommand(bool restore)
  1449. : INHERITED(kEndDrawPicture_OpType), fRestore(restore) {}
  1450. void EndDrawPictureCommand::execute(SkCanvas* canvas) const {
  1451. if (fRestore) {
  1452. canvas->restore();
  1453. }
  1454. }
  1455. DrawPointsCommand::DrawPointsCommand(SkCanvas::PointMode mode,
  1456. size_t count,
  1457. const SkPoint pts[],
  1458. const SkPaint& paint)
  1459. : INHERITED(kDrawPoints_OpType), fMode(mode), fPts(pts, count), fPaint(paint) {}
  1460. void DrawPointsCommand::execute(SkCanvas* canvas) const {
  1461. canvas->drawPoints(fMode, fPts.count(), fPts.begin(), fPaint);
  1462. }
  1463. bool DrawPointsCommand::render(SkCanvas* canvas) const {
  1464. canvas->clear(0xFFFFFFFF);
  1465. canvas->save();
  1466. SkRect bounds;
  1467. bounds.setEmpty();
  1468. for (int i = 0; i < fPts.count(); ++i) {
  1469. SkRectPriv::GrowToInclude(&bounds, fPts[i]);
  1470. }
  1471. xlate_and_scale_to_bounds(canvas, bounds);
  1472. SkPaint p;
  1473. p.setColor(SK_ColorBLACK);
  1474. p.setStyle(SkPaint::kStroke_Style);
  1475. canvas->drawPoints(fMode, fPts.count(), fPts.begin(), p);
  1476. canvas->restore();
  1477. return true;
  1478. }
  1479. void DrawPointsCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1480. INHERITED::toJSON(writer, urlDataManager);
  1481. writer.appendString(DEBUGCANVAS_ATTRIBUTE_MODE, pointmode_name(fMode));
  1482. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POINTS);
  1483. for (int i = 0; i < fPts.count(); i++) {
  1484. MakeJsonPoint(writer, fPts[i]);
  1485. }
  1486. writer.endArray(); // points
  1487. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1488. MakeJsonPaint(writer, fPaint, urlDataManager);
  1489. }
  1490. DrawTextBlobCommand::DrawTextBlobCommand(sk_sp<SkTextBlob> blob,
  1491. SkScalar x,
  1492. SkScalar y,
  1493. const SkPaint& paint)
  1494. : INHERITED(kDrawTextBlob_OpType)
  1495. , fBlob(std::move(blob))
  1496. , fXPos(x)
  1497. , fYPos(y)
  1498. , fPaint(paint) {}
  1499. void DrawTextBlobCommand::execute(SkCanvas* canvas) const {
  1500. canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
  1501. }
  1502. bool DrawTextBlobCommand::render(SkCanvas* canvas) const {
  1503. canvas->clear(SK_ColorWHITE);
  1504. canvas->save();
  1505. SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
  1506. xlate_and_scale_to_bounds(canvas, bounds);
  1507. canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
  1508. canvas->restore();
  1509. return true;
  1510. }
  1511. void DrawTextBlobCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1512. INHERITED::toJSON(writer, urlDataManager);
  1513. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_RUNS);
  1514. SkTextBlobRunIterator iter(fBlob.get());
  1515. while (!iter.done()) {
  1516. writer.beginObject(); // run
  1517. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_GLYPHS);
  1518. for (uint32_t i = 0; i < iter.glyphCount(); i++) {
  1519. writer.appendU32(iter.glyphs()[i]);
  1520. }
  1521. writer.endArray(); // glyphs
  1522. if (iter.positioning() != SkTextBlobRunIterator::kDefault_Positioning) {
  1523. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POSITIONS);
  1524. const SkScalar* iterPositions = iter.pos();
  1525. for (uint32_t i = 0; i < iter.glyphCount(); i++) {
  1526. switch (iter.positioning()) {
  1527. case SkTextBlobRunIterator::kFull_Positioning:
  1528. MakeJsonPoint(writer, iterPositions[i * 2], iterPositions[i * 2 + 1]);
  1529. break;
  1530. case SkTextBlobRunIterator::kHorizontal_Positioning:
  1531. writer.appendFloat(iterPositions[i]);
  1532. break;
  1533. case SkTextBlobRunIterator::kDefault_Positioning: break;
  1534. case SkTextBlobRunIterator::kRSXform_Positioning:
  1535. // TODO_RSXFORM_BLOB
  1536. break;
  1537. }
  1538. }
  1539. writer.endArray(); // positions
  1540. }
  1541. writer.appendName(DEBUGCANVAS_ATTRIBUTE_FONT);
  1542. MakeJsonFont(iter.font(), writer, urlDataManager);
  1543. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1544. MakeJsonPoint(writer, iter.offset());
  1545. writer.endObject(); // run
  1546. iter.next();
  1547. }
  1548. writer.endArray(); // runs
  1549. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_X, fXPos);
  1550. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_Y, fYPos);
  1551. SkRect bounds = fBlob->bounds();
  1552. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1553. MakeJsonRect(writer, bounds);
  1554. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1555. MakeJsonPaint(writer, fPaint, urlDataManager);
  1556. SkString desc;
  1557. // make the bounds local by applying the x,y
  1558. bounds.offset(fXPos, fYPos);
  1559. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, bounds)->c_str());
  1560. }
  1561. DrawPatchCommand::DrawPatchCommand(const SkPoint cubics[12],
  1562. const SkColor colors[4],
  1563. const SkPoint texCoords[4],
  1564. SkBlendMode bmode,
  1565. const SkPaint& paint)
  1566. : INHERITED(kDrawPatch_OpType), fBlendMode(bmode) {
  1567. memcpy(fCubics, cubics, sizeof(fCubics));
  1568. if (colors != nullptr) {
  1569. memcpy(fColors, colors, sizeof(fColors));
  1570. fColorsPtr = fColors;
  1571. } else {
  1572. fColorsPtr = nullptr;
  1573. }
  1574. if (texCoords != nullptr) {
  1575. memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
  1576. fTexCoordsPtr = fTexCoords;
  1577. } else {
  1578. fTexCoordsPtr = nullptr;
  1579. }
  1580. fPaint = paint;
  1581. }
  1582. void DrawPatchCommand::execute(SkCanvas* canvas) const {
  1583. canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
  1584. }
  1585. void DrawPatchCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1586. INHERITED::toJSON(writer, urlDataManager);
  1587. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_CUBICS);
  1588. for (int i = 0; i < 12; i++) {
  1589. MakeJsonPoint(writer, fCubics[i]);
  1590. }
  1591. writer.endArray(); // cubics
  1592. if (fColorsPtr != nullptr) {
  1593. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_COLORS);
  1594. for (int i = 0; i < 4; i++) {
  1595. MakeJsonColor(writer, fColorsPtr[i]);
  1596. }
  1597. writer.endArray(); // colors
  1598. }
  1599. if (fTexCoordsPtr != nullptr) {
  1600. writer.beginArray(DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS);
  1601. for (int i = 0; i < 4; i++) {
  1602. MakeJsonPoint(writer, fTexCoords[i]);
  1603. }
  1604. writer.endArray(); // texCoords
  1605. }
  1606. // fBlendMode
  1607. }
  1608. DrawRectCommand::DrawRectCommand(const SkRect& rect, const SkPaint& paint)
  1609. : INHERITED(kDrawRect_OpType) {
  1610. fRect = rect;
  1611. fPaint = paint;
  1612. }
  1613. void DrawRectCommand::execute(SkCanvas* canvas) const { canvas->drawRect(fRect, fPaint); }
  1614. void DrawRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1615. INHERITED::toJSON(writer, urlDataManager);
  1616. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1617. MakeJsonRect(writer, fRect);
  1618. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1619. MakeJsonPaint(writer, fPaint, urlDataManager);
  1620. SkString desc;
  1621. writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
  1622. }
  1623. DrawRRectCommand::DrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
  1624. : INHERITED(kDrawRRect_OpType) {
  1625. fRRect = rrect;
  1626. fPaint = paint;
  1627. }
  1628. void DrawRRectCommand::execute(SkCanvas* canvas) const { canvas->drawRRect(fRRect, fPaint); }
  1629. bool DrawRRectCommand::render(SkCanvas* canvas) const {
  1630. render_rrect(canvas, fRRect);
  1631. return true;
  1632. }
  1633. void DrawRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1634. INHERITED::toJSON(writer, urlDataManager);
  1635. writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
  1636. make_json_rrect(writer, fRRect);
  1637. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1638. MakeJsonPaint(writer, fPaint, urlDataManager);
  1639. }
  1640. DrawDRRectCommand::DrawDRRectCommand(const SkRRect& outer,
  1641. const SkRRect& inner,
  1642. const SkPaint& paint)
  1643. : INHERITED(kDrawDRRect_OpType) {
  1644. fOuter = outer;
  1645. fInner = inner;
  1646. fPaint = paint;
  1647. }
  1648. void DrawDRRectCommand::execute(SkCanvas* canvas) const {
  1649. canvas->drawDRRect(fOuter, fInner, fPaint);
  1650. }
  1651. bool DrawDRRectCommand::render(SkCanvas* canvas) const {
  1652. render_drrect(canvas, fOuter, fInner);
  1653. return true;
  1654. }
  1655. void DrawDRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1656. INHERITED::toJSON(writer, urlDataManager);
  1657. writer.appendName(DEBUGCANVAS_ATTRIBUTE_OUTER);
  1658. make_json_rrect(writer, fOuter);
  1659. writer.appendName(DEBUGCANVAS_ATTRIBUTE_INNER);
  1660. make_json_rrect(writer, fInner);
  1661. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1662. MakeJsonPaint(writer, fPaint, urlDataManager);
  1663. }
  1664. DrawShadowCommand::DrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
  1665. : INHERITED(kDrawShadow_OpType) {
  1666. fPath = path;
  1667. fShadowRec = rec;
  1668. }
  1669. void DrawShadowCommand::execute(SkCanvas* canvas) const {
  1670. canvas->private_draw_shadow_rec(fPath, fShadowRec);
  1671. }
  1672. bool DrawShadowCommand::render(SkCanvas* canvas) const {
  1673. render_shadow(canvas, fPath, fShadowRec);
  1674. return true;
  1675. }
  1676. void DrawShadowCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1677. INHERITED::toJSON(writer, urlDataManager);
  1678. bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
  1679. bool transparentOccluder =
  1680. SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
  1681. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
  1682. MakeJsonPath(writer, fPath);
  1683. writer.appendName(DEBUGCANVAS_ATTRIBUTE_ZPLANE);
  1684. MakeJsonPoint3(writer, fShadowRec.fZPlaneParams);
  1685. writer.appendName(DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION);
  1686. MakeJsonPoint3(writer, fShadowRec.fLightPos);
  1687. writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS, fShadowRec.fLightRadius);
  1688. writer.appendName(DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR);
  1689. MakeJsonColor(writer, fShadowRec.fAmbientColor);
  1690. writer.appendName(DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR);
  1691. MakeJsonColor(writer, fShadowRec.fSpotColor);
  1692. store_bool(writer, DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
  1693. store_bool(writer, DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
  1694. }
  1695. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1696. DrawEdgeAAQuadCommand::DrawEdgeAAQuadCommand(const SkRect& rect,
  1697. const SkPoint clip[],
  1698. SkCanvas::QuadAAFlags aa,
  1699. SkColor color,
  1700. SkBlendMode mode)
  1701. : INHERITED(kDrawEdgeAAQuad_OpType)
  1702. , fRect(rect)
  1703. , fHasClip(clip != nullptr)
  1704. , fAA(aa)
  1705. , fColor(color)
  1706. , fMode(mode) {
  1707. if (clip) {
  1708. for (int i = 0; i < 4; ++i) {
  1709. fClip[i] = clip[i];
  1710. }
  1711. }
  1712. }
  1713. void DrawEdgeAAQuadCommand::execute(SkCanvas* canvas) const {
  1714. canvas->experimental_DrawEdgeAAQuad(fRect, fHasClip ? fClip : nullptr, fAA, fColor, fMode);
  1715. }
  1716. DrawEdgeAAImageSetCommand::DrawEdgeAAImageSetCommand(const SkCanvas::ImageSetEntry set[],
  1717. int count,
  1718. const SkPoint dstClips[],
  1719. const SkMatrix preViewMatrices[],
  1720. const SkPaint* paint,
  1721. SkCanvas::SrcRectConstraint constraint)
  1722. : INHERITED(kDrawEdgeAAImageSet_OpType)
  1723. , fSet(count)
  1724. , fCount(count)
  1725. , fPaint(paint)
  1726. , fConstraint(constraint) {
  1727. int totalDstClipCount, totalMatrixCount;
  1728. SkCanvasPriv::GetDstClipAndMatrixCounts(set, count, &totalDstClipCount, &totalMatrixCount);
  1729. std::copy_n(set, count, fSet.get());
  1730. fDstClips.reset(totalDstClipCount);
  1731. std::copy_n(dstClips, totalDstClipCount, fDstClips.get());
  1732. fPreViewMatrices.reset(totalMatrixCount);
  1733. std::copy_n(preViewMatrices, totalMatrixCount, fPreViewMatrices.get());
  1734. }
  1735. void DrawEdgeAAImageSetCommand::execute(SkCanvas* canvas) const {
  1736. canvas->experimental_DrawEdgeAAImageSet(fSet.get(),
  1737. fCount,
  1738. fDstClips.get(),
  1739. fPreViewMatrices.get(),
  1740. fPaint.getMaybeNull(),
  1741. fConstraint);
  1742. }
  1743. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1744. DrawDrawableCommand::DrawDrawableCommand(SkDrawable* drawable, const SkMatrix* matrix)
  1745. : INHERITED(kDrawDrawable_OpType), fDrawable(SkRef(drawable)), fMatrix(matrix) {}
  1746. void DrawDrawableCommand::execute(SkCanvas* canvas) const {
  1747. canvas->drawDrawable(fDrawable.get(), fMatrix.getMaybeNull());
  1748. }
  1749. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1750. DrawVerticesCommand::DrawVerticesCommand(sk_sp<SkVertices> vertices,
  1751. SkBlendMode bmode,
  1752. const SkPaint& paint)
  1753. : INHERITED(kDrawVertices_OpType)
  1754. , fVertices(std::move(vertices))
  1755. , fBlendMode(bmode)
  1756. , fPaint(paint) {}
  1757. void DrawVerticesCommand::execute(SkCanvas* canvas) const {
  1758. canvas->drawVertices(fVertices, fBlendMode, fPaint);
  1759. }
  1760. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1761. DrawAtlasCommand::DrawAtlasCommand(const SkImage* image,
  1762. const SkRSXform xform[],
  1763. const SkRect tex[],
  1764. const SkColor colors[],
  1765. int count,
  1766. SkBlendMode bmode,
  1767. const SkRect* cull,
  1768. const SkPaint* paint)
  1769. : INHERITED(kDrawAtlas_OpType)
  1770. , fImage(SkRef(image))
  1771. , fXform(xform, count)
  1772. , fTex(tex, count)
  1773. , fColors(colors, colors ? count : 0)
  1774. , fBlendMode(bmode)
  1775. , fCull(cull)
  1776. , fPaint(paint) {}
  1777. void DrawAtlasCommand::execute(SkCanvas* canvas) const {
  1778. canvas->drawAtlas(fImage.get(),
  1779. fXform.begin(),
  1780. fTex.begin(),
  1781. fColors.isEmpty() ? nullptr : fColors.begin(),
  1782. fXform.count(),
  1783. fBlendMode,
  1784. fCull.getMaybeNull(),
  1785. fPaint.getMaybeNull());
  1786. }
  1787. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1788. RestoreCommand::RestoreCommand() : INHERITED(kRestore_OpType) {}
  1789. void RestoreCommand::execute(SkCanvas* canvas) const { canvas->restore(); }
  1790. SaveCommand::SaveCommand() : INHERITED(kSave_OpType) {}
  1791. void SaveCommand::execute(SkCanvas* canvas) const { canvas->save(); }
  1792. SaveLayerCommand::SaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
  1793. : INHERITED(kSaveLayer_OpType)
  1794. , fBounds(rec.fBounds)
  1795. , fPaint(rec.fPaint)
  1796. , fBackdrop(SkSafeRef(rec.fBackdrop))
  1797. , fSaveLayerFlags(rec.fSaveLayerFlags) {}
  1798. void SaveLayerCommand::execute(SkCanvas* canvas) const {
  1799. canvas->saveLayer(
  1800. SkCanvas::SaveLayerRec(fBounds.getMaybeNull(), fPaint.getMaybeNull(), fSaveLayerFlags));
  1801. }
  1802. void SaveLayerCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1803. INHERITED::toJSON(writer, urlDataManager);
  1804. if (fBounds.isValid()) {
  1805. writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
  1806. MakeJsonRect(writer, *fBounds);
  1807. }
  1808. if (fPaint.isValid()) {
  1809. writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
  1810. MakeJsonPaint(writer, *fPaint, urlDataManager);
  1811. }
  1812. if (fBackdrop != nullptr) {
  1813. writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BACKDROP);
  1814. flatten(fBackdrop.get(), writer, urlDataManager);
  1815. writer.endObject(); // backdrop
  1816. }
  1817. if (fSaveLayerFlags != 0) {
  1818. SkDebugf("unsupported: saveLayer flags\n");
  1819. SkASSERT(false);
  1820. }
  1821. }
  1822. SetMatrixCommand::SetMatrixCommand(const SkMatrix& matrix) : INHERITED(kSetMatrix_OpType) {
  1823. fMatrix = matrix;
  1824. }
  1825. void SetMatrixCommand::execute(SkCanvas* canvas) const { canvas->setMatrix(fMatrix); }
  1826. void SetMatrixCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
  1827. INHERITED::toJSON(writer, urlDataManager);
  1828. writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
  1829. MakeJsonMatrix(writer, fMatrix);
  1830. }