bool paintSkiaText(GraphicsContext* context, HFONT hfont, int numGlyphs, const WORD* glyphs, const int* advances, const GOFFSET* offsets, const SkPoint* origin) { HDC dc = GetDC(0); HGDIOBJ oldFont = SelectObject(dc, hfont); PlatformContextSkia* platformContext = context->platformContext(); int textMode = platformContext->getTextDrawingMode(); // Filling (if necessary). This is the common case. SkPaint paint; platformContext->setupPaintForFilling(&paint); paint.setFlags(SkPaint::kAntiAlias_Flag); bool didFill = false; if ((textMode & cTextFill) && SkColorGetA(paint.getColor())) { if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs)) return false; didFill = true; } // Stroking on top (if necessary). if ((textMode & cTextStroke) && platformContext->getStrokeStyle() != NoStroke && platformContext->getStrokeThickness() > 0) { paint.reset(); platformContext->setupPaintForStroking(&paint, 0, 0); paint.setFlags(SkPaint::kAntiAlias_Flag); if (didFill) { // If there is a shadow and we filled above, there will already be // a shadow. We don't want to draw it again or it will be too dark // and it will go on top of the fill. // // Note that this isn't strictly correct, since the stroke could be // very thick and the shadow wouldn't account for this. The "right" // thing would be to draw to a new layer and then draw that layer // with a shadow. But this is a lot of extra work for something // that isn't normally an issue. SkSafeUnref(paint.setLooper(0)); } if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint, &glyphs[0], &advances[0], &offsets[0], numGlyphs)) return false; } SelectObject(dc, oldFont); ReleaseDC(0, dc); return true; }
void HelloWorldWindow::drawContents(SkCanvas* canvas) { // Clear background canvas->drawColor(SK_ColorWHITE); SkPaint paint; paint.setColor(SK_ColorRED); // Draw a rectangle with red paint SkRect rect = SkRect::MakeXYWH(10, 10, 128, 128); canvas->drawRect(rect, paint); // Set up a linear gradient and draw a circle { SkPoint linearPoints[] = { {0, 0}, {300, 300} }; SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK}; paint.setShader(SkGradientShader::MakeLinear( linearPoints, linearColors, nullptr, 2, SkShader::kMirror_TileMode)); paint.setFlags(SkPaint::kAntiAlias_Flag); canvas->drawCircle(200, 200, 64, paint); // Detach shader paint.setShader(nullptr); } // Draw a message with a nice black paint. paint.setFlags( SkPaint::kAntiAlias_Flag | SkPaint::kSubpixelText_Flag | // ... avoid waggly text when rotating. SkPaint::kUnderlineText_Flag); paint.setColor(SK_ColorBLACK); paint.setTextSize(20); canvas->save(); static const char message[] = "Hello World"; // Translate and rotate canvas->translate(300, 300); fRotationAngle += 0.2f; if (fRotationAngle > 360) { fRotationAngle -= 360; } canvas->rotate(fRotationAngle); // Draw the text: canvas->drawText(message, strlen(message), 0, 0, paint); canvas->restore(); }
SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) { // TODO: we could potentially track invals which don't require rebuilding the blob. SkPaint font; font.setFlags(fFlags); font.setTypeface(fTypeface); font.setTextSize(fSize); font.setTextScaleX(fScaleX); font.setTextSkewX(fSkewX); font.setTextAlign(fAlign); font.setHinting(fHinting); // First, convert to glyphIDs. font.setTextEncoding(SkPaint::kUTF8_TextEncoding); SkSTArray<256, SkGlyphID, true> glyphs; glyphs.reset(font.textToGlyphs(fText.c_str(), fText.size(), nullptr)); SkAssertResult(font.textToGlyphs(fText.c_str(), fText.size(), glyphs.begin()) == glyphs.count()); font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); // Next, build the cached blob. SkTextBlobBuilder builder; const auto& buf = builder.allocRun(font, glyphs.count(), 0, 0, nullptr); if (!buf.glyphs) { fBlob.reset(); return SkRect::MakeEmpty(); } memcpy(buf.glyphs, glyphs.begin(), glyphs.count() * sizeof(SkGlyphID)); fBlob = builder.make(); return fBlob ? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y()) : SkRect::MakeEmpty(); }
virtual void onDrawContent(SkCanvas* canvas) { const char* str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; SkPaint paint; SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); paint.setFlags(0x105); paint.setARGB(fByte, 0xFF, 0xFF, 0xFF); paint.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3), SkBlurMaskFilter::kNormal_BlurStyle)); paint.getMaskFilter()->unref(); SkRandom rand; for (int ps = 6; ps <= 35; ps++) { paint.setColor(rand.nextU() | (0xFF << 24)); paint.setTextSize(SkIntToScalar(ps)); paint.setTextSize(SkIntToScalar(24)); canvas->drawText(str, strlen(str), x, y, paint); y += paint.getFontMetrics(NULL); } if (false) { // avoid bit rot, suppress warning check_for_nonwhite(canvas->getDevice()->accessBitmap(false), fByte); SkDebugf("------ byte %x\n", fByte); } if (false) { fByte += 1; fByte &= 0xFF; this->inval(NULL); } }
static void drawmarshmallow(SkCanvas* canvas) { SkBitmap bitmap; SkPaint paint; SkRect r; SkMatrix m; SkImageDecoder::DecodeFile("/Users/reed/Downloads/3elfs.jpg", &bitmap); if (!bitmap.pixelRef()) { return; } SkShader* s = SkShader::CreateBitmapShader(bitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); paint.setShader(s)->unref(); m.setTranslate(SkIntToScalar(250), SkIntToScalar(134)); s->setLocalMatrix(m); r.set(SkIntToScalar(250), SkIntToScalar(134), SkIntToScalar(250 + 449), SkIntToScalar(134 + 701)); paint.setFlags(2); canvas->drawRect(r, paint); }
void GrStencilAndCoverTextContext::uncachedDrawTextBlob(GrContext* context, GrDrawContext* dc, const GrClip& clip, const SkPaint& skPaint, const SkMatrix& viewMatrix, const SkSurfaceProps& props, const SkTextBlob* blob, SkScalar x, SkScalar y, SkDrawFilter* drawFilter, const SkIRect& clipBounds) { SkPaint runPaint = skPaint; SkTextBlobRunIterator it(blob); for (;!it.done(); it.next()) { size_t textLen = it.glyphCount() * sizeof(uint16_t); const SkPoint& offset = it.offset(); // applyFontToPaint() always overwrites the exact same attributes, // so it is safe to not re-seed the paint for this reason. it.applyFontToPaint(&runPaint); if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) { // A false return from filter() means we should abort the current draw. runPaint = skPaint; continue; } runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint)); GrPaint grPaint; if (!SkPaintToGrPaint(context, dc, runPaint, viewMatrix, &grPaint)) { return; } switch (it.positioning()) { case SkTextBlob::kDefault_Positioning: this->drawText(context, dc, clip, grPaint, runPaint, viewMatrix, props, (const char *)it.glyphs(), textLen, x + offset.x(), y + offset.y(), clipBounds); break; case SkTextBlob::kHorizontal_Positioning: this->drawPosText(context, dc, clip, grPaint, runPaint, viewMatrix, props, (const char*)it.glyphs(), textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), clipBounds); break; case SkTextBlob::kFull_Positioning: this->drawPosText(context, dc, clip, grPaint, runPaint, viewMatrix, props, (const char*)it.glyphs(), textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds); break; } if (drawFilter) { // A draw filter may change the paint arbitrarily, so we must re-seed in this case. runPaint = skPaint; } } }
void LinkHighlight::paintContents(WebCanvas* canvas, const WebRect&, WebContentLayerClient::PaintingControlSetting paintingControl) { if (!m_node || !m_node->layoutObject()) return; SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb()); canvas->drawPath(m_path.skPath(), paint); }
static void make_textstrip(SkBitmap* bm) { bm->setConfig(SkBitmap::kRGB_565_Config, 200, 18); bm->allocPixels(); bm->eraseColor(SK_ColorWHITE); SkCanvas canvas(*bm); SkPaint paint; const char* s = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit"; paint.setFlags(paint.getFlags() | SkPaint::kAntiAlias_Flag | SkPaint::kDevKernText_Flag); paint.setTextSize(SkIntToScalar(14)); canvas.drawText(s, strlen(s), SkIntToScalar(8), SkIntToScalar(14), paint); }
static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState* state) { size_t offset = reader->offset(); size_t stop = offset + PaintOp_unpackData(op32); SkPaint* p = state->editPaint(); do { uint32_t p32 = reader->readU32(); unsigned op = PaintOp_unpackOp(p32); unsigned data = PaintOp_unpackData(p32); // SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data); switch (op) { case kReset_PaintOp: p->reset(); break; case kFlags_PaintOp: p->setFlags(data); break; case kColor_PaintOp: p->setColor(reader->readU32()); break; case kFilterLevel_PaintOp: p->setFilterQuality((SkFilterQuality)data); break; case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break; case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break; case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break; case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break; case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break; case kEncoding_PaintOp: p->setTextEncoding((SkPaint::TextEncoding)data); break; case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break; case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break; case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break; case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break; case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break; case kFlatIndex_PaintOp: { PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32); unsigned index = data; set_paintflat(p, state->getFlat(index), pf); break; } case kTypeface_PaintOp: SkASSERT(SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag)); p->setTypeface(state->getTypeface(data)); break; default: SkDEBUGFAIL("bad paintop"); return; } SkASSERT(reader->offset() <= stop); } while (reader->offset() < stop); }
void LinkHighlightImpl::paintContents(WebDisplayItemList* webDisplayItemList, WebContentLayerClient::PaintingControlSetting paintingControl) { if (!m_node || !m_node->layoutObject()) return; SkPictureRecorder recorder; gfx::Rect visualRect = paintableRegion(); SkCanvas* canvas = recorder.beginRecording(visualRect.width(), visualRect.height()); SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb()); canvas->drawPath(m_path.getSkPath(), paint); webDisplayItemList->appendDrawingItem(WebRect(visualRect.x(), visualRect.y(), visualRect.width(), visualRect.height()), recorder.finishRecordingAsPicture()); }
void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint &paint, SkDrawFilter* drawFilter) { SkPaint runPaint = paint; SkTextBlobRunIterator it(blob); for (;!it.done(); it.next()) { size_t textLen = it.glyphCount() * sizeof(uint16_t); const SkPoint& offset = it.offset(); // applyFontToPaint() always overwrites the exact same attributes, // so it is safe to not re-seed the paint for this reason. it.applyFontToPaint(&runPaint); if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) { // A false return from filter() means we should abort the current draw. runPaint = paint; continue; } runPaint.setFlags(this->filterTextFlags(runPaint)); switch (it.positioning()) { case SkTextBlob::kDefault_Positioning: this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint); break; case SkTextBlob::kHorizontal_Positioning: this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), runPaint); break; case SkTextBlob::kFull_Positioning: this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2, SkPoint::Make(x, y), runPaint); break; default: SkFAIL("unhandled positioning mode"); } if (drawFilter) { // A draw filter may change the paint arbitrarily, so we must re-seed in this case. runPaint = paint; } } }
void LinkHighlightImpl::paintContents(WebDisplayItemList* webDisplayItemList, const WebRect& webClipRect, WebContentLayerClient::PaintingControlSetting paintingControl) { if (!m_node || !m_node->layoutObject()) return; SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(webClipRect.width, webClipRect.height); canvas->translate(-webClipRect.x, -webClipRect.y); SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setColor(m_node->layoutObject()->style()->tapHighlightColor().rgb()); canvas->drawPath(m_path.skPath(), paint); RefPtr<const SkPicture> picture = adoptRef(recorder.endRecording()); // TODO(wkorman): Pass actual visual rect with the drawing item. webDisplayItemList->appendDrawingItem(IntRect(), picture.get()); }
virtual void onDrawContent(SkCanvas* canvas) { SkAutoCanvasRestore restore(canvas, false); { SkRect r; r.set(0, 0, SkIntToScalar(1000), SkIntToScalar(20)); // canvas->saveLayer(&r, NULL, SkCanvas::kHasAlphaLayer_SaveFlag); } SkPaint paint; // const uint16_t glyphs[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 }; int index = fHints % SK_ARRAY_COUNT(gHints); index = 1; // const char* style = gHints[index].fName; // canvas->translate(0, SkIntToScalar(50)); // canvas->drawText(style, strlen(style), SkIntToScalar(20), SkIntToScalar(20), paint); SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromFile("/skimages/samplefont.ttf"))); paint.setAntiAlias(true); paint.setFlags(paint.getFlags() | gHints[index].fFlags); SkRect clip; clip.set(SkIntToScalar(25), SkIntToScalar(34), SkIntToScalar(88), SkIntToScalar(155)); const char* text = "Hamburgefons"; size_t length = strlen(text); SkScalar y = SkIntToScalar(0); for (int i = 9; i <= 24; i++) { paint.setTextSize(SkIntToScalar(i) /*+ (gRand.nextU() & 0xFFFF)*/); for (SkScalar dx = 0; dx <= SkIntToScalar(3)/4; dx += SkIntToScalar(1) /* /4 */) { y += paint.getFontSpacing(); DrawTheText(canvas, text, length, SkIntToScalar(20) + dx, y, paint, fClickX, fMF); } } if (gHints[index].fFlushCache) { // SkGraphics::SetFontCacheUsed(0); } }
void GrAtlasTextBlob::flushRunAsPaths(GrContext* context, GrDrawContext* dc, const SkSurfaceProps& props, const SkTextBlobRunIterator& it, const GrClip& clip, const SkPaint& skPaint, SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y) { SkPaint runPaint = skPaint; size_t textLen = it.glyphCount() * sizeof(uint16_t); const SkPoint& offset = it.offset(); it.applyFontToPaint(&runPaint); if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) { return; } runPaint.setFlags(GrTextUtils::FilterTextFlags(props, runPaint)); switch (it.positioning()) { case SkTextBlob::kDefault_Positioning: GrTextUtils::DrawTextAsPath(context, dc, clip, runPaint, viewMatrix, (const char *)it.glyphs(), textLen, x + offset.x(), y + offset.y(), clipBounds); break; case SkTextBlob::kHorizontal_Positioning: GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), clipBounds); break; case SkTextBlob::kFull_Positioning: GrTextUtils::DrawPosTextAsPath(context, dc, props, clip, runPaint, viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds); break; } }
void onDrawContent(SkCanvas* canvas) override { const char* str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; SkPaint paint; SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); paint.setFlags(0x105); paint.setARGB(fByte, 0xFF, 0xFF, 0xFF); paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)))); paint.getMaskFilter()->unref(); SkRandom rand; for (int ps = 6; ps <= 35; ps++) { paint.setColor(rand.nextU() | (0xFF << 24)); paint.setTextSize(SkIntToScalar(ps)); paint.setTextSize(SkIntToScalar(24)); canvas->drawText(str, strlen(str), x, y, paint); y += paint.getFontMetrics(nullptr); } }
void TestShell::dump() { WebScriptController::flushConsoleMessages(); // Dump the requested representation. WebFrame* frame = m_webView->mainFrame(); if (!frame) return; bool shouldDumpAsText = m_layoutTestController->shouldDumpAsText(); bool shouldDumpAsAudio = m_layoutTestController->shouldDumpAsAudio(); bool shouldGeneratePixelResults = m_layoutTestController->shouldGeneratePixelResults(); bool shouldDumpAsPrinted = m_layoutTestController->isPrinting(); bool dumpedAnything = false; if (shouldDumpAsAudio) { m_printer->handleAudioHeader(); const WebKit::WebArrayBufferView& webArrayBufferView = m_layoutTestController->audioData(); printf("Content-Length: %d\n", webArrayBufferView.byteLength()); if (fwrite(webArrayBufferView.baseAddress(), 1, webArrayBufferView.byteLength(), stdout) != webArrayBufferView.byteLength()) FATAL("Short write to stdout, disk full?\n"); printf("\n"); m_printer->handleTestFooter(true); fflush(stdout); fflush(stderr); return; } if (m_params.dumpTree) { dumpedAnything = true; m_printer->handleTextHeader(); // Text output: the test page can request different types of output // which we handle here. if (!shouldDumpAsText) { // Plain text pages should be dumped as text string mimeType = frame->dataSource()->response().mimeType().utf8(); if (mimeType == "text/plain") { shouldDumpAsText = true; shouldGeneratePixelResults = false; } } if (shouldDumpAsText) { bool recursive = m_layoutTestController->shouldDumpChildFramesAsText(); string dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive); if (fwrite(dataUtf8.c_str(), 1, dataUtf8.size(), stdout) != dataUtf8.size()) FATAL("Short write to stdout, disk full?\n"); } else { WebFrame::RenderAsTextControls renderTextBehavior = WebFrame::RenderAsTextNormal; if (shouldDumpAsPrinted) renderTextBehavior |= WebFrame::RenderAsTextPrinting; if (m_params.debugRenderTree) renderTextBehavior |= WebFrame::RenderAsTextDebug; printf("%s", frame->renderTreeAsText(renderTextBehavior).utf8().data()); bool recursive = m_layoutTestController->shouldDumpChildFrameScrollPositions(); dumpFrameScrollPosition(frame, recursive); } if (m_layoutTestController->shouldDumpBackForwardList()) printf("%s", dumpAllBackForwardLists().c_str()); } if (dumpedAnything && m_params.printSeparators) m_printer->handleTextFooter(); if (m_params.dumpPixels && shouldGeneratePixelResults) { // Image output: we write the image data to the file given on the // command line (for the dump pixels argument), and the MD5 sum to // stdout. dumpedAnything = true; m_webView->layout(); if (m_layoutTestController->testRepaint()) { WebSize viewSize = m_webView->size(); int width = viewSize.width; int height = viewSize.height; if (m_layoutTestController->sweepHorizontally()) { for (WebRect column(0, 0, 1, height); column.x < width; column.x++) m_webViewHost->paintRect(column); } else { for (WebRect line(0, 0, width, 1); line.y < height; line.y++) m_webViewHost->paintRect(line); } } else if (m_layoutTestController->isPrinting()) m_webViewHost->paintPagesWithBoundaries(); else m_webViewHost->paintInvalidatedRegion(); // See if we need to draw the selection bounds rect. Selection bounds // rect is the rect enclosing the (possibly transformed) selection. // The rect should be drawn after everything is laid out and painted. if (m_layoutTestController->shouldDumpSelectionRect()) { // If there is a selection rect - draw a red 1px border enclosing rect WebRect wr = frame->selectionBoundsRect(); if (!wr.isEmpty()) { // Render a red rectangle bounding selection rect SkPaint paint; paint.setColor(0xFFFF0000); // Fully opaque red paint.setStyle(SkPaint::kStroke_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setStrokeWidth(1.0f); SkIRect rect; // Bounding rect rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height); m_webViewHost->canvas()->drawIRect(rect, paint); } } dumpImage(m_webViewHost->canvas()); } m_printer->handleImageFooter(); m_printer->handleTestFooter(dumpedAnything); fflush(stdout); fflush(stderr); }
DEF_TEST(Paint_flattening, reporter) { const SkFilterQuality levels[] = { kNone_SkFilterQuality, kLow_SkFilterQuality, kMedium_SkFilterQuality, kHigh_SkFilterQuality, }; const SkPaint::Hinting hinting[] = { SkPaint::kNo_Hinting, SkPaint::kSlight_Hinting, SkPaint::kNormal_Hinting, SkPaint::kFull_Hinting, }; const SkPaint::Align align[] = { SkPaint::kLeft_Align, SkPaint::kCenter_Align, SkPaint::kRight_Align }; const SkPaint::Cap caps[] = { SkPaint::kButt_Cap, SkPaint::kRound_Cap, SkPaint::kSquare_Cap, }; const SkPaint::Join joins[] = { SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join, }; const SkPaint::TextEncoding encodings[] = { SkPaint::kUTF8_TextEncoding, SkPaint::kUTF16_TextEncoding, SkPaint::kUTF32_TextEncoding, SkPaint::kGlyphID_TextEncoding, }; const SkPaint::Style styles[] = { SkPaint::kFill_Style, SkPaint::kStroke_Style, SkPaint::kStrokeAndFill_Style, }; #define FOR_SETUP(index, array, setter) \ for (size_t index = 0; index < SK_ARRAY_COUNT(array); ++index) { \ paint.setter(array[index]); \ SkPaint paint; paint.setFlags(0x1234); FOR_SETUP(i, levels, setFilterQuality) FOR_SETUP(j, hinting, setHinting) FOR_SETUP(k, align, setTextAlign) FOR_SETUP(l, caps, setStrokeCap) FOR_SETUP(m, joins, setStrokeJoin) FOR_SETUP(n, encodings, setTextEncoding) FOR_SETUP(p, styles, setStyle) SkWriteBuffer writer; paint.flatten(writer); const uint32_t* written = writer.getWriter32()->contiguousArray(); SkReadBuffer reader(written, writer.bytesWritten()); SkPaint paint2; paint2.unflatten(reader); REPORTER_ASSERT(reporter, paint2 == paint); }}}}}}}
static void drawInBitmap(SkBitmap &bitmap) { SkCanvas canvas(bitmap); canvas.clear(SK_ColorWHITE); SkPaint myPaint; myPaint.setAntiAlias(true); myPaint.setColor(SK_ColorBLACK); myPaint.setStrokeWidth(SkIntToScalar(1)); canvas.translate(SkIntToScalar(36), SkIntToScalar(36)); canvas.scale(SkIntToScalar(1), SkIntToScalar(-1)); canvas.scale(SkDoubleToScalar(0.17), SkDoubleToScalar(0.17)); { SkPoint linearPoints[] = { {SkIntToScalar(-58), SkIntToScalar(13)}, {SkIntToScalar(-58+(116/2)), SkIntToScalar(13)} }; SkColor linearColors[] = {SK_ColorBLACK, SK_ColorLTGRAY}; SkShader* shader = SkGradientShader::CreateLinear( linearPoints, linearColors, NULL, 2, SkShader::kMirror_TileMode); SkAutoUnref shader_deleter(shader); myPaint.setShader(shader); myPaint.setFlags(SkPaint::kAntiAlias_Flag); SkRect rect0; rect0.setXYWH(SkIntToScalar(-58), SkIntToScalar(13), SkIntToScalar(116), SkIntToScalar(76)); canvas.drawRect(rect0,myPaint); // Detach shader myPaint.setShader(NULL); } myPaint.setColor(SK_ColorBLACK); myPaint.setStyle(SkPaint::kStrokeAndFill_Style); SkRect rect; rect.setXYWH(SkIntToScalar(-60), SkIntToScalar(75), SkIntToScalar(120), SkIntToScalar(6)); canvas.drawRect(rect, myPaint); SkRect rect1; rect1.setXYWH(SkIntToScalar(-60), SkIntToScalar(61), SkIntToScalar(120), SkIntToScalar(6)); canvas.drawRect(rect1, myPaint); SkRect rect2; rect2.setXYWH(SkIntToScalar(-60), SkIntToScalar(49), SkIntToScalar(120), SkIntToScalar(6)); canvas.drawRect(rect2, myPaint); SkPoint pts0[] = { {-60,11}, {-42,23}, {38,23}, {56,11}, {-60,11} }; myPaint.setColor(SK_ColorBLUE); myPaint.setStyle(SkPaint::kStroke_Style); SkPath path0; path0.addPoly(pts0, 5, true); canvas.drawPath(path0, myPaint); path0.addPoly(pts0, 5, true); myPaint.setColor(SK_ColorWHITE); myPaint.setStyle(SkPaint::kFill_Style); canvas.drawPath(path0, myPaint); myPaint.setColor(SK_ColorBLACK); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawLine(SkIntToScalar(-100), SkIntToScalar(-90), SkIntToScalar(100), SkIntToScalar(-91), myPaint); canvas.drawLine(SkIntToScalar(0), SkIntToScalar(-90), SkIntToScalar(26), SkIntToScalar(-58), myPaint); canvas.drawLine(SkIntToScalar(26), SkIntToScalar(-58), SkIntToScalar(-2), SkIntToScalar(37), myPaint); myPaint.setStyle(SkPaint::kStrokeAndFill_Style); canvas.drawCircle(SkIntToScalar(0), SkIntToScalar(33), SkIntToScalar(4), myPaint); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawCircle(SkDoubleToScalar(0), SkDoubleToScalar(-(129+49)/2), SkIntToScalar(40), myPaint); myPaint.setColor(SK_ColorLTGRAY); myPaint.setStyle(SkPaint::kStrokeAndFill_Style); SkPoint pts[9]; pts[0].set(-60, -50); pts[1].set(-60, 100); pts[2].set( 60, 100); pts[3].set(60, -52); pts[4].set(100, -52); pts[5].set(100, 150); pts[6].set(-100, 150); pts[7].set(-100, -50); pts[8].set(-60, -50); SkPath path; path.addPoly(pts, 9, false); canvas.drawPath(path, myPaint); myPaint.setColor(SK_ColorBLACK); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawPath(path, myPaint); SkRect inrect; inrect.setXYWH(SkIntToScalar(-105), SkIntToScalar(100), SkIntToScalar(15), SkIntToScalar(45)); myPaint.setColor(SK_ColorLTGRAY); myPaint.setStyle(SkPaint::kFill_Style); canvas.drawRect(inrect, myPaint); myPaint.setColor(SK_ColorGRAY); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawRect(inrect, myPaint); SkRect inrect1; inrect1.setXYWH(SkIntToScalar(90), SkIntToScalar(100), SkIntToScalar(15), SkIntToScalar(45)); myPaint.setColor(SK_ColorLTGRAY); myPaint.setStyle(SkPaint::kFill_Style); canvas.drawRect(inrect1, myPaint); myPaint.setColor(SK_ColorGRAY); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawRect(inrect1, myPaint); SkRect inrect2; inrect2.setXYWH(SkIntToScalar(-105), SkIntToScalar(-115), SkIntToScalar(15), SkIntToScalar(45)); myPaint.setColor(SK_ColorLTGRAY); myPaint.setStyle(SkPaint::kFill_Style); canvas.drawRect(inrect2, myPaint); myPaint.setColor(SK_ColorGRAY); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawRect(inrect2, myPaint); SkRect inrect3; inrect3.setXYWH(SkIntToScalar(90), SkIntToScalar(-115), SkIntToScalar(15), SkIntToScalar(45)); myPaint.setColor(SK_ColorLTGRAY); myPaint.setStyle(SkPaint::kFill_Style); canvas.drawRect(inrect3, myPaint); myPaint.setColor(SK_ColorGRAY); myPaint.setStyle(SkPaint::kStroke_Style); canvas.drawRect(inrect3, myPaint); }