Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(897)

Unified Diff: skia/ext/vector_platform_device_emf_win.cc

Issue 900683004: Removed unused code in skia/ext/vector_*. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tue Feb 3 23:09:45 PST 2015 Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « skia/ext/vector_platform_device_emf_win.h ('k') | skia/skia_chrome.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: skia/ext/vector_platform_device_emf_win.cc
diff --git a/skia/ext/vector_platform_device_emf_win.cc b/skia/ext/vector_platform_device_emf_win.cc
deleted file mode 100644
index 90e4a201234e02a4d5625e2e9f8d51ec04fb2c37..0000000000000000000000000000000000000000
--- a/skia/ext/vector_platform_device_emf_win.cc
+++ /dev/null
@@ -1,982 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "skia/ext/vector_platform_device_emf_win.h"
-
-#include <windows.h>
-
-#include "base/logging.h"
-#include "base/strings/string16.h"
-#include "skia/ext/bitmap_platform_device.h"
-#include "skia/ext/skia_utils_win.h"
-#include "third_party/skia/include/core/SkPathEffect.h"
-#include "third_party/skia/include/core/SkTemplates.h"
-#include "third_party/skia/include/core/SkUtils.h"
-#include "third_party/skia/include/ports/SkTypeface_win.h"
-
-namespace skia {
-
-#define CHECK_FOR_NODRAW_ANNOTATION(paint) \
- do { if (paint.isNoDrawAnnotation()) { return; } } while (0)
-
-// static
-SkBaseDevice* VectorPlatformDeviceEmf::CreateDevice(
- int width, int height, bool is_opaque, HANDLE shared_section) {
- if (!is_opaque) {
- // TODO(maruel): http://crbug.com/18382 When restoring a semi-transparent
- // layer, i.e. merging it, we need to rasterize it because GDI doesn't
- // support transparency except for AlphaBlend(). Right now, a
- // BitmapPlatformDevice is created when VectorCanvas think a saveLayers()
- // call is being done. The way to save a layer would be to create an
- // EMF-based VectorDevice and have this device registers the drawing. When
- // playing back the device into a bitmap, do it at the printer's dpi instead
- // of the layout's dpi (which is much lower).
- return BitmapPlatformDevice::Create(width, height, is_opaque,
- shared_section);
- }
-
- // TODO(maruel): http://crbug.com/18383 Look if it would be worth to
- // increase the resolution by ~10x (any worthy factor) to increase the
- // rendering precision (think about printing) while using a relatively
- // low dpi. This happens because we receive float as input but the GDI
- // functions works with integers. The idea is to premultiply the matrix
- // with this factor and multiply each SkScalar that are passed to
- // SkScalarRound(value) as SkScalarRound(value * 10). Safari is already
- // doing the same for text rendering.
- SkASSERT(shared_section);
- SkBaseDevice* device = VectorPlatformDeviceEmf::create(
- reinterpret_cast<HDC>(shared_section), width, height);
- return device;
-}
-
-static void FillBitmapInfoHeader(int width, int height, BITMAPINFOHEADER* hdr) {
- hdr->biSize = sizeof(BITMAPINFOHEADER);
- hdr->biWidth = width;
- hdr->biHeight = -height; // Minus means top-down bitmap.
- hdr->biPlanes = 1;
- hdr->biBitCount = 32;
- hdr->biCompression = BI_RGB; // no compression
- hdr->biSizeImage = 0;
- hdr->biXPelsPerMeter = 1;
- hdr->biYPelsPerMeter = 1;
- hdr->biClrUsed = 0;
- hdr->biClrImportant = 0;
-}
-
-SkBaseDevice* VectorPlatformDeviceEmf::create(HDC dc, int width, int height) {
- InitializeDC(dc);
-
- // Link the SkBitmap to the current selected bitmap in the device context.
- SkBitmap bitmap;
- HGDIOBJ selected_bitmap = GetCurrentObject(dc, OBJ_BITMAP);
- bool succeeded = false;
- if (selected_bitmap != NULL) {
- BITMAP bitmap_data = {0};
- if (GetObject(selected_bitmap, sizeof(BITMAP), &bitmap_data) ==
- sizeof(BITMAP)) {
- // The context has a bitmap attached. Attach our SkBitmap to it.
- // Warning: If the bitmap gets unselected from the HDC,
- // VectorPlatformDeviceEmf has no way to detect this, so the HBITMAP
- // could be released while SkBitmap still has a reference to it. Be
- // cautious.
- if (width == bitmap_data.bmWidth && height == bitmap_data.bmHeight) {
- SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
- succeeded = bitmap.installPixels(info, bitmap_data.bmBits,
- bitmap_data.bmWidthBytes);
- }
- }
- }
-
- if (!succeeded)
- bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
-
- return new VectorPlatformDeviceEmf(dc, bitmap);
-}
-
-VectorPlatformDeviceEmf::VectorPlatformDeviceEmf(HDC dc, const SkBitmap& bitmap)
- : SkBitmapDevice(bitmap),
- hdc_(dc),
- previous_brush_(NULL),
- previous_pen_(NULL) {
- transform_.reset();
- SetPlatformDevice(this, this);
-}
-
-VectorPlatformDeviceEmf::~VectorPlatformDeviceEmf() {
- SkASSERT(previous_brush_ == NULL);
- SkASSERT(previous_pen_ == NULL);
-}
-
-HDC VectorPlatformDeviceEmf::BeginPlatformPaint() {
- return hdc_;
-}
-
-void VectorPlatformDeviceEmf::drawPaint(const SkDraw& draw,
- const SkPaint& paint) {
- // TODO(maruel): Bypass the current transformation matrix.
- SkRect rect;
- rect.fLeft = 0;
- rect.fTop = 0;
- rect.fRight = SkIntToScalar(width() + 1);
- rect.fBottom = SkIntToScalar(height() + 1);
- drawRect(draw, rect, paint);
-}
-
-void VectorPlatformDeviceEmf::drawPoints(const SkDraw& draw,
- SkCanvas::PointMode mode,
- size_t count,
- const SkPoint pts[],
- const SkPaint& paint) {
- if (!count)
- return;
-
- if (mode == SkCanvas::kPoints_PointMode) {
- SkASSERT(false);
- return;
- }
-
- SkPaint tmp_paint(paint);
- tmp_paint.setStyle(SkPaint::kStroke_Style);
-
- // Draw a path instead.
- SkPath path;
- switch (mode) {
- case SkCanvas::kLines_PointMode:
- if (count % 2) {
- SkASSERT(false);
- return;
- }
- for (size_t i = 0; i < count / 2; ++i) {
- path.moveTo(pts[2 * i]);
- path.lineTo(pts[2 * i + 1]);
- }
- break;
- case SkCanvas::kPolygon_PointMode:
- path.moveTo(pts[0]);
- for (size_t i = 1; i < count; ++i) {
- path.lineTo(pts[i]);
- }
- break;
- default:
- SkASSERT(false);
- return;
- }
- // Draw the calculated path.
- drawPath(draw, path, tmp_paint);
-}
-
-void VectorPlatformDeviceEmf::drawRect(const SkDraw& draw,
- const SkRect& rect,
- const SkPaint& paint) {
- CHECK_FOR_NODRAW_ANNOTATION(paint);
- if (paint.getPathEffect()) {
- // Draw a path instead.
- SkPath path_orginal;
- path_orginal.addRect(rect);
-
- // Apply the path effect to the rect.
- SkPath path_modified;
- paint.getFillPath(path_orginal, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- paint_no_effet.setPathEffect(NULL);
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- if (!ApplyPaint(paint)) {
- return;
- }
- HDC dc = BeginPlatformPaint();
- if (!Rectangle(dc, SkScalarRoundToInt(rect.fLeft),
- SkScalarRoundToInt(rect.fTop),
- SkScalarRoundToInt(rect.fRight),
- SkScalarRoundToInt(rect.fBottom))) {
- SkASSERT(false);
- }
- EndPlatformPaint();
- Cleanup();
-}
-
-void VectorPlatformDeviceEmf::drawRRect(const SkDraw& draw, const SkRRect& rr,
- const SkPaint& paint) {
- SkPath path;
- path.addRRect(rr);
- this->drawPath(draw, path, paint, NULL, true);
-}
-
-void VectorPlatformDeviceEmf::drawPath(const SkDraw& draw,
- const SkPath& path,
- const SkPaint& paint,
- const SkMatrix* prePathMatrix,
- bool pathIsMutable) {
- CHECK_FOR_NODRAW_ANNOTATION(paint);
- if (paint.getPathEffect()) {
- // Apply the path effect forehand.
- SkPath path_modified;
- paint.getFillPath(path, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- paint_no_effet.setPathEffect(NULL);
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- if (!ApplyPaint(paint)) {
- return;
- }
- HDC dc = BeginPlatformPaint();
- if (PlatformDevice::LoadPathToDC(dc, path)) {
- switch (paint.getStyle()) {
- case SkPaint::kFill_Style: {
- BOOL res = StrokeAndFillPath(dc);
- SkASSERT(res != 0);
- break;
- }
- case SkPaint::kStroke_Style: {
- BOOL res = StrokePath(dc);
- SkASSERT(res != 0);
- break;
- }
- case SkPaint::kStrokeAndFill_Style: {
- BOOL res = StrokeAndFillPath(dc);
- SkASSERT(res != 0);
- break;
- }
- default:
- SkASSERT(false);
- break;
- }
- }
- EndPlatformPaint();
- Cleanup();
-}
-
-void VectorPlatformDeviceEmf::drawBitmapRect(const SkDraw& draw,
- const SkBitmap& bitmap,
- const SkRect* src,
- const SkRect& dst,
- const SkPaint& paint,
- SkCanvas::DrawBitmapRectFlags flags) {
- SkMatrix matrix;
- SkRect bitmapBounds, tmpSrc, tmpDst;
- SkBitmap tmpBitmap;
-
- bitmapBounds.isetWH(bitmap.width(), bitmap.height());
-
- // Compute matrix from the two rectangles
- if (src) {
- tmpSrc = *src;
- } else {
- tmpSrc = bitmapBounds;
- }
- matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
-
- const SkBitmap* bitmapPtr = &bitmap;
-
- // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
- // needed (if the src was clipped). No check needed if src==null.
- if (src) {
- if (!bitmapBounds.contains(*src)) {
- if (!tmpSrc.intersect(bitmapBounds)) {
- return; // nothing to draw
- }
- // recompute dst, based on the smaller tmpSrc
- matrix.mapRect(&tmpDst, tmpSrc);
- }
-
- // since we may need to clamp to the borders of the src rect within
- // the bitmap, we extract a subset.
- // TODO: make sure this is handled in drawrect and remove it from here.
- SkIRect srcIR;
- tmpSrc.roundOut(&srcIR);
- if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
- return;
- }
- bitmapPtr = &tmpBitmap;
-
- // Since we did an extract, we need to adjust the matrix accordingly
- SkScalar dx = 0, dy = 0;
- if (srcIR.fLeft > 0) {
- dx = SkIntToScalar(srcIR.fLeft);
- }
- if (srcIR.fTop > 0) {
- dy = SkIntToScalar(srcIR.fTop);
- }
- if (dx || dy) {
- matrix.preTranslate(dx, dy);
- }
- }
- this->drawBitmap(draw, *bitmapPtr, matrix, paint);
-}
-
-void VectorPlatformDeviceEmf::drawBitmap(const SkDraw& draw,
- const SkBitmap& bitmap,
- const SkMatrix& matrix,
- const SkPaint& paint) {
- // Load the temporary matrix. This is what will translate, rotate and resize
- // the bitmap.
- SkMatrix actual_transform(transform_);
- actual_transform.preConcat(matrix);
- LoadTransformToDC(hdc_, actual_transform);
-
- InternalDrawBitmap(bitmap, 0, 0, paint);
-
- // Restore the original matrix.
- LoadTransformToDC(hdc_, transform_);
-}
-
-void VectorPlatformDeviceEmf::drawSprite(const SkDraw& draw,
- const SkBitmap& bitmap,
- int x, int y,
- const SkPaint& paint) {
- SkMatrix identity;
- identity.reset();
- LoadTransformToDC(hdc_, identity);
-
- InternalDrawBitmap(bitmap, x, y, paint);
-
- // Restore the original matrix.
- LoadTransformToDC(hdc_, transform_);
-}
-
-/////////////////////////////////////////////////////////////////////////
-
-static bool gdiCanHandleText(const SkPaint& paint) {
- return !paint.getShader() &&
- !paint.getPathEffect() &&
- (SkPaint::kFill_Style == paint.getStyle()) &&
- (255 == paint.getAlpha());
-}
-
-class SkGDIFontSetup {
- public:
- SkGDIFontSetup() :
- fHDC(NULL),
- fNewFont(NULL),
- fSavedFont(NULL),
- fSavedTextColor(0),
- fUseGDI(false) {
- SkDEBUGCODE(fUseGDIHasBeenCalled = false;)
- }
- ~SkGDIFontSetup();
-
- // can only be called once
- bool useGDI(HDC hdc, const SkPaint&);
-
- private:
- HDC fHDC;
- HFONT fNewFont;
- HFONT fSavedFont;
- COLORREF fSavedTextColor;
- bool fUseGDI;
- SkDEBUGCODE(bool fUseGDIHasBeenCalled;)
-};
-
-bool SkGDIFontSetup::useGDI(HDC hdc, const SkPaint& paint) {
- SkASSERT(!fUseGDIHasBeenCalled);
- SkDEBUGCODE(fUseGDIHasBeenCalled = true;)
-
- fUseGDI = gdiCanHandleText(paint);
- if (fUseGDI) {
- fSavedTextColor = GetTextColor(hdc);
- SetTextColor(hdc, skia::SkColorToCOLORREF(paint.getColor()));
-
- LOGFONT lf = {0};
- SkLOGFONTFromTypeface(paint.getTypeface(), &lf);
- lf.lfHeight = -SkScalarRoundToInt(paint.getTextSize());
- fNewFont = CreateFontIndirect(&lf);
- fSavedFont = (HFONT)::SelectObject(hdc, fNewFont);
- fHDC = hdc;
- }
- return fUseGDI;
-}
-
-SkGDIFontSetup::~SkGDIFontSetup() {
- if (fUseGDI) {
- ::SelectObject(fHDC, fSavedFont);
- ::DeleteObject(fNewFont);
- SetTextColor(fHDC, fSavedTextColor);
- }
-}
-
-static SkScalar getAscent(const SkPaint& paint) {
- SkPaint::FontMetrics fm;
- paint.getFontMetrics(&fm);
- return fm.fAscent;
-}
-
-// return the options int for ExtTextOut. Only valid if the paint's text
-// encoding is not UTF8 (in which case ExtTextOut can't be used).
-static UINT getTextOutOptions(const SkPaint& paint) {
- if (SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding()) {
- return ETO_GLYPH_INDEX;
- } else {
- SkASSERT(SkPaint::kUTF16_TextEncoding == paint.getTextEncoding());
- return 0;
- }
-}
-
-static SkiaEnsureTypefaceCharactersAccessible
- g_skia_ensure_typeface_characters_accessible = NULL;
-
-SK_API void SetSkiaEnsureTypefaceCharactersAccessible(
- SkiaEnsureTypefaceCharactersAccessible func) {
- // This function is supposed to be called once in process life time.
- SkASSERT(g_skia_ensure_typeface_characters_accessible == NULL);
- g_skia_ensure_typeface_characters_accessible = func;
-}
-
-void EnsureTypefaceCharactersAccessible(
- const SkTypeface& typeface, const wchar_t* text, unsigned int text_length) {
- LOGFONT lf = {0};
- SkLOGFONTFromTypeface(&typeface, &lf);
- g_skia_ensure_typeface_characters_accessible(lf, text, text_length);
-}
-
-bool EnsureExtTextOut(HDC hdc, int x, int y, UINT options, const RECT * lprect,
- LPCWSTR text, unsigned int characters, const int * lpDx,
- SkTypeface* const typeface) {
- bool success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx);
- if (!success) {
- if (typeface) {
- EnsureTypefaceCharactersAccessible(*typeface,
- text,
- characters);
- success = ExtTextOut(hdc, x, y, options, lprect, text, characters, lpDx);
- if (!success) {
- LOGFONT lf = {0};
- SkLOGFONTFromTypeface(typeface, &lf);
- VLOG(1) << "SkFontHost::EnsureTypefaceCharactersAccessible FAILED for "
- << " FaceName = " << lf.lfFaceName
- << " and characters: " << base::string16(text, characters);
- }
- } else {
- VLOG(1) << "ExtTextOut FAILED for default FaceName "
- << " and characters: " << base::string16(text, characters);
- }
- }
- return success;
-}
-
-void VectorPlatformDeviceEmf::drawText(const SkDraw& draw,
- const void* text,
- size_t byteLength,
- SkScalar x,
- SkScalar y,
- const SkPaint& paint) {
- SkGDIFontSetup setup;
- bool useDrawPath = true;
-
- if (SkPaint::kUTF8_TextEncoding != paint.getTextEncoding()
- && setup.useGDI(hdc_, paint)) {
- UINT options = getTextOutOptions(paint);
- UINT count = byteLength >> 1;
- useDrawPath = !EnsureExtTextOut(hdc_, SkScalarRoundToInt(x),
- SkScalarRoundToInt(y + getAscent(paint)), options, 0,
- reinterpret_cast<const wchar_t*>(text), count, NULL,
- paint.getTypeface());
- }
-
- if (useDrawPath) {
- SkPath path;
- paint.getTextPath(text, byteLength, x, y, &path);
- drawPath(draw, path, paint);
- }
-}
-
-static size_t size_utf8(const char* text) {
- return SkUTF8_CountUTF8Bytes(text);
-}
-
-static size_t size_utf16(const char* text) {
- uint16_t c = *reinterpret_cast<const uint16_t*>(text);
- return SkUTF16_IsHighSurrogate(c) ? 4 : 2;
-}
-
-static size_t size_glyphid(const char* text) {
- return 2;
-}
-
-void VectorPlatformDeviceEmf::drawPosText(const SkDraw& draw,
- const void* text,
- size_t len,
- const SkScalar pos[],
- int scalarsPerPos,
- const SkPoint& offset,
- const SkPaint& paint) {
- SkGDIFontSetup setup;
- bool useDrawText = true;
-
- if (scalarsPerPos == 2 && len >= 2 &&
- SkPaint::kUTF8_TextEncoding != paint.getTextEncoding() &&
- setup.useGDI(hdc_, paint)) {
- int startX = SkScalarRoundToInt(pos[0] + offset.x());
- int startY = SkScalarRoundToInt(pos[1] + offset.y() + getAscent(paint));
- const int count = len >> 1;
- SkAutoSTMalloc<64, INT> storage(count);
- INT* advances = storage.get();
- for (int i = 0; i < count - 1; ++i) {
- advances[i] = SkScalarRoundToInt(pos[2] - pos[0]);
- pos += 2;
- }
- advances[count - 1] = 0;
- useDrawText = !EnsureExtTextOut(hdc_, startX, startY,
- getTextOutOptions(paint), 0, reinterpret_cast<const wchar_t*>(text),
- count, advances, paint.getTypeface());
- }
-
- if (useDrawText) {
- size_t (*bytesPerCodePoint)(const char*);
- switch (paint.getTextEncoding()) {
- case SkPaint::kUTF8_TextEncoding:
- bytesPerCodePoint = size_utf8;
- break;
- case SkPaint::kUTF16_TextEncoding:
- bytesPerCodePoint = size_utf16;
- break;
- default:
- SkASSERT(SkPaint::kGlyphID_TextEncoding == paint.getTextEncoding());
- bytesPerCodePoint = size_glyphid;
- break;
- }
-
- const char* curr = reinterpret_cast<const char*>(text);
- const char* stop = curr + len;
- while (curr < stop) {
- SkScalar x = offset.x() + pos[0];
- SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[1] : 0);
-
- size_t bytes = bytesPerCodePoint(curr);
- drawText(draw, curr, bytes, x, y, paint);
- curr += bytes;
- pos += scalarsPerPos;
- }
- }
-}
-
-void VectorPlatformDeviceEmf::drawTextOnPath(const SkDraw& draw,
- const void* text,
- size_t len,
- const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- SkASSERT(false);
-}
-
-void VectorPlatformDeviceEmf::drawVertices(const SkDraw& draw,
- SkCanvas::VertexMode vmode,
- int vertexCount,
- const SkPoint vertices[],
- const SkPoint texs[],
- const SkColor colors[],
- SkXfermode* xmode,
- const uint16_t indices[],
- int indexCount,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- SkASSERT(false);
-}
-
-void VectorPlatformDeviceEmf::drawDevice(const SkDraw& draw,
- SkBaseDevice* device,
- int x,
- int y,
- const SkPaint& paint) {
- // TODO(maruel): http://b/1183870 Playback the EMF buffer at printer's dpi if
- // it is a vectorial device.
- drawSprite(draw, device->accessBitmap(false), x, y, paint);
-}
-
-bool VectorPlatformDeviceEmf::ApplyPaint(const SkPaint& paint) {
- // Note: The goal here is to transfert the SkPaint's state to the HDC's state.
- // This function does not execute the SkPaint drawing commands. These should
- // be executed in drawPaint().
-
- SkPaint::Style style = paint.getStyle();
- if (!paint.getAlpha())
- style = (SkPaint::Style) SkPaint::kStyleCount;
-
- switch (style) {
- case SkPaint::kFill_Style:
- if (!CreateBrush(true, paint) ||
- !CreatePen(false, paint))
- return false;
- break;
- case SkPaint::kStroke_Style:
- if (!CreateBrush(false, paint) ||
- !CreatePen(true, paint))
- return false;
- break;
- case SkPaint::kStrokeAndFill_Style:
- if (!CreateBrush(true, paint) ||
- !CreatePen(true, paint))
- return false;
- break;
- default:
- if (!CreateBrush(false, paint) ||
- !CreatePen(false, paint))
- return false;
- break;
- }
-
- /*
- getFlags();
- isAntiAlias();
- isDither()
- isLinearText()
- isSubpixelText()
- isUnderlineText()
- isStrikeThruText()
- isFakeBoldText()
- isDevKernText()
- isFilterBitmap()
-
- // Skia's text is not used. This should be fixed.
- getTextAlign()
- getTextScaleX()
- getTextSkewX()
- getTextEncoding()
- getFontMetrics()
- getFontSpacing()
- */
-
- // BUG 1094907: Implement shaders. Shaders currently in use:
- // SkShader::CreateBitmapShader
- // SkGradientShader::CreateRadial
- // SkGradientShader::CreateLinear
- // SkASSERT(!paint.getShader());
-
- // http://b/1106647 Implement loopers and mask filter. Looper currently in
- // use:
- // SkBlurDrawLooper is used for shadows.
- // SkASSERT(!paint.getLooper());
- // SkASSERT(!paint.getMaskFilter());
-
- // http://b/1165900 Implement xfermode.
- // SkASSERT(!paint.getXfermode());
-
- // The path effect should be processed before arriving here.
- SkASSERT(!paint.getPathEffect());
-
- // This isn't used in the code. Verify this assumption.
- SkASSERT(!paint.getRasterizer());
- // Reuse code to load Win32 Fonts.
- return true;
-}
-
-void VectorPlatformDeviceEmf::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region,
- const SkClipStack&) {
- transform_ = transform;
- LoadTransformToDC(hdc_, transform_);
- clip_region_ = region;
- if (!clip_region_.isEmpty())
- LoadClipRegion();
-}
-
-void VectorPlatformDeviceEmf::LoadClipRegion() {
- SkMatrix t;
- t.reset();
- LoadClippingRegionToDC(hdc_, clip_region_, t);
-}
-
-SkBaseDevice* VectorPlatformDeviceEmf::onCreateCompatibleDevice(
- const CreateInfo& info) {
- SkASSERT(info.fInfo.colorType() == kN32_SkColorType);
- return VectorPlatformDeviceEmf::CreateDevice(
- info.fInfo.width(), info.fInfo.height(), info.fInfo.isOpaque(), NULL);
-}
-
-bool VectorPlatformDeviceEmf::CreateBrush(bool use_brush, COLORREF color) {
- SkASSERT(previous_brush_ == NULL);
- // We can't use SetDCBrushColor() or DC_BRUSH when drawing to a EMF buffer.
- // SetDCBrushColor() calls are not recorded at all and DC_BRUSH will use
- // WHITE_BRUSH instead.
-
- if (!use_brush) {
- // Set the transparency.
- if (0 == SetBkMode(hdc_, TRANSPARENT)) {
- SkASSERT(false);
- return false;
- }
-
- // Select the NULL brush.
- previous_brush_ = SelectObject(GetStockObject(NULL_BRUSH));
- return previous_brush_ != NULL;
- }
-
- // Set the opacity.
- if (0 == SetBkMode(hdc_, OPAQUE)) {
- SkASSERT(false);
- return false;
- }
-
- // Create and select the brush.
- previous_brush_ = SelectObject(CreateSolidBrush(color));
- return previous_brush_ != NULL;
-}
-
-bool VectorPlatformDeviceEmf::CreatePen(bool use_pen,
- COLORREF color,
- int stroke_width,
- float stroke_miter,
- DWORD pen_style) {
- SkASSERT(previous_pen_ == NULL);
- // We can't use SetDCPenColor() or DC_PEN when drawing to a EMF buffer.
- // SetDCPenColor() calls are not recorded at all and DC_PEN will use BLACK_PEN
- // instead.
-
- // No pen case
- if (!use_pen) {
- previous_pen_ = SelectObject(GetStockObject(NULL_PEN));
- return previous_pen_ != NULL;
- }
-
- // Use the stock pen if the stroke width is 0.
- if (stroke_width == 0) {
- // Create a pen with the right color.
- previous_pen_ = SelectObject(::CreatePen(PS_SOLID, 0, color));
- return previous_pen_ != NULL;
- }
-
- // Load a custom pen.
- LOGBRUSH brush = {0};
- brush.lbStyle = BS_SOLID;
- brush.lbColor = color;
- brush.lbHatch = 0;
- HPEN pen = ExtCreatePen(pen_style, stroke_width, &brush, 0, NULL);
- SkASSERT(pen != NULL);
- previous_pen_ = SelectObject(pen);
- if (previous_pen_ == NULL)
- return false;
-
- if (!SetMiterLimit(hdc_, stroke_miter, NULL)) {
- SkASSERT(false);
- return false;
- }
- return true;
-}
-
-void VectorPlatformDeviceEmf::Cleanup() {
- if (previous_brush_) {
- HGDIOBJ result = SelectObject(previous_brush_);
- previous_brush_ = NULL;
- if (result) {
- BOOL res = DeleteObject(result);
- SkASSERT(res != 0);
- }
- }
- if (previous_pen_) {
- HGDIOBJ result = SelectObject(previous_pen_);
- previous_pen_ = NULL;
- if (result) {
- BOOL res = DeleteObject(result);
- SkASSERT(res != 0);
- }
- }
- // Remove any loaded path from the context.
- AbortPath(hdc_);
-}
-
-HGDIOBJ VectorPlatformDeviceEmf::SelectObject(HGDIOBJ object) {
- HGDIOBJ result = ::SelectObject(hdc_, object);
- SkASSERT(result != HGDI_ERROR);
- if (result == HGDI_ERROR)
- return NULL;
- return result;
-}
-
-bool VectorPlatformDeviceEmf::CreateBrush(bool use_brush,
- const SkPaint& paint) {
- // Make sure that for transparent color, no brush is used.
- if (paint.getAlpha() == 0) {
- use_brush = false;
- }
-
- return CreateBrush(use_brush, SkColorToCOLORREF(paint.getColor()));
-}
-
-bool VectorPlatformDeviceEmf::CreatePen(bool use_pen, const SkPaint& paint) {
- // Make sure that for transparent color, no pen is used.
- if (paint.getAlpha() == 0) {
- use_pen = false;
- }
-
- DWORD pen_style = PS_GEOMETRIC | PS_SOLID;
- switch (paint.getStrokeJoin()) {
- case SkPaint::kMiter_Join:
- // Connects path segments with a sharp join.
- pen_style |= PS_JOIN_MITER;
- break;
- case SkPaint::kRound_Join:
- // Connects path segments with a round join.
- pen_style |= PS_JOIN_ROUND;
- break;
- case SkPaint::kBevel_Join:
- // Connects path segments with a flat bevel join.
- pen_style |= PS_JOIN_BEVEL;
- break;
- default:
- SkASSERT(false);
- break;
- }
- switch (paint.getStrokeCap()) {
- case SkPaint::kButt_Cap:
- // Begin/end contours with no extension.
- pen_style |= PS_ENDCAP_FLAT;
- break;
- case SkPaint::kRound_Cap:
- // Begin/end contours with a semi-circle extension.
- pen_style |= PS_ENDCAP_ROUND;
- break;
- case SkPaint::kSquare_Cap:
- // Begin/end contours with a half square extension.
- pen_style |= PS_ENDCAP_SQUARE;
- break;
- default:
- SkASSERT(false);
- break;
- }
-
- return CreatePen(use_pen,
- SkColorToCOLORREF(paint.getColor()),
- SkScalarRoundToInt(paint.getStrokeWidth()),
- paint.getStrokeMiter(),
- pen_style);
-}
-
-void VectorPlatformDeviceEmf::InternalDrawBitmap(const SkBitmap& bitmap,
- int x, int y,
- const SkPaint& paint) {
- unsigned char alpha = paint.getAlpha();
- if (alpha == 0)
- return;
-
- bool is_translucent;
- if (alpha != 255) {
- // ApplyPaint expect an opaque color.
- SkPaint tmp_paint(paint);
- tmp_paint.setAlpha(255);
- if (!ApplyPaint(tmp_paint))
- return;
- is_translucent = true;
- } else {
- if (!ApplyPaint(paint))
- return;
- is_translucent = false;
- }
- int src_size_x = bitmap.width();
- int src_size_y = bitmap.height();
- if (!src_size_x || !src_size_y)
- return;
-
- // Create a BMP v4 header that we can serialize. We use the shared "V3"
- // fillter to fill the stardard items, then add in the "V4" stuff we want.
- BITMAPV4HEADER bitmap_header = {0};
- FillBitmapInfoHeader(src_size_x, src_size_y,
- reinterpret_cast<BITMAPINFOHEADER*>(&bitmap_header));
- bitmap_header.bV4Size = sizeof(BITMAPV4HEADER);
- bitmap_header.bV4RedMask = 0x00ff0000;
- bitmap_header.bV4GreenMask = 0x0000ff00;
- bitmap_header.bV4BlueMask = 0x000000ff;
- bitmap_header.bV4AlphaMask = 0xff000000;
-
- SkAutoLockPixels lock(bitmap);
- SkASSERT(bitmap.colorType() == kN32_SkColorType);
- const uint32_t* pixels = static_cast<const uint32_t*>(bitmap.getPixels());
- if (pixels == NULL) {
- SkASSERT(false);
- return;
- }
-
- if (!is_translucent) {
- int row_length = bitmap.rowBytesAsPixels();
- // There is no quick way to determine if an image is opaque.
- for (int y2 = 0; y2 < src_size_y; ++y2) {
- for (int x2 = 0; x2 < src_size_x; ++x2) {
- if (SkColorGetA(pixels[(y2 * row_length) + x2]) != 255) {
- is_translucent = true;
- y2 = src_size_y;
- break;
- }
- }
- }
- }
-
- HDC dc = BeginPlatformPaint();
- BITMAPINFOHEADER hdr = {0};
- FillBitmapInfoHeader(src_size_x, src_size_y, &hdr);
- if (is_translucent) {
- // The image must be loaded as a bitmap inside a device context.
- HDC bitmap_dc = ::CreateCompatibleDC(dc);
- void* bits = NULL;
- HBITMAP hbitmap = ::CreateDIBSection(
- bitmap_dc, reinterpret_cast<const BITMAPINFO*>(&hdr),
- DIB_RGB_COLORS, &bits, NULL, 0);
-
- // static cast to a char so we can do byte ptr arithmatic to
- // get the offset.
- unsigned char* dest_buffer = static_cast<unsigned char *>(bits);
-
- // We will copy row by row to avoid having to worry about
- // the row strides being different.
- const int dest_row_size = hdr.biBitCount / 8 * hdr.biWidth;
- for (int row = 0; row < bitmap.height(); ++row) {
- int dest_offset = row * dest_row_size;
- // pixels_offset in terms of pixel count.
- int src_offset = row * bitmap.rowBytesAsPixels();
- memcpy(dest_buffer + dest_offset, pixels + src_offset, dest_row_size);
- }
- SkASSERT(hbitmap);
- HGDIOBJ old_bitmap = ::SelectObject(bitmap_dc, hbitmap);
-
- // After some analysis of IE7's behavior, this is the thing to do. I was
- // sure IE7 was doing so kind of bitmasking due to the way translucent image
- // where renderered but after some windbg tracing, it is being done by the
- // printer driver after all (mostly HP printers). IE7 always use AlphaBlend
- // for bitmasked images. The trick seems to switch the stretching mode in
- // what the driver expects.
- DWORD previous_mode = GetStretchBltMode(dc);
- BOOL result = SetStretchBltMode(dc, COLORONCOLOR);
- SkASSERT(result);
- // Note that this function expect premultiplied colors (!)
- BLENDFUNCTION blend_function = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
- result = GdiAlphaBlend(dc,
- x, y, // Destination origin.
- src_size_x, src_size_y, // Destination size.
- bitmap_dc,
- 0, 0, // Source origin.
- src_size_x, src_size_y, // Source size.
- blend_function);
- SkASSERT(result);
- result = SetStretchBltMode(dc, previous_mode);
- SkASSERT(result);
-
- ::SelectObject(bitmap_dc, static_cast<HBITMAP>(old_bitmap));
- DeleteObject(hbitmap);
- DeleteDC(bitmap_dc);
- } else {
- int nCopied = StretchDIBits(dc,
- x, y, // Destination origin.
- src_size_x, src_size_y,
- 0, 0, // Source origin.
- src_size_x, src_size_y, // Source size.
- pixels,
- reinterpret_cast<const BITMAPINFO*>(&hdr),
- DIB_RGB_COLORS,
- SRCCOPY);
- }
- EndPlatformPaint();
- Cleanup();
-}
-
-} // namespace skia
« no previous file with comments | « skia/ext/vector_platform_device_emf_win.h ('k') | skia/skia_chrome.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698