SkXPSDevice.cpp revision 74b461961607fa57a150a9282c410ef0cab38764
1b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/* 2b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com * Copyright 2011 Google Inc. 3b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com * 4b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com * Use of this source code is governed by a BSD-style license that can be 5b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com * found in the LICENSE file. 6b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com */ 7b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 8b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#ifndef UNICODE 9b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define UNICODE 10b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#endif 11b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#ifndef _UNICODE 12b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define _UNICODE 13b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#endif 14b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTypes.h" 15b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <ObjBase.h> 16b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <XpsObjectModel.h> 17b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <T2EmbApi.h> 18b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <FontSub.h> 19b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 20b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkColor.h" 21b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkConstexprMath.h" 22b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkData.h" 23b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkDraw.h" 24b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkDrawProcs.h" 25b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkFontHost.h" 26b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkGlyphCache.h" 27b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkHRESULT.h" 28b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkImageEncoder.h" 29b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkIStream.h" 30b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkMaskFilter.h" 31b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkPaint.h" 32b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkPoint.h" 33b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkRasterizer.h" 34b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkShader.h" 35b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkSize.h" 36b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkStream.h" 37b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTDArray.h" 38b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTLazy.h" 39b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTScopedComPtr.h" 40b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkUtils.h" 41b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkXPSDevice.h" 42b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 43b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//Windows defines a FLOAT type, 44b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//make it clear when converting a scalar that this is what is wanted. 45b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define SkScalarToFLOAT(n) SkScalarToFloat(n) 46b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 47b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//Dummy representation of a GUID from create_id. 48b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX" 49b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//Length of GUID representation from create_id, including NULL terminator. 50b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define GUID_ID_LEN SK_ARRAY_COUNT(L_GUID_ID) 51b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 52b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/** 53b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com Formats a GUID and places it into buffer. 54b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com buffer should have space for at least GUID_ID_LEN wide characters. 55b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com The string will always be wchar null terminated. 56b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0 57b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com @return -1 if there was an error, > 0 if success. 58b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com */ 59b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic int format_guid(const GUID& guid, 60b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t* buffer, size_t bufferSize, 61b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t sep = '-') { 62b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(bufferSize >= GUID_ID_LEN); 63b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return swprintf_s(buffer, 64b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bufferSize, 65b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com L"%08lX%c%04X%c%04X%c%02X%02X%c%02X%02X%02X%02X%02X%02X", 66b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data1, 67b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 68b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data2, 69b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 70b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data3, 71b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 72b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[0], 73b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[1], 74b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 75b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[2], 76b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[3], 77b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[4], 78b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[5], 79b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[6], 80b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[7]); 81b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 82b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/** 83b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com Creates a GUID based id and places it into buffer. 84b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com buffer should have space for at least GUID_ID_LEN wide characters. 85b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com The string will always be wchar null terminated. 86b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0 87b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com The string may begin with a digit, 88b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com and so may not be suitable as a bare resource key. 89b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com */ 90b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic HRESULT create_id(wchar_t* buffer, size_t bufferSize, 91b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t sep = '-') { 92b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com GUID guid = {}; 93b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(CoCreateGuid(&guid), "Could not create GUID for id."); 9474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 95b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (format_guid(guid, buffer, bufferSize, sep) == -1) { 96b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(E_UNEXPECTED, "Could not format GUID into id."); 97b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 9874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 99b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 100b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 101b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 102b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic SkBitmap make_fake_bitmap(int width, int height) { 103b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap bitmap; 104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmap.setConfig(SkBitmap::kNo_Config, width, height); 105b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return bitmap; 106b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 107b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 108b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::SkXPSDevice() 109b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com : SkDevice(make_fake_bitmap(10000, 10000)) 110b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com , fCurrentPage(0) { 111b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 113b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::~SkXPSDevice() { 114b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 115b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 116b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::TypefaceUse::TypefaceUse() 117b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com : typefaceId(0xffffffff) 118b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com , fontData(NULL) 119b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com , xpsFont(NULL) 120b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com , glyphsUsed(NULL) { 121b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 122b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 123b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::TypefaceUse::~TypefaceUse() { 124b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //xpsFont owns fontData ref 125b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->xpsFont->Release(); 126b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com delete this->glyphsUsed; 127b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 128b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 129b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::beginPortfolio(SkWStream* outputStream) { 130b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!this->fAutoCo.succeeded()) return false; 13174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 132b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create XPS Factory. 133b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(CoCreateInstance( 134b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSID_XpsOMObjectFactory, 135b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 136b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSCTX_INPROC_SERVER, 137b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IID_PPV_ARGS(&this->fXpsFactory)), 138b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create XPS factory."); 13974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 140b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream), 141b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not convert SkStream to IStream."); 14274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 143b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 144b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 145b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 146b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::beginSheet( 147b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& unitsPerMeter, 148b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& pixelsPerMeter, 149b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkSize& trimSize, 150b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* mediaBox, 151b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* bleedBox, 152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* artBox, 153b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* cropBox) { 154b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ++this->fCurrentPage; 15574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 156b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //For simplicity, just write everything out in geometry units, 157b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //then have a base canvas do the scale to physical units. 158b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize = trimSize; 159b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentUnitsPerMeter = unitsPerMeter; 160b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentPixelsPerMeter = pixelsPerMeter; 16174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 162b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.reset(); 163b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas), 164b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create base canvas."); 16574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 166b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 167b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 168b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 169b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsThumbnail(IXpsOMPage* page, 170b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const unsigned int pageNum, 171b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMImageResource** image) { 172b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMThumbnailGenerator> thumbnailGenerator; 173b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(CoCreateInstance( 174b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSID_XpsOMThumbnailGenerator, 175b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 176b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSCTX_INPROC_SERVER, 177b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IID_PPV_ARGS(&thumbnailGenerator)), 178b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create thumbnail generator."); 17974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 180b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 181b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static const size_t size = SK_MAX( 182b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Documents/1/Metadata/.png") + SK_DIGITS_IN(pageNum), 183b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Metadata/" L_GUID_ID L".png") 184b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ); 185b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 186b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (pageNum > 0) { 187b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Documents/1/Metadata/%u.png", pageNum); 188b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 189b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 190b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(create_id(id, GUID_ID_LEN)); 191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Metadata/%s.png", id); 192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 193b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 194b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create thumbnail part uri."); 19574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 196b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(thumbnailGenerator->GenerateThumbnail(page, 197b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_IMAGE_TYPE_PNG, 198b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_THUMBNAIL_SIZE_LARGE, 199b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 200b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com image), 201b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not generate thumbnail."); 20274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 203b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 204b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 205b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 206b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsPage(const XPS_SIZE& pageSize, 207b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPage** page) { 208b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static const size_t size = SK_ARRAY_COUNT(L"/Documents/1/Pages/.fpage") 209b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com + SK_DIGITS_IN(fCurrentPage); 210b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 211b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Documents/1/Pages/%u.fpage", 212b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentPage); 213b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 214b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 215b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create page part uri."); 21674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 217b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //If the language is unknown, use "und" (XPS Spec 2.3.5.1). 218b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePage(&pageSize, 219b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com L"und", 220b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 221b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com page), 222b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create page."); 22374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 224b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 225b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 226b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 227b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::initXpsDocumentWriter(IXpsOMImageResource* image) { 228b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create package writer. 229b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { 230b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 231b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(L"/FixedDocumentSequence.fdseq", 232b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &partUri), 233b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create document sequence part uri."); 234b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePackageWriterOnStream( 235b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fOutputStream.get(), 236b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TRUE, 237b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_INTERLEAVING_OFF, //XPS_INTERLEAVING_ON, 238b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 239b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 240b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com image, 241b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 242b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 243b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &this->fPackageWriter), 244b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create package writer."); 245b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 24674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 247b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Begin the lone document. 248b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { 249b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 250b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri( 251b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com L"/Documents/1/FixedDocument.fdoc", 252b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &partUri), 253b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create fixed document part uri."); 254b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fPackageWriter->StartNewDocument(partUri.get(), 255b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 256b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 257b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 258b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL), 259b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not start document."); 260b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 26174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 262b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 263b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 264b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 265b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::endSheet() { 266b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS is fixed at 96dpi (XPS Spec 11.1). 267b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static const float xpsDPI = 96.0f; 268b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static const float inchesPerMeter = 10000.0f / 254.0f; 269b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static const float targetUnitsPerMeter = xpsDPI * inchesPerMeter; 270b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const float scaleX = targetUnitsPerMeter 271b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fX); 272b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const float scaleY = targetUnitsPerMeter 273b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fY); 27474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 275b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the scale canvas. 276b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> scaleCanvas; 277b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fXpsFactory->CreateCanvas(&scaleCanvas), 278b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create scale canvas."); 279b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> scaleCanvasVisuals; 280b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(scaleCanvas->GetVisuals(&scaleCanvasVisuals), 281b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get scale canvas visuals."); 28274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 283b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> geomToPhys; 284b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_MATRIX rawGeomToPhys = { scaleX, 0, 0, scaleY, 0, 0, }; 285b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fXpsFactory->CreateMatrixTransform(&rawGeomToPhys, &geomToPhys), 286b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create geometry to physical transform."); 287b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(scaleCanvas->SetTransformLocal(geomToPhys.get()), 288b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on scale canvas."); 28974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 290b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the content canvas to the scale canvas. 291b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(scaleCanvasVisuals->Append(this->fCurrentXpsCanvas.get()), 292b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add base canvas to scale canvas."); 29374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 294b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the page. 295b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SIZE pageSize = { 296b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(this->fCurrentCanvasSize.width()) * scaleX, 297b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(this->fCurrentCanvasSize.height()) * scaleY, 298b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 299b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPage> page; 300b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRB(this->createXpsPage(pageSize, &page)); 30174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 302b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> pageVisuals; 303b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(page->GetVisuals(&pageVisuals), "Could not get page visuals."); 30474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 305b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the scale canvas to the page. 306b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(pageVisuals->Append(scaleCanvas.get()), 307b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add scale canvas to page."); 30874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 309b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the package writer if it hasn't been created yet. 310b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL == this->fPackageWriter.get()) { 311b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageResource> image; 312b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Ignore return, thumbnail is completely optional. 313b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->createXpsThumbnail(page.get(), 0, &image); 31474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 315b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRB(this->initXpsDocumentWriter(image.get())); 316b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 31774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 318b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fPackageWriter->AddPage(page.get(), 319b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &pageSize, 320b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 321b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 322b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 323b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL), 324b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not write the page."); 325b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.reset(); 32674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 327b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 328b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 329b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 330b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic HRESULT subset_typeface(SkXPSDevice::TypefaceUse* current) { 331b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //CreateFontPackage wants unsigned short. 332b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Microsoft, Y U NO stdint.h? 333b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<unsigned short> keepList; 334b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com current->glyphsUsed->exportTo(&keepList); 33574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 336b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //The following are declared with the types required by CreateFontPackage. 337b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned char *puchFontPackageBuffer; 338b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned long pulFontPackageBufferSize; 339b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned long pulBytesWritten; 340b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned long result = CreateFontPackage( 341b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (unsigned char *) current->fontData->getMemoryBase(), 342b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (unsigned long) current->fontData->getLength(), 343b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &puchFontPackageBuffer, 344b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &pulFontPackageBufferSize, 345b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &pulBytesWritten, 346b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST,// | TTFCFP_FLAGS_TTC, 347b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0,//TTC index 348b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TTFCFP_SUBSET, 349b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 350b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 351b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 352b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com keepList.begin(), 353b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com keepList.count(), 354b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_malloc_throw, 355b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_realloc_throw, 356b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_free, 357b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL); 358b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (result != NO_ERROR) { 359b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("CreateFontPackage Error %lu", result)); 360b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return E_UNEXPECTED; 361b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 36274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 363b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMemoryStream* newStream = new SkMemoryStream; 364b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newStream->setMemoryOwned(puchFontPackageBuffer, pulBytesWritten); 365b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> newIStream; 366b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIStream::CreateFromSkStream(newStream, true, &newIStream); 36774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 368b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FONT_EMBEDDING embedding; 369b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->GetEmbeddingOption(&embedding), 370b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get embedding option from font."); 37174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 372b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 373b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->GetPartName(&partUri), 374b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get part uri from font."); 37574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 376b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->SetContent( 377b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newIStream.get(), 378b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com embedding, 379b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get()), 380b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set new stream for subsetted font."); 38174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 382b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 383b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 384b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 385b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::endPortfolio() { 386b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Subset fonts 387b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!this->fTypefaces.empty()) { 388b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDevice::TypefaceUse* current = &this->fTypefaces.front(); 389b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const TypefaceUse* last = &this->fTypefaces.back(); 390b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (; current <= last; ++current) { 391b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Ignore return for now, if it didn't subset, let it be. 392b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com subset_typeface(current); 393b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 394b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 39574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 396b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fPackageWriter->Close(), "Could not close writer."); 39774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 398b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 399b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 400b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 401b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_COLOR xps_color(const SkColor skColor) { 402b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS uses non-pre-multiplied alpha (XPS Spec 11.4). 403b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR xpsColor; 404b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.colorType = XPS_COLOR_TYPE_SRGB; 405b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.alpha = SkColorGetA(skColor); 406b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.red = SkColorGetR(skColor); 407b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.green = SkColorGetG(skColor); 408b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.blue = SkColorGetB(skColor); 40974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 410b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xpsColor; 411b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 412b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 413b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_POINT xps_point(const SkPoint& point) { 414b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT xpsPoint = { 415b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(point.fX), 416b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(point.fY), 417b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 418b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xpsPoint; 419b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 420b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 421b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_POINT xps_point(const SkPoint& point, const SkMatrix& matrix) { 422b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint skTransformedPoint; 423b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix.mapXY(point.fX, point.fY, &skTransformedPoint); 424b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xps_point(skTransformedPoint); 425b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 426b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 427b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_SPREAD_METHOD xps_spread_method(SkShader::TileMode tileMode) { 428b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (tileMode) { 429b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kClamp_TileMode: 430b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_PAD; 431b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kRepeat_TileMode: 432b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_REPEAT; 433b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kMirror_TileMode: 434b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_REFLECT; 435b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 436b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(!"Unknown tile mode."); 437b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 438b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_PAD; 439b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 440b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 441b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic void transform_offsets(SkScalar* stopOffsets, const int numOffsets, 442b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPoint& start, const SkPoint& end, 443b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& transform) { 444b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint startTransformed; 445b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(start.fX, start.fY, &startTransformed); 446b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint endTransformed; 447b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(end.fX, end.fY, &endTransformed); 44874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 449b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Manhattan distance between transformed start and end. 450b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar startToEnd = (endTransformed.fX - startTransformed.fX) 451b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com + (endTransformed.fY - startTransformed.fY); 452b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkScalarNearlyZero(startToEnd)) { 453b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 0; i < numOffsets; ++i) { 454b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stopOffsets[i] = 0; 455b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 456b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 457b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 45874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 459b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 0; i < numOffsets; ++i) { 460b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint stop; 461b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stop.fX = SkScalarMul(end.fX - start.fX, stopOffsets[i]); 462b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stop.fY = SkScalarMul(end.fY - start.fY, stopOffsets[i]); 46374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 464b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint stopTransformed; 465b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(stop.fX, stop.fY, &stopTransformed); 46674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 467b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Manhattan distance between transformed start and stop. 468b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar startToStop = (stopTransformed.fX - startTransformed.fX) 469b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com + (stopTransformed.fY - startTransformed.fY); 470b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Percentage along transformed line. 471b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stopOffsets[i] = SkScalarDiv(startToStop, startToEnd); 472b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 473b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 474b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 475b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsTransform(const SkMatrix& matrix, 476b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform** xpsTransform) { 477b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar affine[6]; 478b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!matrix.asAffine(affine)) { 479b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *xpsTransform = NULL; 480b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_FALSE; 481b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 482b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_MATRIX rawXpsMatrix = { 483b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kAScaleX]), 484b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kASkewY]), 485b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kASkewX]), 486b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kAScaleY]), 487b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kATransX]), 488b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(affine[SkMatrix::kATransY]), 489b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 490b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateMatrixTransform(&rawXpsMatrix, xpsTransform), 491b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create transform."); 49274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 493b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 494b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 495b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 496b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createPath(IXpsOMGeometryFigure* figure, 497b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals, 498b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPath** path) { 499b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> geometry; 500b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&geometry), 501b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create geometry."); 50274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 503b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> figureCollection; 504b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(geometry->GetFigures(&figureCollection), "Could not get figures."); 505b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figureCollection->Append(figure), "Could not add figure."); 50674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 507b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePath(path), "Could not create path."); 508b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*path)->SetGeometryLocal(geometry.get()), "Could not set geometry"); 50974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 510b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(*path), "Could not add path to visuals."); 511b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 512b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 513b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 514b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsSolidColorBrush(const SkColor skColor, 515b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 516b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 517b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR xpsColor = xps_color(skColor); 518b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMSolidColorBrush> solidBrush; 519b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateSolidColorBrush(&xpsColor, NULL, &solidBrush), 520b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create solid color brush."); 521b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(solidBrush->SetOpacity(alpha / 255.0f), "Could not set opacity."); 522b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(solidBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI Fail."); 523b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 524b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 525b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 526b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::sideOfClamp(const SkRect& areaToFill, 527b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const XPS_RECT& imageViewBox, 528b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMImageResource* image, 529b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals) { 530b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 531b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 53274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 533b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> areaToFillPath; 534b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 53574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 536b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageBrush> areaToFillBrush; 537b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageBrush(image, 538b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageViewBox, 539b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageViewBox, 540b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &areaToFillBrush), 541b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create brush for side of clamp."); 542b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 543b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode for side of clamp."); 544b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 545b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set brush for side of clamp"); 54674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 547b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 548b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 549b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 550b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::cornerOfClamp(const SkRect& areaToFill, 551b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor color, 552b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals) { 553b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 554b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 55574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 556b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> areaToFillPath; 557b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 55874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 559b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> areaToFillBrush; 560b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, 0xFF, &areaToFillBrush)); 561b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 562b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set brush for corner of clamp."); 56374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 564b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 565b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 566b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 567b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_N = XPS_TILE_MODE_NONE; 568b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_T = XPS_TILE_MODE_TILE; 569b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_X = XPS_TILE_MODE_FLIPX; 570b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_Y = XPS_TILE_MODE_FLIPY; 571b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_XY = XPS_TILE_MODE_FLIPXY; 572b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 573b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//TODO(bungeman): In the future, should skia add None, 574b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//handle None+Mirror and None+Repeat correctly. 575b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//None is currently an internal hack so masks don't repeat (None+None only). 576b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_TILE_MODE SkToXpsTileMode[SkShader::kTileModeCount+1] 577b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com [SkShader::kTileModeCount+1] = { 578b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Clamp //Repeat //Mirror //None 579b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/*Clamp */ XTM_N, XTM_T, XTM_Y, XTM_N, 580b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/*Repeat*/ XTM_T, XTM_T, XTM_Y, XTM_N, 581b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/*Mirror*/ XTM_X, XTM_X, XTM_XY, XTM_X, 582b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/*None */ XTM_N, XTM_N, XTM_Y, XTM_N, 583b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com}; 584b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 585b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsImageBrush( 586b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkBitmap& bitmap, 587b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 588b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader::TileMode (&xy)[2], 589b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 590b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMTileBrush** xpsBrush) { 591b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDynamicMemoryWStream write; 592b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!SkImageEncoder::EncodeStream(&write, bitmap, 593b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkImageEncoder::kPNG_Type, 100)) { 594b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(E_FAIL, "Unable to encode bitmap as png."); 595b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 596b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMemoryStream* read = new SkMemoryStream; 597b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com read->setData(write.copyToData())->unref(); 598b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> readWrapper; 599b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(SkIStream::CreateFromSkStream(read, true, &readWrapper), 600b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create stream from png data."); 60174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 602b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const size_t size = 603b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Documents/1/Resources/Images/" L_GUID_ID L".png"); 604b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 605b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 606b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(create_id(id, GUID_ID_LEN)); 607b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Documents/1/Resources/Images/%s.png", id); 60874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 609b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> imagePartUri; 610b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &imagePartUri), 611b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image part uri."); 61274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 613b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageResource> imageResource; 614b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageResource( 615b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com readWrapper.get(), 616b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_IMAGE_TYPE_PNG, 617b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imagePartUri.get(), 618b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageResource), 619b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image resource."); 62074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 621b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bitmapRect = { 622b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 623b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), static_cast<FLOAT>(bitmap.height()) 624b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 625b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageBrush> xpsImageBrush; 626b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageBrush(imageResource.get(), 627b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &bitmapRect, &bitmapRect, 628b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsImageBrush), 629b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image brush."); 63074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 631b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode != xy[0] && 632b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode != xy[1]) { 63374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 634b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 635b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set image tile mode"); 636b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetOpacity(alpha / 255.0f), 637b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set image opacity."); 638b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->QueryInterface(xpsBrush), "QI failed."); 639b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 640b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): compute how big this really needs to be. 641b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar BIG = SkIntToScalar(1000); //SK_ScalarMax; 642b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const FLOAT BIG_F = SkScalarToFLOAT(BIG); 643b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar bWidth = SkIntToScalar(bitmap.width()); 644b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar bHeight = SkIntToScalar(bitmap.height()); 64574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 646b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create brush canvas 647b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> brushCanvas; 648b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&brushCanvas), 649b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image brush canvas."); 650b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> brushVisuals; 651b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(brushCanvas->GetVisuals(&brushVisuals), 652b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get image brush canvas visuals collection."); 65374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 654b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create central figure 655b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect bitmapPoints = SkRect::MakeLTRB(0, 0, bWidth, bHeight); 656b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> centralFigure; 657b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(bitmapPoints, FALSE, TRUE, ¢ralFigure)); 65874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 659b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> centralPath; 660b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(centralFigure.get(), 661b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get(), 662b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ¢ralPath)); 663b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 664b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode for image brush central path."); 665b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(centralPath->SetFillBrushLocal(xpsImageBrush.get()), 666b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill brush for image brush central path."); 66774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 668b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add left/right 669b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0]) { 670b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect leftArea = SkRect::MakeLTRB(-BIG, 0, 0, bHeight); 671b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT leftImageViewBox = { 672b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 673b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0, static_cast<FLOAT>(bitmap.height()), 674b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 675b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(leftArea, leftImageViewBox, 676b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 677b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 678b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 679b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect rightArea = SkRect::MakeLTRB(bWidth, 0, BIG, bHeight); 680b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT rightImageViewBox = { 681b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmap.width() - 1.0f, 0.0f, 682b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0f, static_cast<FLOAT>(bitmap.height()), 683b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 684b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(rightArea, rightImageViewBox, 685b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 686b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 687b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 68874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 689b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add top/bottom 690b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[1]) { 691b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect topArea = SkRect::MakeLTRB(0, -BIG, bWidth, 0); 692b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT topImageViewBox = { 693b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 694b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), 1.0, 695b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 696b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(topArea, topImageViewBox, 697b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 698b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 69974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 700b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect bottomArea = SkRect::MakeLTRB(0, bHeight, bWidth, BIG); 701b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bottomImageViewBox = { 702b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0f, bitmap.height() - 1.0f, 703b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), 1.0f, 704b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 705b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(bottomArea, bottomImageViewBox, 706b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 707b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 708b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 70974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 710b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add tl, tr, bl, br 711b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0] && 712b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode == xy[1]) { 71374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 714b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoLockPixels alp(bitmap); 71574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 716b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor tlColor = bitmap.getColor(0,0); 717b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect tlArea = SkRect::MakeLTRB(-BIG, -BIG, 0, 0); 718b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(tlArea, tlColor, brushVisuals.get())); 71974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 720b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor trColor = bitmap.getColor(bitmap.width()-1,0); 721b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect trArea = SkRect::MakeLTRB(bWidth, -BIG, BIG, 0); 722b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(trArea, trColor, brushVisuals.get())); 72374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 724b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor brColor = bitmap.getColor(bitmap.width()-1, 725b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmap.height()-1); 726b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect brArea = SkRect::MakeLTRB(bWidth, bHeight, BIG, BIG); 727b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(brArea, brColor, brushVisuals.get())); 72874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 729b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor blColor = bitmap.getColor(0,bitmap.height()-1); 730b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect blArea = SkRect::MakeLTRB(-BIG, bHeight, 0, BIG); 731b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(blArea, blColor, brushVisuals.get())); 732b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 73374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 734b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create visual brush from canvas 735b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bound = {}; 736b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0] && 737b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode == xy[1]) { 73874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 739b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = BIG_F / -2; 740b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = BIG_F / -2; 741b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = BIG_F; 742b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = BIG_F; 743b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kClamp_TileMode == xy[0]) { 744b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = BIG_F / -2; 745b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = 0.0f; 746b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = BIG_F; 747b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = static_cast<FLOAT>(bitmap.height()); 748b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kClamp_TileMode == xy[1]) { 749b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = 0; 750b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = BIG_F / -2; 751b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = static_cast<FLOAT>(bitmap.width()); 752b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = BIG_F; 753b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 754b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualBrush> clampBrush; 755b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateVisualBrush(&bound, &bound, &clampBrush), 756b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create visual brush for image brush."); 757b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetVisualLocal(brushCanvas.get()), 758b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set canvas on visual brush for image brush."); 759b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 760b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode on visual brush for image brush."); 761b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetOpacity(alpha / 255.0f), 762b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity on visual brush for image brush."); 76374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 764b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->QueryInterface(xpsBrush), "QI failed."); 765b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 76674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 767b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 768b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 769b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsMatrixToUse.get()) { 770b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsBrush)->SetTransformLocal(xpsMatrixToUse.get()), 771b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for image brush."); 772b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 773b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): perspective bitmaps in general. 774b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 77574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 776b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 777b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 778b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 779b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsGradientStop(const SkColor skColor, 780b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar offset, 781b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGradientStop** xpsGradStop) { 782b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR gradStopXpsColor = xps_color(skColor); 783b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGradientStop(&gradStopXpsColor, 784b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 785b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(offset), 786b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGradStop), 787b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create gradient stop."); 788b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 789b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 790b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 791b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsLinearGradient(SkShader::GradientInfo info, 792b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 793b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 794b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform* xpsMatrix, 795b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 796b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint; 797b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT endPoint; 798b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsMatrix) { 799b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com startPoint = xps_point(info.fPoint[0]); 800b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com endPoint = xps_point(info.fPoint[1]); 801b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 802b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform_offsets(info.fColorOffsets, info.fColorCount, 803b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fPoint[0], info.fPoint[1], 804b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix); 805b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com startPoint = xps_point(info.fPoint[0], localMatrix); 806b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com endPoint = xps_point(info.fPoint[1], localMatrix); 807b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 80874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 809b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 810b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[0], 811b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[0], 812b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop0)); 81374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 814b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 815b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[1], 816b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[1], 817b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop1)); 81874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 819b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMLinearGradientBrush> gradientBrush; 820b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateLinearGradientBrush(gradStop0.get(), 821b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradStop1.get(), 822b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &startPoint, 823b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &endPoint, 824b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientBrush), 825b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create linear gradient brush."); 826b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsMatrix) { 827b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetTransformLocal(xpsMatrix), 828b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on linear gradient brush."); 829b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 83074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 831b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 832b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->GetGradientStops(&gradStopCollection), 833b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get linear gradient stop collection."); 834b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 2; i < info.fColorCount; ++i) { 835b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop; 836b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[i], 837b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[i], 838b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop)); 839b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradStopCollection->Append(gradStop.get()), 840b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add linear gradient stop."); 841b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 84274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 843b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 844b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set spread method of linear gradient."); 84574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 846b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetOpacity(alpha / 255.0f), 847b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity of linear gradient brush."); 848b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed"); 84974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 850b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 851b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 852b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 853b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsRadialGradient(SkShader::GradientInfo info, 854b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 855b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 856b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform* xpsMatrix, 857b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 858b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 859b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[0], 860b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[0], 861b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop0)); 86274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 863b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 864b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[1], 865b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[1], 866b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop1)); 86774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 868b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: figure out how to fake better if not affine 869b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT centerPoint; 870b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT gradientOrigin; 871b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SIZE radiiSizes; 872b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsMatrix) { 873b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com centerPoint = xps_point(info.fPoint[0]); 874b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradientOrigin = xps_point(info.fPoint[0]); 875b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.width = SkScalarToFLOAT(info.fRadius[0]); 876b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.height = SkScalarToFLOAT(info.fRadius[0]); 877b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 878b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com centerPoint = xps_point(info.fPoint[0], localMatrix); 879b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradientOrigin = xps_point(info.fPoint[0], localMatrix); 88074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 881b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar radius = info.fRadius[0]; 882b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector vec[2]; 88374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 884b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com vec[0].set(radius, 0); 885b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com vec[1].set(0, radius); 886b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix.mapVectors(vec, 2); 88774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 888b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar d0 = vec[0].length(); 889b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar d1 = vec[1].length(); 89074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 891b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.width = SkScalarToFLOAT(d0); 892b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.height = SkScalarToFLOAT(d1); 893b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 89474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 895b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMRadialGradientBrush> gradientBrush; 896b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateRadialGradientBrush(gradStop0.get(), 897b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradStop1.get(), 898b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ¢erPoint, 899b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientOrigin, 900b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &radiiSizes, 901b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientBrush), 902b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create radial gradient brush."); 903b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsMatrix) { 904b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetTransformLocal(xpsMatrix), 905b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on radial gradient brush."); 906b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 90774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 908b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 909b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->GetGradientStops(&gradStopCollection), 910b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get radial gradient stop collection."); 911b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 2; i < info.fColorCount; ++i) { 912b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop; 913b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[i], 914b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[i], 915b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop)); 916b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradStopCollection->Append(gradStop.get()), 917b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add radial gradient stop."); 918b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 91974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 920b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 921b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set spread method of radial gradient."); 92274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 923b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetOpacity(alpha / 255.0f), 924b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity of radial gradient brush."); 925b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed."); 92674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 927b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 928b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 929b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 930b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint, 931b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** brush, 932b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix* parentTransform) { 933b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader *shader = skPaint.getShader(); 934b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL == shader) { 935b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 936b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 937b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 93874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 939b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Gradient shaders. 940b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::GradientInfo info; 941b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorCount = 0; 942b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColors = NULL; 943b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets = NULL; 944b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::GradientType gradientType = shader->asAGradient(&info); 94574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 946b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kNone_GradientType == gradientType) { 947b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Nothing to see, move along. 94874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 949b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kColor_GradientType == gradientType) { 950b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(1 == info.fColorCount); 951b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkColor color; 952b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColors = &color; 953b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::GradientType gradientType = shader->asAGradient(&info); 954b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAlpha alpha = skPaint.getAlpha(); 955b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, alpha, brush)); 956b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 95774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 958b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 959b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (info.fColorCount == 0) { 960b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor color = skPaint.getColor(); 961b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, 0xFF, brush)); 962b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 963b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 96474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 965b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoTArray<SkColor> colors(info.fColorCount); 966b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoTArray<SkScalar> colorOffsets(info.fColorCount); 967b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColors = colors.get(); 968b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets = colorOffsets.get(); 969b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shader->asAGradient(&info); 97074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 971b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (1 == info.fColorCount) { 972b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkColor color = info.fColors[0]; 973b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAlpha alpha = skPaint.getAlpha(); 974b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, alpha, brush)); 975b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 976b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 97774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 978b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix localMatrix; 979b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shader->getLocalMatrix(&localMatrix); 980b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != parentTransform) { 981b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix.preConcat(*parentTransform); 982b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 983b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 984b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 98574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 986b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kLinear_GradientType == gradientType) { 987b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsLinearGradient(info, 988b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skPaint.getAlpha(), 989b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix, 990b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsMatrixToUse.get(), 991b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brush)); 992b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 993b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 99474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 995b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kRadial_GradientType == gradientType) { 996b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRadialGradient(info, 997b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skPaint.getAlpha(), 998b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix, 999b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsMatrixToUse.get(), 1000b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brush)); 1001b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1002b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 100374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1004b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kRadial2_GradientType == gradientType) { 1005b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //simple if affine and one is 0, otherwise will have to fake 1006b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 100774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1008b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kSweep_GradientType == gradientType) { 1009b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //have to fake 1010b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1011b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 101274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1013b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap outTexture; 1014b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix outMatrix; 1015b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::TileMode xy[2]; 1016b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar twoPointRadialParams[3]; 1017b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::BitmapType bitmapType = shader->asABitmap(&outTexture, 1018b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &outMatrix, 1019b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy, 1020b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com twoPointRadialParams); 1021b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (bitmapType) { 1022b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kNone_BitmapType: 1023b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1024b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kDefault_BitmapType: { 1025b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: outMatrix?? 1026b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix localMatrix; 1027b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shader->getLocalMatrix(&localMatrix); 1028b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != parentTransform) { 1029b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix.preConcat(*parentTransform); 1030b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 103174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1032b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMTileBrush> tileBrush; 1033b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsImageBrush(outTexture, 1034b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix, 1035b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy, 1036b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skPaint.getAlpha(), 1037b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &tileBrush)); 103874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1039b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(tileBrush->QueryInterface<IXpsOMBrush>(brush), "QI failed."); 104074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1041b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1042b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1043b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kRadial_BitmapType: 1044b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kSweep_BitmapType: 1045b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kTwoPointRadial_BitmapType: 1046b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 1047b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1048b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 104974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1050b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 1051b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1052b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1053b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1054b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic bool rect_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 1055b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool zeroWidth = (0 == paint.getStrokeWidth()); 1056b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool stroke = (SkPaint::kFill_Style != paint.getStyle()); 105774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1058b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return paint.getPathEffect() || 1059b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getMaskFilter() || 1060b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getRasterizer() || 1061b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (stroke && ( 1062b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (matrix.hasPerspective() && !zeroWidth) || 1063b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPaint::kMiter_Join != paint.getStrokeJoin() || 1064b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (SkPaint::kMiter_Join == paint.getStrokeJoin() && 1065b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getStrokeMiter() < SK_ScalarSqrt2) 1066b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com )) 1067b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ; 1068b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1069b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1070b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsRect(const SkRect& rect, BOOL stroke, BOOL fill, 1071b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure** xpsRect) { 1072b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPoint points[4] = { 1073b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fLeft, rect.fTop }, 1074b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fRight, rect.fTop }, 1075b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fRight, rect.fBottom }, 1076b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fLeft, rect.fBottom }, 1077b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1078b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return this->createXpsQuad(points, stroke, fill, xpsRect); 1079b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1080b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4], 1081b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, 1082b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure** xpsQuad) { 1083b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the start point. 1084b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint = xps_point(points[0]); 108574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1086b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Create the figure. 1087b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, xpsQuad), 1088b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create quad geometry figure."); 108974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1090b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the type of each segment. 1091b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE segmentTypes[3] = { 1092b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1093b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1094b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1095b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 109674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1097b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the x and y coordinates of each corner of the figure. 1098b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FLOAT segmentData[6] = { 1099b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[1].fX), SkScalarToFLOAT(points[1].fY), 1100b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[2].fX), SkScalarToFLOAT(points[2].fY), 1101b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[3].fX), SkScalarToFLOAT(points[3].fY), 1102b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 110374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Describe if the segments are stroked. 1105b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL segmentStrokes[3] = { 1106b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, stroke, stroke, 1107b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 110874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1109b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the segment data to the figure. 1110b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetSegments( 1111b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 3, 6, 1112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes , segmentData, segmentStrokes), 1113b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add segment data to quad."); 111474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1115b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Set the closed and filled properties of the figure. 1116b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetIsClosed(stroke), "Could not set quad close."); 1117b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetIsFilled(fill), "Could not set quad fill."); 111874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1119b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1120b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1121b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1122982cb875f01e247843b9a79082f680cdcf234c2creed@google.comuint32_t SkXPSDevice::getDeviceCapabilities() { 1123982cb875f01e247843b9a79082f680cdcf234c2creed@google.com return kVector_Capability; 1124982cb875f01e247843b9a79082f680cdcf234c2creed@google.com} 1125982cb875f01e247843b9a79082f680cdcf234c2creed@google.com 1126b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::clear(SkColor color) { 1127b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: override this for XPS 1128b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("XPS clear not yet implemented.")); 1129b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1130b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1131b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode, 1132b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com size_t count, const SkPoint points[], 1133b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1134b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //This will call back into the device to do the drawing. 1135b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com d.drawPoints(mode, count, points, paint, true); 1136b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1137b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1138b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, 1139b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int vertexCount, const SkPoint verts[], 1140b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPoint texs[], const SkColor colors[], 1141b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXfermode* xmode, const uint16_t indices[], 1142b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int indexCount, const SkPaint& paint) { 1143b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: override this for XPS 1144b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("XPS drawVertices not yet implemented.")); 1145b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1146b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1147b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& paint) { 1148b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize); 114974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1150b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //If trying to paint with a stroke, ignore that and fill. 1151b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPaint* fillPaint = const_cast<SkPaint*>(&paint); 1152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTLazy<SkPaint> modifiedPaint; 1153b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paint.getStyle() != SkPaint::kFill_Style) { 1154b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillPaint = modifiedPaint.set(paint); 1155b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillPaint->setStyle(SkPaint::kFill_Style); 1156b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 115774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1158b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->internalDrawRect(d, r, false, *fillPaint); 1159b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1160b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1161b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawRect(const SkDraw& d, 1162b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect& r, 1163b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1164b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->internalDrawRect(d, r, true, paint); 1165b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1166b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1167b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::internalDrawRect(const SkDraw& d, 1168b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect& r, 1169b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool transformRect, 1170b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1171b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Exit early if there is nothing to draw. 1172b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (d.fClip->isEmpty() || 1173b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 1174b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1175b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 117674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1177b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Path the rect if we can't optimize it. 1178b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (rect_must_be_pathed(paint, *d.fMatrix)) { 1179b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath tmp; 1180b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com tmp.addRect(r); 1181b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com tmp.setFillType(SkPath::kWinding_FillType); 1182b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->drawPath(d, tmp, paint, NULL, true); 1183b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1184b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 118574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1186b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded path. 1187b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1188b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1189b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded path for rect."); 119074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded geometry. 1192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1193b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1194b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded geometry for rect."); 119574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1196b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the geometry to the shaded path. 1197b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1198b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set shaded geometry for rect."); 119974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1200b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the brushes. 1201b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL fill = FALSE; 1202b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke = FALSE; 1203b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->shadePath(shadedPath.get(), paint, *d.fMatrix, &fill, &stroke)); 120474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1205b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool xpsTransformsPath = true; 1206b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Transform the geometry. 1207b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (transformRect && xpsTransformsPath) { 1208b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1209b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsTransform(*d.fMatrix, &xpsTransform)); 1210b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1211b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1212b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for rect."); 1213b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1214b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1215b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1216b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 121774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1218b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the figure. 1219b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 1220b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { 1221b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint points[4] = { 1222b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fLeft, r.fTop }, 1223b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fLeft, r.fBottom }, 1224b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fRight, r.fBottom }, 1225b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fRight, r.fTop }, 1226b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1227b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!xpsTransformsPath && transformRect) { 1228b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com d.fMatrix->mapPoints(points, SK_ARRAY_COUNT(points)); 1229b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1230b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsQuad(points, stroke, fill, &rectFigure)); 1231b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 123274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1233b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures of the shaded geometry. 1234b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1235b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1236b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded figures for rect."); 123774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1238b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the figure to the shaded geometry figures. 1239b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(rectFigure.get()), 1240b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add shaded figure for rect."); 124174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1242b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->clip(shadedPath.get(), d)); 124374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1244b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the shaded path to the current visuals. 1245b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1246b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1247b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for rect."); 1248b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1249b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add rect to current visuals."); 1250b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1251b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1252b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic HRESULT close_figure(const SkTDArray<XPS_SEGMENT_TYPE>& segmentTypes, 1253b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkTDArray<BOOL>& segmentStrokes, 1254b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkTDArray<FLOAT>& segmentData, 1255b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, 1256b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure* figure, 1257b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigureCollection* figures) { 1258b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the segment data to the figure. 1259b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetSegments(segmentTypes.count(), segmentData.count(), 1260b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.begin() , segmentData.begin(), 1261b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.begin()), 1262b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set path segments."); 126374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1264b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Set the closed and filled properties of the figure. 1265b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetIsClosed(stroke), "Could not set path closed."); 1266b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetIsFilled(fill), "Could not set path fill."); 126774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1268b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the figure created above to this geometry. 1269b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figures->Append(figure), "Could not add path to geometry."); 1270b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1271b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1272b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1273b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::addXpsPathGeometry( 1274b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigureCollection* xpsFigures, 1275b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, const SkPath& path) { 1276b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<XPS_SEGMENT_TYPE> segmentTypes; 1277b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<BOOL> segmentStrokes; 1278b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<FLOAT> segmentData; 127974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1280b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> xpsFigure; 1281b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath::Iter iter(path, true); 1282b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint points[4]; 1283b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath::Verb verb; 1284b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com while ((verb = iter.next(points)) != SkPath::kDone_Verb) { 1285b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (verb) { 1286b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kMove_Verb: { 1287b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsFigure.get()) { 1288b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1289b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, 1290b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.get() , xpsFigures)); 1291b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.reset(); 1292b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.rewind(); 1293b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.rewind(); 1294b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.rewind(); 1295b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1296b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the start point. 1297b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint = xps_point(points[0]); 1298b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Create the figure. 1299b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, 1300b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFigure), 1301b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create path geometry figure."); 1302b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1303b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1304b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kLine_Verb: 1305b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (iter.isCloseLine()) break; //ignore the line, auto-closed 1306b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_LINE); 1307b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1308b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1309b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1310b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1311b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kQuad_Verb: 1312b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER); 1313b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1314b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1315b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1316b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fX)); 1317b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fY)); 1318b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1319b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kCubic_Verb: 1320b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_BEZIER); 1321b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1322b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1323b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1324b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fX)); 1325b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fY)); 1326b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[3].fX)); 1327b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[3].fY)); 1328b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1329b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kClose_Verb: 1330b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // we ignore these, and just get the whole segment from 1331b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // the corresponding line/quad/cubic verbs 1332b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1333b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 1334b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(!"unexpected verb"); 1335b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1336b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1337b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1338b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsFigure.get()) { 1339b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1340b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, 1341b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.get(), xpsFigures)); 1342b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1343b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1344b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1345b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1346b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::drawInverseWindingPath(const SkDraw& d, 1347b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPath& devicePath, 1348b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPath* shadedPath) { 1349b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect universeRect = SkRect::MakeLTRB(0, 0, 1350b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight); 135174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1352b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const XPS_RECT universeRectXps = { 1353b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0f, 0.0f, 1354b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(this->fCurrentCanvasSize.fWidth), 1355b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(this->fCurrentCanvasSize.fHeight), 1356b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 135774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1358b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the geometry. 1359b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1360b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->GetGeometry(&shadedGeometry), 1361b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded geometry for inverse path."); 136274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1363b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures from the geometry. 1364b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1365b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedGeometry->GetFigures(&shadedFigures), 1366b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded figures for inverse path."); 136774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1368b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedGeometry->SetFillRule(XPS_FILL_RULE_NONZERO), 1369b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set shaded fill rule for inverse path."); 137074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1371b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Take everything drawn so far, and make a shared resource out of it. 1372b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Replace everything drawn so far with 1373b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //inverse canvas 1374b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // old canvas of everything so far 1375b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // world shaded figure, clipped to current clip 1376b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // top canvas of everything so far, clipped to path 1377b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Note: this is not quite right when there is nothing solid in the 1378b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //canvas of everything so far, as the bit on top will allow 1379b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //the world paint to show through. 138074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1381b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create new canvas. 1382b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> newCanvas; 1383b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&newCanvas), 1384b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create inverse canvas."); 138574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1386b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Save the old canvas to a dictionary on the new canvas. 1387b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMDictionary> newDictionary; 1388b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateDictionary(&newDictionary), 1389b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create inverse dictionary."); 1390b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newCanvas->SetDictionaryLocal(newDictionary.get()), 1391b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set inverse dictionary."); 139274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1393b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const size_t size = SK_ARRAY_COUNT(L"ID" L_GUID_ID); 1394b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 1395b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 1396b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(create_id(id, GUID_ID_LEN, '_')); 1397b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"ID%s", id); 1398b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newDictionary->Append(buffer, this->fCurrentXpsCanvas.get()), 1399b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add canvas to inverse dictionary."); 140074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1401b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Start drawing 1402b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> newVisuals; 1403b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newCanvas->GetVisuals(&newVisuals), 1404b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get inverse canvas visuals."); 140574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1406b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw old canvas from dictionary onto new canvas. 1407b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> oldGeometry; 1408b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&oldGeometry), 1409b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create old inverse geometry."); 141074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1411b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> oldFigures; 1412b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(oldGeometry->GetFigures(&oldFigures), 1413b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get old inverse figures."); 141474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1415b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> oldFigure; 1416b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(universeRect, FALSE, TRUE, &oldFigure)); 1417b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(oldFigures->Append(oldFigure.get()), 1418b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add old inverse figure."); 141974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1420b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualBrush> oldBrush; 1421b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps, 1422b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &universeRectXps, 1423b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &oldBrush), 1424b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create old inverse brush."); 142574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1426b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> oldPath; 1427b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePath(&oldPath), 1428b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create old inverse path."); 1429b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(oldPath->SetGeometryLocal(oldGeometry.get()), 1430b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set old inverse geometry."); 1431b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(oldPath->SetFillBrushLocal(oldBrush.get()), 1432b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set old inverse fill brush."); 1433b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //the brush must be parented before setting the lookup. 1434b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newVisuals->Append(oldPath.get()), 1435b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add old inverse path to new canvas visuals."); 1436b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(oldBrush->SetVisualLookup(buffer), 1437b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set old inverse brush visual lookup."); 143874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1439b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw the clip filling shader. 1440b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure; 1441b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure)); 1442b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedFigures->Append(shadedFigure.get()), 1443b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add inverse shaded figure."); 1444b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //the geometry is already set 1445b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clip(shadedPath, d)); 1446b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newVisuals->Append(shadedPath), 1447b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add inverse shaded path to canvas visuals."); 144874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1449b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw the old canvas on top, clipped to the original path. 1450b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> topCanvas; 1451b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&topCanvas), 1452b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create top inverse canvas."); 1453b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Clip the canvas to prevent alpha spill. 1454b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //This is the entire reason this canvas exists. 1455b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clip(topCanvas.get(), d)); 145674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1457b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> topGeometry; 1458b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&topGeometry), 1459b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create top inverse geometry."); 146074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1461b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> topFigures; 1462b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topGeometry->GetFigures(&topFigures), 1463b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get top inverse figures."); 146474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1465b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> topFigure; 1466b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(universeRect, FALSE, TRUE, &topFigure)); 1467b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topFigures->Append(topFigure.get()), 1468b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add old inverse figure."); 146974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1470b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualBrush> topBrush; 1471b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateVisualBrush(&universeRectXps, 1472b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &universeRectXps, 1473b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &topBrush), 1474b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create top inverse brush."); 147574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1476b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> topPath; 1477b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePath(&topPath), 1478b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create top inverse path."); 1479b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topPath->SetGeometryLocal(topGeometry.get()), 1480b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set top inverse geometry."); 1481b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topPath->SetFillBrushLocal(topBrush.get()), 1482b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set top inverse fill brush."); 1483b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //the brush must be parented before setting the lookup. 1484b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(newVisuals->Append(topCanvas.get()), 1485b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add top canvas to inverse canvas visuals."); 1486b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> topVisuals; 1487b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topCanvas->GetVisuals(&topVisuals), 1488b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get top inverse canvas visuals."); 1489b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topVisuals->Append(topPath.get()), 1490b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add top inverse path to top canvas visuals."); 1491b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(topBrush->SetVisualLookup(buffer), 1492b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set top inverse brush visual lookup."); 149374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1494b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clipToPath(topPath.get(), devicePath, XPS_FILL_RULE_NONZERO)); 149574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1496b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //swap current canvas to new canvas 1497b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.swap(newCanvas); 149874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1499b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1500b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1501b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1502b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::convertToPpm(const SkMaskFilter* filter, 1503b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix* matrix, 1504b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector* ppuScale, 1505b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkIRect& clip, SkIRect* clipIRect) { 1506b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: currently ignoring the ppm if blur ignoring transform. 1507b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (filter) { 1508b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMaskFilter::BlurInfo blurInfo; 1509b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMaskFilter::BlurType blurType = filter->asABlur(&blurInfo); 151074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1511b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkMaskFilter::kNone_BlurType != blurType 1512b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com && blurInfo.fIgnoreTransform) { 1513b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1514b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ppuScale->fX = SK_Scalar1; 1515b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ppuScale->fY = SK_Scalar1; 1516b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *clipIRect = clip; 1517b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1518b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1519b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 152074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1521b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //This action is in unit space, but the ppm is specified in physical space. 1522b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ppuScale->fX = SkScalarDiv(this->fCurrentPixelsPerMeter.fX, 1523b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentUnitsPerMeter.fX); 1524b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ppuScale->fY = SkScalarDiv(this->fCurrentPixelsPerMeter.fY, 1525b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentUnitsPerMeter.fY); 152674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1527b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix->postScale(ppuScale->fX, ppuScale->fY); 152874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1529b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkIRect& irect = clip; 1530b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect clipRect = SkRect::MakeLTRB( 1531b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarMul(SkIntToScalar(irect.fLeft), ppuScale->fX), 1532b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarMul(SkIntToScalar(irect.fTop), ppuScale->fY), 1533b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarMul(SkIntToScalar(irect.fRight), ppuScale->fX), 1534b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarMul(SkIntToScalar(irect.fBottom), ppuScale->fY)); 1535b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com clipRect.roundOut(clipIRect); 1536b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1537b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1538b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::applyMask(const SkDraw& d, 1539b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMask& mask, 1540b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& ppuScale, 1541b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPath* shadedPath) { 1542b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the geometry object. 1543b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1544b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->GetGeometry(&shadedGeometry), 1545b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask shaded geometry."); 154674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1547b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures from the geometry. 1548b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1549b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedGeometry->GetFigures(&shadedFigures), 1550b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask shaded figures."); 155174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1552b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix m; 1553b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.reset(); 1554b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.setTranslate(SkIntToScalar(mask.fBounds.fLeft), 1555b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIntToScalar(mask.fBounds.fTop)); 1556b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.postScale(SkScalarInvert(ppuScale.fX), SkScalarInvert(ppuScale.fY)); 155774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1558b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::TileMode xy[2]; 1559b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy[0] = (SkShader::TileMode)3; 1560b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy[1] = (SkShader::TileMode)3; 156174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1562b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap bm; 1563b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bm.setConfig(SkBitmap::kA8_Config, 1564b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask.fBounds.width(), 1565b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask.fBounds.height(), 1566b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask.fRowBytes); 1567b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bm.setPixels(mask.fImage); 156874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1569b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMTileBrush> maskBrush; 1570b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsImageBrush(bm, m, xy, 0xFF, &maskBrush)); 1571b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetOpacityMaskBrushLocal(maskBrush.get()), 1572b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set mask."); 157374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1574b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect universeRect = SkRect::MakeLTRB(0, 0, 1575b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight); 1576b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure; 1577b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure), 1578b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create mask shaded figure."); 1579b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedFigures->Append(shadedFigure.get()), 1580b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add mask shaded figure."); 158174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1582b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clip(shadedPath, d)); 158374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1584b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the path to the active visual collection. 1585b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1586b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1587b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask current visuals."); 1588b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(currentVisuals->Append(shadedPath), 1589b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add masked shaded path to current visuals."); 159074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1591b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1592b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1593b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1594b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath, 1595b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& shaderPaint, 1596b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& matrix, 1597b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL* fill, BOOL* stroke) { 1598b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *fill = FALSE; 1599b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *stroke = FALSE; 160074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1601b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint::Style style = shaderPaint.getStyle(); 1602b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool hasFill = SkPaint::kFill_Style == style 1603b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style; 1604b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool hasStroke = SkPaint::kStroke_Style == style 1605b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style; 160674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1607b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): use dictionaries and lookups. 1608b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (hasFill) { 1609b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *fill = TRUE; 1610b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> fillBrush; 1611b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush(shaderPaint, &fillBrush, &matrix)); 1612b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetFillBrushLocal(fillBrush.get()), 1613b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill for shaded path."); 1614b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 161574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1616b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (hasStroke) { 1617b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *stroke = TRUE; 1618b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> strokeBrush; 1619b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush(shaderPaint, &strokeBrush, &matrix)); 1620b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeBrushLocal(strokeBrush.get()), 1621b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set stroke brush for shaded path."); 1622b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeThickness( 1623b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(shaderPaint.getStrokeWidth())), 1624b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set shaded path stroke thickness."); 162574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1626b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (0 == shaderPaint.getStrokeWidth()) { 1627b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS hair width is a hack. (XPS Spec 11.6.12). 1628b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMDashCollection> dashes; 1629b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->GetStrokeDashes(&dashes), 1630b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set dashes for shaded path."); 1631b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_DASH dash; 1632b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com dash.length = 1.0; 1633b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com dash.gap = 0.0; 1634b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(dashes->Append(&dash), "Could not add dashes to shaded path."); 1635b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeDashOffset(-2.0), 1636b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set dash offset for shaded path."); 1637b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1638b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1639b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1640b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1641b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1642b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawPath(const SkDraw& d, 1643b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPath& platonicPath, 1644b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint, 1645b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix* prePathMatrix, 1646b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool pathIsMutable) { 1647b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // nothing to draw 1648b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (d.fClip->isEmpty() || 1649b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 1650b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1651b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 165274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1653b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath modifiedPath; 1654b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool paintHasPathEffect = paint.getPathEffect() 1655b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || paint.getStyle() != SkPaint::kFill_Style; 165674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1657b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Apply pre-path matrix [Platonic-path -> Skeletal-path]. 1658b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix matrix = *d.fMatrix; 1659b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath); 1660b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (prePathMatrix) { 1661b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paintHasPathEffect || paint.getRasterizer()) { 1662b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!pathIsMutable) { 1663b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skeletalPath = &modifiedPath; 1664b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com pathIsMutable = true; 1665b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1666b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com platonicPath.transform(*prePathMatrix, skeletalPath); 1667b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1668b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!matrix.preConcat(*prePathMatrix)) { 1669b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1670b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1671b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1672b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 167374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1674b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTLazy<SkPaint> modifiedPaint; 1675b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPaint* shaderPaint = const_cast<SkPaint*>(&paint); 167674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1677b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Apply path effect [Skeletal-path -> Fillable-path]. 1678b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* fillablePath = skeletalPath; 1679b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paintHasPathEffect) { 1680b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!pathIsMutable) { 1681b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath = &modifiedPath; 1682b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com pathIsMutable = true; 1683b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1684b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool fill = paint.getFillPath(*skeletalPath, fillablePath); 168574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1686b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shaderPaint = modifiedPaint.set(paint); 1687b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shaderPaint->setPathEffect(NULL); 1688b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (fill) { 1689b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shaderPaint->setStyle(SkPaint::kFill_Style); 1690b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1691b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shaderPaint->setStyle(SkPaint::kStroke_Style); 1692b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shaderPaint->setStrokeWidth(0); 1693b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1694b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 169574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1696b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded path. This will be the path which is painted. 1697b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1698b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1699b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded path for path."); 170074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1701b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the geometry for the shaded path. 1702b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1703b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1704b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded geometry for path."); 170574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1706b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the geometry to the shaded path. 1707b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1708b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add the shaded geometry to shaded path."); 170974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1710b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the brushes. 1711b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL fill; 1712b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke; 1713b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->shadePath(shadedPath.get(), 1714b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *shaderPaint, 1715b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *d.fMatrix, 1716b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &fill, 1717b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &stroke)); 171874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1719b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMaskFilter* filter = paint.getMaskFilter(); 172074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1721b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Rasterizer 1722b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paint.getRasterizer()) { 1723b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIRect clipIRect; 1724b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector ppuScale; 1725b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->convertToPpm(filter, 1726b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &matrix, 1727b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &ppuScale, 1728b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com d.fClip->getBounds(), 1729b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect); 173074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1731b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask* mask = NULL; 173274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1733b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Mask] 1734b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask rasteredMask; 1735b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paint.getRasterizer()->rasterize( 1736b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *fillablePath, 1737b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix, 1738b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect, 1739b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filter, //just to compute how much to draw. 1740b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &rasteredMask, 1741b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask::kComputeBoundsAndRenderImage_CreateMode)) { 174274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1743b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage); 1744b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &rasteredMask; 174574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1746b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Mask -> Mask] 1747b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask filteredMask; 1748b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (filter && 1749b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filter->filterMask(&filteredMask, *mask, *d.fMatrix, NULL)) { 175074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1751b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &filteredMask; 1752b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1753b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filteredMask.fImage = NULL; 1754b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1755b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage filteredAmi(filteredMask.fImage); 175674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1757b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw mask. 1758b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get())); 1759b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1760b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1761b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 176274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1763b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Mask filter 1764b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (filter) { 1765b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIRect clipIRect; 1766b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector ppuScale; 1767b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->convertToPpm(filter, 1768b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &matrix, 1769b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &ppuScale, 1770b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com d.fClip->getBounds(), 1771b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect); 177274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1773b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Pixel-path] 1774b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* pixelPath = pathIsMutable ? fillablePath : &modifiedPath; 1775b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath->transform(matrix, pixelPath); 177674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1777b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask* mask = NULL; 177874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1779b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Pixel-path -> Mask] 1780b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask rasteredMask; 1781b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkDraw::DrawToMask( 1782b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *pixelPath, 1783b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect, 1784b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filter, //just to compute how much to draw. 1785b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &matrix, 1786b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &rasteredMask, 1787b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask::kComputeBoundsAndRenderImage_CreateMode)) { 178874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1789b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage); 1790b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &rasteredMask; 179174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1792b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Mask -> Mask] 1793b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask filteredMask; 1794b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (filter->filterMask(&filteredMask, 1795b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com rasteredMask, 1796b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix, 1797b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL)) { 1798b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &filteredMask; 1799b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1800b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filteredMask.fImage = NULL; 1801b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1802b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage filteredAmi(filteredMask.fImage); 180374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1804b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw mask. 1805b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get())); 1806b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1807b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1808b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 180974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1810b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures from the shaded geometry. 1811b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1812b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1813b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded figures for shaded path."); 181474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1815b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool xpsTransformsPath = true; 181674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1817b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the fill rule. 1818b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FILL_RULE xpsFillRule; 1819b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (platonicPath.getFillType()) { 1820b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kWinding_FillType: 1821b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_NONZERO; 1822b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1823b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kEvenOdd_FillType: 1824b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_EVENODD; 1825b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1826b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kInverseWinding_FillType: { 1827b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Device-path] 1828b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* devicePath = pathIsMutable ? fillablePath : &modifiedPath; 1829b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath->transform(matrix, devicePath); 183074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1831b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->drawInverseWindingPath(d, 1832b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *devicePath, 1833b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shadedPath.get())); 1834b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1835b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1836b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kInverseEvenOdd_FillType: { 1837b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect universe = SkRect::MakeLTRB( 1838b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 0, 1839b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fWidth, 1840b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fHeight); 1841b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure; 1842b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure)); 1843b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(addOneFigure.get()), 1844b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add even-odd flip figure to shaded path."); 1845b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1846b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_EVENODD; 1847b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1848b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1849b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 1850b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(!"Unknown SkPath::FillType."); 1851b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1852b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetFillRule(xpsFillRule), 1853b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill rule for shaded path."); 185474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1855b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the XPS transform, if possible. 1856b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransformsPath) { 1857b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1858b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsTransform(matrix, &xpsTransform)); 185974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1860b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1861b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1862b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on shaded path."); 1863b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1864b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1865b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1866b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 186774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1868b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* devicePath = fillablePath; 1869b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!xpsTransformsPath) { 1870b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Device-path] 1871b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com devicePath = pathIsMutable ? fillablePath : &modifiedPath; 1872b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath->transform(matrix, devicePath); 1873b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1874b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->addXpsPathGeometry(shadedFigures.get(), 1875b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, *devicePath)); 187674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1877b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->clip(shadedPath.get(), d)); 187874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1879b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the path to the active visual collection. 1880b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1881b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1882b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for shaded path."); 1883b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1884b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add shaded path to current visuals."); 1885b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1886b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1887b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) { 1888b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath clipPath; 1889b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAssertResult(d.fClip->getBoundaryPath(&clipPath)); 189074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1891b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD); 1892b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1893b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual, 1894b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPath& clipPath, 1895b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FILL_RULE fillRule) { 1896b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the geometry. 1897b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> clipGeometry; 1898b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&clipGeometry), 1899b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create clip geometry."); 190074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1901b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figure collection of the geometry. 1902b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> clipFigures; 1903b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clipGeometry->GetFigures(&clipFigures), 1904b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get the clip figures."); 190574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1906b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the figures into the geometry. 1907b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->addXpsPathGeometry( 1908b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com clipFigures.get(), 1909b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FALSE, TRUE, clipPath)); 191074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1911b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clipGeometry->SetFillRule(fillRule), 1912b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill rule."); 1913b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsVisual->SetClipGeometryLocal(clipGeometry.get()), 1914b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set clip geometry."); 191574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1916b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1917b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1918b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1919b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap, 1920b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkIRect* srcRectOrNull, 1921b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& matrix, const SkPaint& paint) { 1922b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (d.fClip->isEmpty()) { 1923b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1924b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 192574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1926b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIRect srcRect; 1927b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap tmp; 1928b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkBitmap* bitmapPtr = &bitmap; 1929b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL == srcRectOrNull) { 1930b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com srcRect.set(0, 0, bitmap.width(), bitmap.height()); 1931b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmapPtr = &bitmap; 1932b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1933b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com srcRect = *srcRectOrNull; 1934b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!bitmap.extractSubset(&tmp, srcRect)) { 1935b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; // extraction failed 1936b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1937b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmapPtr = &tmp; 1938b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 193974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1940b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the new shaded path. 1941b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1942b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1943b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create path for bitmap."); 194474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1945b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded geometry. 1946b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1947b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1948b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create geometry for bitmap."); 194974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1950b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the shaded geometry to the shaded path. 1951b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1952b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set the geometry for bitmap."); 195374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1954b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the shaded figures from the shaded geometry. 1955b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1956b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1957b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get the figures for bitmap."); 195874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1959b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix transform = matrix; 1960b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.postConcat(*d.fMatrix); 196174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1962b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1963b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsTransform(transform, &xpsTransform)); 1964b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1965b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1966b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for bitmap."); 1967b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1968b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: perspective that bitmap! 1969b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 197074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1971b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 1972b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsTransform.get()) { 1973b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader::TileMode xy[2] = { 1974b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode, 1975b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode, 1976b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1977b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMTileBrush> xpsImageBrush; 1978b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsImageBrush(*bitmapPtr, 1979b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform, 1980b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy, 1981b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getAlpha(), 1982b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsImageBrush)); 1983b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetFillBrushLocal(xpsImageBrush.get()), 1984b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set bitmap brush."); 198574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1986b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect bitmapRect = SkRect::MakeLTRB(0, 0, 1987b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1988b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsRect(bitmapRect, FALSE, TRUE, &rectFigure)); 1989b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1990b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(rectFigure.get()), 1991b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add bitmap figure."); 199274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1993b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the current visual collection and add the shaded path to it. 1994b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1995b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1996b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for bitmap"); 1997b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1998b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add bitmap to current visuals."); 199974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2000b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->clip(shadedPath.get(), d)); 2001b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2002b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2003b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, 2004b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int x, int y, 2005b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2006b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: override this for XPS 2007b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("XPS drawSprite not yet implemented.")); 2008b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2009b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2010b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint, 2011b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse** typefaceUse) { 2012b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkTypeface* typeface = paint.getTypeface(); 201374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2014b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Check cache. 2015b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkFontID typefaceID = SkTypeface::UniqueID(typeface); 2016b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!this->fTypefaces.empty()) { 2017b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* current = &this->fTypefaces.front(); 2018b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const TypefaceUse* last = &this->fTypefaces.back(); 2019b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (; current <= last; ++current) { 2020b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (current->typefaceId == typefaceID) { 2021b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *typefaceUse = current; 2022b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 2023b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2024b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2025b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 202674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2027b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: create glyph only fonts 2028b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //and let the host deal with what kind of font we're looking at. 2029b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_RESTRICTED; 203074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2031b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> fontStream; 2032b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkStream* fontData = SkFontHost::OpenStream(typefaceID); 20338cddc8d0ea02b3476fd57668cf9b25ba5b9770d8bungeman@google.com HRM(SkIStream::CreateFromSkStream(fontData, true, &fontStream), 2034b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font stream."); 203574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2036b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const size_t size = 2037b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Resources/Fonts/" L_GUID_ID L".odttf"); 2038b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 2039b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 2040b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(create_id(id, GUID_ID_LEN)); 2041b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Resources/Fonts/%s.odttf", id); 204274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2043b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 2044b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 2045b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font resource part uri."); 204674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2047b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMFontResource> xpsFontResource; 2048b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateFontResource(fontStream.get(), 2049b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com embedding, 2050b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 2051b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FALSE, 2052b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFontResource), 2053b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font resource."); 205474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2055b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse& newTypefaceUse = this->fTypefaces.push_back(); 2056b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.typefaceId = typefaceID; 2057b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.fontData = fontData; 2058b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.xpsFont = xpsFontResource.release(); 205974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2060b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoGlyphCache agc = SkAutoGlyphCache(paint, &SkMatrix::I()); 2061b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkGlyphCache* glyphCache = agc.getCache(); 2062b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned int glyphCount = glyphCache->getGlyphCount(); 2063b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount); 206474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2065b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *typefaceUse = &newTypefaceUse; 2066b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 2067b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2068b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2069b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::AddGlyphs(const SkDraw& d, 2070b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMObjectFactory* xpsFactory, 2071b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMCanvas* canvas, 2072b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMFontResource* font, 2073b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com LPCWSTR text, 2074b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_GLYPH_INDEX* xpsGlyphs, 2075b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com UINT32 xpsGlyphsLen, 2076b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT *origin, 2077b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FLOAT fontSize, 2078b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION sims, 2079b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& transform, 2080b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2081b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGlyphs> glyphs; 2082b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsFactory->CreateGlyphs(font, &glyphs), "Could not create glyphs."); 208374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2084b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS uses affine transformations for everything... 2085b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //...except positioning text. 2086b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool useCanvasForClip; 2087b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if ((transform.getType() & ~SkMatrix::kTranslate_Mask) == 0) { 2088b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com origin->x += SkScalarToFLOAT(transform.getTranslateX()); 2089b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com origin->y += SkScalarToFLOAT(transform.getTranslateY()); 2090b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = false; 2091b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 2092b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 2093b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(transform, &xpsMatrixToUse)); 2094b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsMatrixToUse.get()) { 2095b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetTransformLocal(xpsMatrixToUse.get()), 2096b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform matrix."); 2097b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = true; 2098b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 2099b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(!"Attempt to add glyphs in perspective."); 2100b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = false; 2101b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2102b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 210374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor; 2105b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor."); 210674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2107b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != text) { 2108b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->SetUnicodeString(text), 2109b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set unicode string."); 2110b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 211174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (NULL != xpsGlyphs) { 2113b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->SetGlyphIndices(xpsGlyphsLen, xpsGlyphs), 2114b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set glyphs."); 2115b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 211674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2117b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->ApplyEdits(), "Could not apply glyph edits."); 211874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2119b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> xpsFillBrush; 2120b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush( 2121b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint, 2122b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFillBrush, 2123b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip ? NULL : &transform)); 212474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2125b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetFillBrushLocal(xpsFillBrush.get()), 2126b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill brush."); 212774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2128b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetOrigin(origin), "Could not set glyph origin."); 212974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2130b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetFontRenderingEmSize(fontSize), 2131b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set font size."); 213274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2133b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetStyleSimulations(sims), 2134b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set style simulations."); 213574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2136b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> visuals; 2137b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals."); 213874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2139b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!useCanvasForClip) { 2140b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clip(glyphs.get(), d)); 2141b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas."); 2142b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 2143b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> glyphCanvas; 2144b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&glyphCanvas), 2145b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create glyph canvas."); 214674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2147b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> glyphCanvasVisuals; 2148b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphCanvas->GetVisuals(&glyphCanvasVisuals), 2149b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get glyph visuals collection."); 215074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2151b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphCanvasVisuals->Append(glyphs.get()), 2152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add glyphs to page."); 2153b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->clip(glyphCanvas.get(), d)); 215474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2155b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(glyphCanvas.get()), 2156b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add glyph canvas to page."); 2157b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 215874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2159b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 2160b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2161b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2162b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstruct SkXPSDrawProcs : public SkDrawProcs { 2163b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.compublic: 2164b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com /** [in] Advance width and offsets for glyphs measured in 2165b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com hundredths of the font em size (XPS Spec 5.1.3). */ 2166b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FLOAT centemPerUnit; 2167b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com /** [in,out] The accumulated glyphs used in the current typeface. */ 2168b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitSet* glyphUse; 2169b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com /** [out] The glyphs to draw. */ 2170b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<XPS_GLYPH_INDEX> xpsGlyphs; 2171b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com}; 2172b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2173b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic void xps_draw_1_glyph(const SkDraw1Glyph& state, 2174b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkFixed x, SkFixed y, 2175b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkGlyph& skGlyph) { 2176b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(skGlyph.fWidth > 0 && skGlyph.fHeight > 0); 217774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2178b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDrawProcs* procs = static_cast<SkXPSDrawProcs*>(state.fDraw->fProcs); 21792211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com 21802211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com //Draw pre-adds half the sampling frequency for floor rounding. 21812211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com if (state.fCache->isSubpixel()) { 21822211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com x -= (SK_FixedHalf >> SkGlyph::kSubBits); 21832211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com y -= (SK_FixedHalf >> SkGlyph::kSubBits); 21842211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com } else { 21852211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com x -= SK_FixedHalf; 21862211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com y -= SK_FixedHalf; 21872211b623274e24d0025763cfa855c9eb53d5b900bungeman@google.com } 218874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2189b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_GLYPH_INDEX* xpsGlyph = procs->xpsGlyphs.append(); 2190b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com uint16_t glyphID = skGlyph.getGlyphID(); 2191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs->glyphUse->setBit(glyphID, true); 2192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->index = glyphID; 2193b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (1 == procs->xpsGlyphs.count()) { 2194b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->advanceWidth = 0.0f; 2195b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->horizontalOffset = SkFixedToFloat(x) * procs->centemPerUnit; 2196b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->verticalOffset = SkFixedToFloat(y) * -procs->centemPerUnit; 2197b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 2198b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const XPS_GLYPH_INDEX& first = procs->xpsGlyphs[0]; 2199b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->advanceWidth = 0.0f; 2200b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->horizontalOffset = (SkFixedToFloat(x) * procs->centemPerUnit) 2201b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com - first.horizontalOffset; 2202b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGlyph->verticalOffset = (SkFixedToFloat(y) * -procs->centemPerUnit) 2203b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com - first.verticalOffset; 2204b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2205b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2206b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2207b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic void text_draw_init(const SkPaint& paint, 2208b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const void* text, size_t byteLength, 2209b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitSet& glyphsUsed, 2210b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDraw& myDraw, SkXPSDrawProcs& procs) { 2211b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.fD1GProc = xps_draw_1_glyph; 2212b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int numGlyphGuess; 2213b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (paint.getTextEncoding()) { 2214b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPaint::kUTF8_TextEncoding: 2215b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com numGlyphGuess = SkUTF8_CountUnichars( 2216b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<const char *>(text), 2217b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com byteLength); 2218b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 2219b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPaint::kUTF16_TextEncoding: 2220b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com numGlyphGuess = SkUTF16_CountUnichars( 2221b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<const uint16_t *>(text), 2222b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com byteLength); 2223b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 2224b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPaint::kGlyphID_TextEncoding: 2225b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com numGlyphGuess = byteLength / 2; 2226b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 2227b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 2228b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_DEBUGBREAK(true); 2229b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2230b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs.setReserve(numGlyphGuess); 2231b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.glyphUse = &glyphsUsed; 2232b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); 223374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2234b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com myDraw.fProcs = &procs; 2235b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com myDraw.fMVMatrix = &SkMatrix::I(); 2236b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com myDraw.fExtMatrix = &SkMatrix::I(); 2237b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2238b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2239b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 2240b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint::Style style = paint.getStyle(); 2241b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return matrix.hasPerspective() 2242b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStroke_Style == style 2243b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style 2244b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || paint.getMaskFilter() 2245b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || paint.getRasterizer() 2246b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ; 2247b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2248b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2249b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawText(const SkDraw& d, 2250b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const void* text, size_t byteLen, 2251b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar x, SkScalar y, 2252b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2253b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (byteLen < 1) return; 225474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2255b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (text_must_be_pathed(paint, *d.fMatrix)) { 2256b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath path; 2257b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getTextPath(text, byteLen, x, y, &path); 2258b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->drawPath(d, path, paint, NULL, true); 2259b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: add automation "text" 2260b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 2261b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 226274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2263b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* typeface; 2264b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(CreateTypefaceUse(paint, &typeface)); 226574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2266b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDraw myDraw(d); 2267b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDrawProcs procs; 2268b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs); 226974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2270b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com myDraw.drawText(static_cast<const char*>(text), byteLen, x, y, paint); 2271089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2272089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com // SkDraw may have clipped out the glyphs, so we need to check 2273089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com if (procs.xpsGlyphs.count() == 0) { 2274089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com return; 2275089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com } 2276089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2277b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT origin = { 2278b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit, 2279b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit, 2280b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 2281b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].horizontalOffset = 0.0f; 2282b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].verticalOffset = 0.0f; 228374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2284b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(AddGlyphs(d, 2285b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fXpsFactory.get(), 2286b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.get(), 2287b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com typeface->xpsFont, 2288b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 2289b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(), 2290b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &origin, 2291b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(paint.getTextSize()), 2292b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION_NONE, 2293b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *d.fMatrix, 2294b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint)); 2295b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2296b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2297b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawPosText(const SkDraw& d, 2298b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const void* text, size_t byteLen, 2299b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar pos[], 2300b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar constY, int scalarsPerPos, 2301b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2302b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (byteLen < 1) return; 230374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2304b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (text_must_be_pathed(paint, *d.fMatrix)) { 2305b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath path; 2306b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: make this work, Draw currently does not handle as well. 2307b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //paint.getTextPath(text, byteLength, x, y, &path); 2308b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //this->drawPath(d, path, paint, NULL, true); 2309b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: add automation "text" 2310b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 2311b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 231274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2313b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* typeface; 2314b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(CreateTypefaceUse(paint, &typeface)); 231574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2316b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDraw myDraw(d); 2317b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDrawProcs procs; 2318b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com text_draw_init(paint, text, byteLen, *typeface->glyphsUsed, myDraw, procs); 231974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2320b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com myDraw.drawPosText(static_cast<const char*>(text), byteLen, 2321b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com pos, constY, scalarsPerPos, 2322b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint); 232374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2324089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com // SkDraw may have clipped out the glyphs, so we need to check 2325089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com if (procs.xpsGlyphs.count() == 0) { 2326089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com return; 2327089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com } 2328089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2329b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT origin = { 2330b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].horizontalOffset / procs.centemPerUnit, 2331b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].verticalOffset / -procs.centemPerUnit, 2332b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 2333b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].horizontalOffset = 0.0f; 2334b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs[0].verticalOffset = 0.0f; 233574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2336b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(AddGlyphs(d, 2337b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fXpsFactory.get(), 2338b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.get(), 2339b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com typeface->xpsFont, 2340b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 2341b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com procs.xpsGlyphs.begin(), procs.xpsGlyphs.count(), 2342b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &origin, 2343b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(paint.getTextSize()), 2344b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION_NONE, 2345b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *d.fMatrix, 2346b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint)); 2347b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2348b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2349b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawTextOnPath(const SkDraw& d, const void* text, size_t len, 2350b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPath& path, const SkMatrix* matrix, 2351b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2352b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //This will call back into the device to do the drawing. 2353b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com d.drawTextOnPath((const char*)text, len, path, matrix, paint); 2354b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2355b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2356b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::drawDevice(const SkDraw& d, SkDevice* dev, 2357b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int x, int y, 2358b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint&) { 2359b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDevice* that = static_cast<SkXPSDevice*>(dev); 236074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2361b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 2362b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_MATRIX rawTransform = { 2363b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0f, 2364b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0f, 2365b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0f, 2366b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0f, 2367b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(x), 2368b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(y), 2369b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 2370b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform), 2371b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create layer transform."); 2372b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()), 2373b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set layer transform."); 237474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2375b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the current visual collection and add the layer to it. 2376b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 2377b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 2378b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for layer."); 2379b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(that->fCurrentXpsCanvas.get()), 2380b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add layer to current visuals."); 2381b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2382b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2383982cb875f01e247843b9a79082f680cdcf234c2creed@google.combool SkXPSDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, 2384982cb875f01e247843b9a79082f680cdcf234c2creed@google.com SkCanvas::Config8888) { 2385982cb875f01e247843b9a79082f680cdcf234c2creed@google.com return false; 2386982cb875f01e247843b9a79082f680cdcf234c2creed@google.com} 2387982cb875f01e247843b9a79082f680cdcf234c2creed@google.com 2388b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkDevice* SkXPSDevice::onCreateCompatibleDevice(SkBitmap::Config config, 2389b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int width, int height, 2390b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool isOpaque, 2391b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com Usage usage) { 2392b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkDevice::kGeneral_Usage == usage) { 2393b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com return NULL; 2394b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_CRASH(); 2395b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //To what stream do we write? 2396b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //SkXPSDevice* dev = new SkXPSDevice(this); 2397b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //SkSize s = SkSize::Make(width, height); 2398b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //dev->BeginCanvas(s, s, SkMatrix::I()); 2399b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //return dev; 2400b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 240174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2402b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return new SkXPSDevice(this->fXpsFactory.get()); 2403b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2404b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2405b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::SkXPSDevice(IXpsOMObjectFactory* xpsFactory) 2406b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com : SkDevice(make_fake_bitmap(10000, 10000)) 2407b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com , fCurrentPage(0) { 240874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2409b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(CoCreateInstance( 2410b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSID_XpsOMObjectFactory, 2411b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com NULL, 2412b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com CLSCTX_INPROC_SERVER, 2413b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IID_PPV_ARGS(&this->fXpsFactory)), 2414b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create factory for layer."); 241574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2416b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateCanvas(&this->fCurrentXpsCanvas), 2417b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create canvas for layer."); 2418b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2419b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 2420b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.combool SkXPSDevice::allowImageFilter(SkImageFilter*) { 2421b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com return false; 2422b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com} 2423b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 2424