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 847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary#include "SkTypes.h" 98f11d4dcafef4447fa68ea0ab28a72589241e9fdMike Klein#if defined(SK_BUILD_FOR_WIN) 1047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary 114dbbd04314cc0606f8d3bafe515c97e52c180f73halcanary#include "SkLeanWindows.h" 124dbbd04314cc0606f8d3bafe515c97e52c180f73halcanary 13b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#ifndef UNICODE 14b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define UNICODE 15b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#endif 16b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#ifndef _UNICODE 17b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define _UNICODE 18b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#endif 19b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <ObjBase.h> 20b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <XpsObjectModel.h> 21b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <T2EmbApi.h> 22b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include <FontSub.h> 23bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary#include <limits> 24b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 25b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkColor.h" 26b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkData.h" 27b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkDraw.h" 28b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org#include "SkEndian.h" 29bda26436faacf21ae2afd572aacd45eaa79fd0a6herb#include "SkFindAndPlaceGlyph.h" 3047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary#include "SkGeometry.h" 31b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkGlyphCache.h" 32b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkHRESULT.h" 33b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary#include "SkIStream.h" 34627778d5ba4fd6f4a4a1238bbf7a1b561469fe21Mike Reed#include "SkImage.h" 35b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkImageEncoder.h" 36b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary#include "SkImagePriv.h" 3780747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed#include "SkMaskFilterBase.h" 38b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkPaint.h" 39a439334b6e758d38501e225e2e5d0ab73e2fb6ebreed#include "SkPathEffect.h" 40da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner#include "SkPathOps.h" 41b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkPoint.h" 421e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed#include "SkRasterClip.h" 43b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org#include "SkSFNTHeader.h" 44b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkShader.h" 45b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkSize.h" 46b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkStream.h" 47b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTDArray.h" 48b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTLazy.h" 49b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTScopedComPtr.h" 50b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org#include "SkTTCFHeader.h" 51398de9ad9cb1ed3aa97aaf023d7f8287b8e62601reed@google.com#include "SkTypefacePriv.h" 52b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkUtils.h" 532f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed#include "SkVertices.h" 54b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkXPSDevice.h" 55b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 56b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//Windows defines a FLOAT type, 57b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//make it clear when converting a scalar that this is what is wanted. 58b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define SkScalarToFLOAT(n) SkScalarToFloat(n) 59b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 60da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner//Dummy representation of a GUID from createId. 61b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX" 6296fcdcc219d2a0d3579719b84b28bede76efba64halcanary//Length of GUID representation from createId, including nullptr terminator. 63b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#define GUID_ID_LEN SK_ARRAY_COUNT(L_GUID_ID) 64b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 65b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com/** 66b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com Formats a GUID and places it into buffer. 67b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com buffer should have space for at least GUID_ID_LEN wide characters. 68b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com The string will always be wchar null terminated. 69b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0 70b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com @return -1 if there was an error, > 0 if success. 71b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com */ 72b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic int format_guid(const GUID& guid, 73b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t* buffer, size_t bufferSize, 74b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t sep = '-') { 75b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(bufferSize >= GUID_ID_LEN); 76b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return swprintf_s(buffer, 77b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bufferSize, 78b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com L"%08lX%c%04X%c%04X%c%02X%02X%c%02X%02X%02X%02X%02X%02X", 79b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data1, 80b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 81b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data2, 82b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 83b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data3, 84b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 85b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[0], 86b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[1], 87b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sep, 88b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[2], 89b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[3], 90b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[4], 91b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[5], 92b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[6], 93b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com guid.Data4[7]); 94b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 95b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 96da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen WagnerHRESULT SkXPSDevice::createId(wchar_t* buffer, size_t bufferSize, wchar_t sep) { 97b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com GUID guid = {}; 98da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner#ifdef SK_XPS_USE_DETERMINISTIC_IDS 99da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner guid.Data1 = fNextId++; 100da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner // The following make this a valid Type4 UUID. 101da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner guid.Data3 = 0x4000; 102da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner guid.Data4[0] = 0x80; 103da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner#else 104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(CoCreateGuid(&guid), "Could not create GUID for id."); 105da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner#endif 10674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 107b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (format_guid(guid, buffer, bufferSize, sep) == -1) { 108b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(E_UNEXPECTED, "Could not format GUID into id."); 109b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 11074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 111b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 113b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 114b39b09e4477f5c51b27015a17c7ac699028c4d87Hal CanarySkXPSDevice::SkXPSDevice(SkISize s) 115b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary : INHERITED(SkImageInfo::MakeUnknown(s.width(), s.height()), 116b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 117abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary , fCurrentPage(0) {} 1189a53fd7c41554630124522f4b6eedc16912abbb7robertphillips 119abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal CanarySkXPSDevice::~SkXPSDevice() {} 120b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 121b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::TypefaceUse::TypefaceUse() 122b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com : typefaceId(0xffffffff) 12396fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fontData(nullptr) 12496fcdcc219d2a0d3579719b84b28bede76efba64halcanary , xpsFont(nullptr) 125abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary , glyphsUsed(nullptr) {} 126b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 127b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comSkXPSDevice::TypefaceUse::~TypefaceUse() { 128b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //xpsFont owns fontData ref 129b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->xpsFont->Release(); 130b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com delete this->glyphsUsed; 131b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 132b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 133abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canarybool SkXPSDevice::beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory* factory) { 134abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary SkASSERT(factory); 135abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary fXpsFactory.reset(SkRefComPtr(factory)); 136abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary HRB(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream)); 137b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 138b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 139b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 140b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::beginSheet( 141b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& unitsPerMeter, 142b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& pixelsPerMeter, 143b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkSize& trimSize, 144b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* mediaBox, 145b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* bleedBox, 146b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* artBox, 147b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect* cropBox) { 148b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ++this->fCurrentPage; 14974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 150b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //For simplicity, just write everything out in geometry units, 151b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //then have a base canvas do the scale to physical units. 152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize = trimSize; 153b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentUnitsPerMeter = unitsPerMeter; 154b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentPixelsPerMeter = pixelsPerMeter; 155abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary return this->createCanvasForLayer(); 156abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary} 15774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 158abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canarybool SkXPSDevice::createCanvasForLayer() { 159abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary SkASSERT(fXpsFactory); 160abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary fCurrentXpsCanvas.reset(); 161abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary HRB(fXpsFactory->CreateCanvas(&fCurrentXpsCanvas)); 162b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 163b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 164b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 165bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanarytemplate <typename T> static constexpr size_t sk_digits_in() { 166bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary return static_cast<size_t>(std::numeric_limits<T>::digits10 + 1); 167bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary} 168bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary 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, 17596fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 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; 181bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary constexpr size_t size = SkTMax( 182bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary SK_ARRAY_COUNT(L"/Documents/1/Metadata/.png") + sk_digits_in<decltype(pageNum)>(), 183bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary SK_ARRAY_COUNT(L"/Metadata/" L_GUID_ID L".png")); 184b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 185b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (pageNum > 0) { 186b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Documents/1/Metadata/%u.png", pageNum); 187b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 188b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 189da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner HR(this->createId(id, GUID_ID_LEN)); 190b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Metadata/%s.png", id); 191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 193b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create thumbnail part uri."); 19474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 195b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(thumbnailGenerator->GenerateThumbnail(page, 196b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_IMAGE_TYPE_PNG, 197b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_THUMBNAIL_SIZE_LARGE, 198b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 199b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com image), 200b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not generate thumbnail."); 20174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 202b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 203b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 204b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 205b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsPage(const XPS_SIZE& pageSize, 206b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPage** page) { 207bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary constexpr size_t size = 208bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary SK_ARRAY_COUNT(L"/Documents/1/Pages/.fpage") 209bfa9275968d11d459b30a485cedcb55c7fecf9d7halcanary + sk_digits_in<decltype(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(), 23996fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 240b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com image, 24196fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 24296fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 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(), 25596fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 25696fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 25796fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 25896fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr), 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. 31096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == 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, 32096fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 32196fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 32296fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 32396fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr), 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 336b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org int ttcCount = (current->ttcIndex + 1); 337b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 338b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //The following are declared with the types required by CreateFontPackage. 33996fcdcc219d2a0d3579719b84b28bede76efba64halcanary unsigned char *fontPackageBufferRaw = nullptr; 340b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org unsigned long fontPackageBufferSize; 341b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org unsigned long bytesWritten; 342b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned long result = CreateFontPackage( 343b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (unsigned char *) current->fontData->getMemoryBase(), 344b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (unsigned long) current->fontData->getLength(), 345b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org &fontPackageBufferRaw, 346b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org &fontPackageBufferSize, 347b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org &bytesWritten, 348b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST | (ttcCount > 0 ? TTFCFP_FLAGS_TTC : 0), 349b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org current->ttcIndex, 350b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TTFCFP_SUBSET, 351b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 352b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 353b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 354b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com keepList.begin(), 355b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com keepList.count(), 356b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_malloc_throw, 357b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_realloc_throw, 358b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com sk_free, 35996fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr); 360b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkAutoTMalloc<unsigned char> fontPackageBuffer(fontPackageBufferRaw); 361b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (result != NO_ERROR) { 362b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("CreateFontPackage Error %lu", result)); 363b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return E_UNEXPECTED; 364b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 36574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 366b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // If it was originally a ttc, keep it a ttc. 367b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // CreateFontPackage over-allocates, realloc usually decreases the size substantially. 368b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org size_t extra; 369b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org if (ttcCount > 0) { 370b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // Create space for a ttc header. 371b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org extra = sizeof(SkTTCFHeader) + (ttcCount * sizeof(SK_OT_ULONG)); 372b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fontPackageBuffer.realloc(bytesWritten + extra); 373b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org //overlap is certain, use memmove 374b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org memmove(fontPackageBuffer.get() + extra, fontPackageBuffer.get(), bytesWritten); 375b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 376b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // Write the ttc header. 377b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkTTCFHeader* ttcfHeader = reinterpret_cast<SkTTCFHeader*>(fontPackageBuffer.get()); 378b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org ttcfHeader->ttcTag = SkTTCFHeader::TAG; 379b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org ttcfHeader->version = SkTTCFHeader::version_1; 380b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org ttcfHeader->numOffsets = SkEndian_SwapBE32(ttcCount); 381b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SK_OT_ULONG* offsetPtr = SkTAfter<SK_OT_ULONG>(ttcfHeader); 382b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org for (int i = 0; i < ttcCount; ++i, ++offsetPtr) { 3830aa5cea8694d3686b6742a36eab81ab9001de954bsalomon *offsetPtr = SkEndian_SwapBE32(SkToU32(extra)); 384b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 385b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 386b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org // Fix up offsets in sfnt table entries. 387b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkSFNTHeader* sfntHeader = SkTAddOffset<SkSFNTHeader>(fontPackageBuffer.get(), extra); 388b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org int numTables = SkEndian_SwapBE16(sfntHeader->numTables); 389b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkSFNTHeader::TableDirectoryEntry* tableDirectory = 390b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader); 391b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org for (int i = 0; i < numTables; ++i, ++tableDirectory) { 392b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org tableDirectory->offset = SkEndian_SwapBE32( 3930aa5cea8694d3686b6742a36eab81ab9001de954bsalomon SkToU32(SkEndian_SwapBE32(SkToU32(tableDirectory->offset)) + extra)); 394b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 395b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } else { 396b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org extra = 0; 397b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fontPackageBuffer.realloc(bytesWritten); 398b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org } 399b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 400145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner std::unique_ptr<SkMemoryStream> newStream(new SkMemoryStream()); 40118300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein newStream->setMemoryOwned(fontPackageBuffer.release(), bytesWritten + extra); 402b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 403b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> newIStream; 40418300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein SkIStream::CreateFromSkStream(newStream.release(), true, &newIStream); 40574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 406b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FONT_EMBEDDING embedding; 407b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->GetEmbeddingOption(&embedding), 408b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get embedding option from font."); 40974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 410b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 411b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->GetPartName(&partUri), 412b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get part uri from font."); 41374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 414b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(current->xpsFont->SetContent( 415b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newIStream.get(), 416b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com embedding, 417b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get()), 418b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set new stream for subsetted font."); 41974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 420b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 421b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 422b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 423b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.combool SkXPSDevice::endPortfolio() { 424b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Subset fonts 425b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!this->fTypefaces.empty()) { 426b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDevice::TypefaceUse* current = &this->fTypefaces.front(); 427b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const TypefaceUse* last = &this->fTypefaces.back(); 428b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (; current <= last; ++current) { 429b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Ignore return for now, if it didn't subset, let it be. 430b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com subset_typeface(current); 431b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 432b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 43374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 434b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRBM(this->fPackageWriter->Close(), "Could not close writer."); 43574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 436b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return true; 437b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 438b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 439b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_COLOR xps_color(const SkColor skColor) { 440b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS uses non-pre-multiplied alpha (XPS Spec 11.4). 441b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR xpsColor; 442b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.colorType = XPS_COLOR_TYPE_SRGB; 443b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.alpha = SkColorGetA(skColor); 444b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.red = SkColorGetR(skColor); 445b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.green = SkColorGetG(skColor); 446b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsColor.value.sRGB.blue = SkColorGetB(skColor); 44774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 448b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xpsColor; 449b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 450b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 451b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_POINT xps_point(const SkPoint& point) { 452b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT xpsPoint = { 453b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(point.fX), 454b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(point.fY), 455b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 456b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xpsPoint; 457b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 458b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 459b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_POINT xps_point(const SkPoint& point, const SkMatrix& matrix) { 460b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint skTransformedPoint; 461b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix.mapXY(point.fX, point.fY, &skTransformedPoint); 462b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return xps_point(skTransformedPoint); 463b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 464b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 465b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_SPREAD_METHOD xps_spread_method(SkShader::TileMode tileMode) { 466b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (tileMode) { 467b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kClamp_TileMode: 468b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_PAD; 469b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kRepeat_TileMode: 470b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_REPEAT; 471b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkShader::kMirror_TileMode: 472b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_REFLECT; 473b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 474330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("Unknown tile mode."); 475b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 476b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return XPS_SPREAD_METHOD_PAD; 477b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 478b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 479b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic void transform_offsets(SkScalar* stopOffsets, const int numOffsets, 480b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPoint& start, const SkPoint& end, 481b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& transform) { 482b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint startTransformed; 483b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(start.fX, start.fY, &startTransformed); 484b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint endTransformed; 485b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(end.fX, end.fY, &endTransformed); 48674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 487b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Manhattan distance between transformed start and end. 488b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar startToEnd = (endTransformed.fX - startTransformed.fX) 489b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com + (endTransformed.fY - startTransformed.fY); 490b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkScalarNearlyZero(startToEnd)) { 491b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 0; i < numOffsets; ++i) { 492b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stopOffsets[i] = 0; 493b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 494b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 495b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 49674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 497b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 0; i < numOffsets; ++i) { 498b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint stop; 4998be952ad8c9deefe19cff36f9ad217563400f817Mike Reed stop.fX = (end.fX - start.fX) * stopOffsets[i]; 5008be952ad8c9deefe19cff36f9ad217563400f817Mike Reed stop.fY = (end.fY - start.fY) * stopOffsets[i]; 50174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 502b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint stopTransformed; 503b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform.mapXY(stop.fX, stop.fY, &stopTransformed); 50474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 505b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Manhattan distance between transformed start and stop. 506b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar startToStop = (stopTransformed.fX - startTransformed.fX) 507b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com + (stopTransformed.fY - startTransformed.fY); 508b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Percentage along transformed line. 50980ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed stopOffsets[i] = startToStop / startToEnd; 510b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 511b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 512b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 513b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsTransform(const SkMatrix& matrix, 514b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform** xpsTransform) { 515b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar affine[6]; 516b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!matrix.asAffine(affine)) { 51796fcdcc219d2a0d3579719b84b28bede76efba64halcanary *xpsTransform = nullptr; 518b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_FALSE; 519b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 520b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_MATRIX rawXpsMatrix = { 521f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kAScaleX]), 522f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kASkewY]), 523f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kASkewX]), 524f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kAScaleY]), 525f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kATransX]), 526f0cb7a09abe35e8eff152212e68f3cee3be075dfMike Reed SkScalarToFLOAT(affine[SkMatrix::kATransY]), 527b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 528b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateMatrixTransform(&rawXpsMatrix, xpsTransform), 529b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create transform."); 53074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 531b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 532b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 533b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 534b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createPath(IXpsOMGeometryFigure* figure, 535b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals, 536b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPath** path) { 537b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> geometry; 538b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&geometry), 539b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create geometry."); 54074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 541b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> figureCollection; 542b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(geometry->GetFigures(&figureCollection), "Could not get figures."); 543b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figureCollection->Append(figure), "Could not add figure."); 54474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 545b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePath(path), "Could not create path."); 546b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*path)->SetGeometryLocal(geometry.get()), "Could not set geometry"); 54774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 548b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(*path), "Could not add path to visuals."); 549b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 550b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 551b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 552b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsSolidColorBrush(const SkColor skColor, 553b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 554b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 555b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR xpsColor = xps_color(skColor); 556b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMSolidColorBrush> solidBrush; 55796fcdcc219d2a0d3579719b84b28bede76efba64halcanary HRM(this->fXpsFactory->CreateSolidColorBrush(&xpsColor, nullptr, &solidBrush), 558b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create solid color brush."); 559b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(solidBrush->SetOpacity(alpha / 255.0f), "Could not set opacity."); 560b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(solidBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI Fail."); 561b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 562b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 563b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 564b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::sideOfClamp(const SkRect& areaToFill, 565b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const XPS_RECT& imageViewBox, 566b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMImageResource* image, 567b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals) { 568b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 569b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 57074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 571b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> areaToFillPath; 572b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 57374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 574b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageBrush> areaToFillBrush; 575b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageBrush(image, 576b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageViewBox, 577b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageViewBox, 578b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &areaToFillBrush), 579b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create brush for side of clamp."); 580b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 581b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode for side of clamp."); 582b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 583b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set brush for side of clamp"); 58474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 585b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 586b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 587b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 588b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::cornerOfClamp(const SkRect& areaToFill, 589b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor color, 590b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMVisualCollection* visuals) { 591b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 592b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 59374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 594b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> areaToFillPath; 595b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 59674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 597b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> areaToFillBrush; 598b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, 0xFF, &areaToFillBrush)); 599b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 600b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set brush for corner of clamp."); 60174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 602b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 603b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 604b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 605b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_N = XPS_TILE_MODE_NONE; 606b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_T = XPS_TILE_MODE_TILE; 607b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_X = XPS_TILE_MODE_FLIPX; 608b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_Y = XPS_TILE_MODE_FLIPY; 609b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic const XPS_TILE_MODE XTM_XY = XPS_TILE_MODE_FLIPXY; 610b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 611b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//TODO(bungeman): In the future, should skia add None, 612b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//handle None+Mirror and None+Repeat correctly. 613b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com//None is currently an internal hack so masks don't repeat (None+None only). 614b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic XPS_TILE_MODE SkToXpsTileMode[SkShader::kTileModeCount+1] 615b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com [SkShader::kTileModeCount+1] = { 616a634b742320ae1c14ddb296e45569947daced9fchalcanary //Clamp //Repeat //Mirror //None 617a634b742320ae1c14ddb296e45569947daced9fchalcanary /*Clamp */ {XTM_N, XTM_T, XTM_Y, XTM_N}, 618a634b742320ae1c14ddb296e45569947daced9fchalcanary /*Repeat*/ {XTM_T, XTM_T, XTM_Y, XTM_N}, 619a634b742320ae1c14ddb296e45569947daced9fchalcanary /*Mirror*/ {XTM_X, XTM_X, XTM_XY, XTM_X}, 620a634b742320ae1c14ddb296e45569947daced9fchalcanary /*None */ {XTM_N, XTM_N, XTM_Y, XTM_N}, 621b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com}; 622b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 623b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsImageBrush( 624b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkBitmap& bitmap, 625b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 626b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader::TileMode (&xy)[2], 627b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 628b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMTileBrush** xpsBrush) { 629b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDynamicMemoryWStream write; 630db6830162eca5b94e61d9825ec93306fc615d204Hal Canary if (!SkEncodeImage(&write, bitmap, SkEncodedImageFormat::kPNG, 100)) { 631b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(E_FAIL, "Unable to encode bitmap as png."); 632b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 633b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMemoryStream* read = new SkMemoryStream; 63442943c8aa9c611c18ad0f1a30a27669f3d82239creed read->setData(write.detachAsData()); 635b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> readWrapper; 636b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(SkIStream::CreateFromSkStream(read, true, &readWrapper), 637b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create stream from png data."); 63874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 639b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const size_t size = 640b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Documents/1/Resources/Images/" L_GUID_ID L".png"); 641b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 642b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 643da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner HR(this->createId(id, GUID_ID_LEN)); 644b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Documents/1/Resources/Images/%s.png", id); 64574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 646b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> imagePartUri; 647b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &imagePartUri), 648b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image part uri."); 64974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 650b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageResource> imageResource; 651b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageResource( 652b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com readWrapper.get(), 653b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_IMAGE_TYPE_PNG, 654b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imagePartUri.get(), 655b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &imageResource), 656b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image resource."); 65774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 658b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bitmapRect = { 659b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 660b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), static_cast<FLOAT>(bitmap.height()) 661b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 662b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMImageBrush> xpsImageBrush; 663b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateImageBrush(imageResource.get(), 664b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &bitmapRect, &bitmapRect, 665b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsImageBrush), 666b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image brush."); 66774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 668b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode != xy[0] && 669b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode != xy[1]) { 67074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 671b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 672b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set image tile mode"); 673b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetOpacity(alpha / 255.0f), 674b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set image opacity."); 675b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->QueryInterface(xpsBrush), "QI failed."); 676b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 677b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): compute how big this really needs to be. 678b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar BIG = SkIntToScalar(1000); //SK_ScalarMax; 679b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const FLOAT BIG_F = SkScalarToFLOAT(BIG); 680b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar bWidth = SkIntToScalar(bitmap.width()); 681b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar bHeight = SkIntToScalar(bitmap.height()); 68274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 683b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create brush canvas 684b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> brushCanvas; 685b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&brushCanvas), 686b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create image brush canvas."); 687b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> brushVisuals; 688b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(brushCanvas->GetVisuals(&brushVisuals), 689b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get image brush canvas visuals collection."); 69074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 691b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create central figure 692b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect bitmapPoints = SkRect::MakeLTRB(0, 0, bWidth, bHeight); 693b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> centralFigure; 694b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRect(bitmapPoints, FALSE, TRUE, ¢ralFigure)); 69574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 696b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> centralPath; 697b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createPath(centralFigure.get(), 698b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get(), 699b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ¢ralPath)); 700b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsImageBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 701b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode for image brush central path."); 702b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(centralPath->SetFillBrushLocal(xpsImageBrush.get()), 703b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill brush for image brush central path."); 70474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 705b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add left/right 706b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0]) { 707b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect leftArea = SkRect::MakeLTRB(-BIG, 0, 0, bHeight); 708b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT leftImageViewBox = { 709b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 710b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0, static_cast<FLOAT>(bitmap.height()), 711b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 712b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(leftArea, leftImageViewBox, 713b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 714b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 715b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 716b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect rightArea = SkRect::MakeLTRB(bWidth, 0, BIG, bHeight); 717b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT rightImageViewBox = { 718b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmap.width() - 1.0f, 0.0f, 719b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1.0f, static_cast<FLOAT>(bitmap.height()), 720b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 721b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(rightArea, rightImageViewBox, 722b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 723b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 724b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 72574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 726b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add top/bottom 727b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[1]) { 728b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect topArea = SkRect::MakeLTRB(0, -BIG, bWidth, 0); 729b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT topImageViewBox = { 730b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0, 0.0, 731b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), 1.0, 732b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 733b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(topArea, topImageViewBox, 734b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 735b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 73674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 737b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkRect bottomArea = SkRect::MakeLTRB(0, bHeight, bWidth, BIG); 738b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bottomImageViewBox = { 739b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0.0f, bitmap.height() - 1.0f, 740b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com static_cast<FLOAT>(bitmap.width()), 1.0f, 741b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 742b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->sideOfClamp(bottomArea, bottomImageViewBox, 743b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com imageResource.get(), 744b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brushVisuals.get())); 745b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 74674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 747b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //add tl, tr, bl, br 748b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0] && 749b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode == xy[1]) { 75074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 751b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor tlColor = bitmap.getColor(0,0); 752b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect tlArea = SkRect::MakeLTRB(-BIG, -BIG, 0, 0); 753b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(tlArea, tlColor, brushVisuals.get())); 75474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 755b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor trColor = bitmap.getColor(bitmap.width()-1,0); 756b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect trArea = SkRect::MakeLTRB(bWidth, -BIG, BIG, 0); 757b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(trArea, trColor, brushVisuals.get())); 75874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 759b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor brColor = bitmap.getColor(bitmap.width()-1, 760b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bitmap.height()-1); 761b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect brArea = SkRect::MakeLTRB(bWidth, bHeight, BIG, BIG); 762b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(brArea, brColor, brushVisuals.get())); 76374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 764b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor blColor = bitmap.getColor(0,bitmap.height()-1); 765b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect blArea = SkRect::MakeLTRB(-BIG, bHeight, 0, BIG); 766b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->cornerOfClamp(blArea, blColor, brushVisuals.get())); 767b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 76874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 769b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //create visual brush from canvas 770b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_RECT bound = {}; 771b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kClamp_TileMode == xy[0] && 772b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode == xy[1]) { 77374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 774b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = BIG_F / -2; 775b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = BIG_F / -2; 776b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = BIG_F; 777b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = BIG_F; 778b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kClamp_TileMode == xy[0]) { 779b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = BIG_F / -2; 780b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = 0.0f; 781b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = BIG_F; 782b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = static_cast<FLOAT>(bitmap.height()); 783b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kClamp_TileMode == xy[1]) { 784b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.x = 0; 785b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.y = BIG_F / -2; 786b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.width = static_cast<FLOAT>(bitmap.width()); 787b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bound.height = BIG_F; 788b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 789b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualBrush> clampBrush; 790b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateVisualBrush(&bound, &bound, &clampBrush), 791b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create visual brush for image brush."); 792b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetVisualLocal(brushCanvas.get()), 793b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set canvas on visual brush for image brush."); 794b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 795b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set tile mode on visual brush for image brush."); 796b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->SetOpacity(alpha / 255.0f), 797b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity on visual brush for image brush."); 79874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 799b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clampBrush->QueryInterface(xpsBrush), "QI failed."); 800b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 80174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 802b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 803b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 80449f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsMatrixToUse.get()) { 805b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsBrush)->SetTransformLocal(xpsMatrixToUse.get()), 806b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for image brush."); 807b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 808b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): perspective bitmaps in general. 809b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 81074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 811b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 812b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 813b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 814b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsGradientStop(const SkColor skColor, 815b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkScalar offset, 816b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGradientStop** xpsGradStop) { 817b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_COLOR gradStopXpsColor = xps_color(skColor); 818b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGradientStop(&gradStopXpsColor, 81996fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 820b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(offset), 821b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsGradStop), 822b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create gradient stop."); 823b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 824b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 825b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 826b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsLinearGradient(SkShader::GradientInfo info, 827b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 828b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 829b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform* xpsMatrix, 830b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 831b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint; 832b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT endPoint; 83349f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsMatrix) { 834b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com startPoint = xps_point(info.fPoint[0]); 835b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com endPoint = xps_point(info.fPoint[1]); 836b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 837b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform_offsets(info.fColorOffsets, info.fColorCount, 838b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fPoint[0], info.fPoint[1], 839b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix); 840b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com startPoint = xps_point(info.fPoint[0], localMatrix); 841b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com endPoint = xps_point(info.fPoint[1], localMatrix); 842b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 84374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 844b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 845b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[0], 846b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[0], 847b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop0)); 84874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 849b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 850b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[1], 851b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[1], 852b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop1)); 85374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 854b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMLinearGradientBrush> gradientBrush; 855b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateLinearGradientBrush(gradStop0.get(), 856b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradStop1.get(), 857b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &startPoint, 858b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &endPoint, 859b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientBrush), 860b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create linear gradient brush."); 86149f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsMatrix) { 862b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetTransformLocal(xpsMatrix), 863b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on linear gradient brush."); 864b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 86574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 866b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 867b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->GetGradientStops(&gradStopCollection), 868b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get linear gradient stop collection."); 869b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 2; i < info.fColorCount; ++i) { 870b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop; 871b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[i], 872b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[i], 873b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop)); 874b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradStopCollection->Append(gradStop.get()), 875b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add linear gradient stop."); 876b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 87774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 878b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 879b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set spread method of linear gradient."); 88074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 881b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetOpacity(alpha / 255.0f), 882b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity of linear gradient brush."); 883b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed"); 88474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 885b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 886b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 887b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 888b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsRadialGradient(SkShader::GradientInfo info, 889b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkAlpha alpha, 890b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& localMatrix, 891b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMMatrixTransform* xpsMatrix, 892b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** xpsBrush) { 893b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 894b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[0], 895b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[0], 896b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop0)); 89774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 898b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 899b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[1], 900b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[1], 901b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop1)); 90274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 903b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: figure out how to fake better if not affine 904b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT centerPoint; 905b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT gradientOrigin; 906b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SIZE radiiSizes; 90749f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsMatrix) { 908b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com centerPoint = xps_point(info.fPoint[0]); 909b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradientOrigin = xps_point(info.fPoint[0]); 910b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.width = SkScalarToFLOAT(info.fRadius[0]); 911b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.height = SkScalarToFLOAT(info.fRadius[0]); 912b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 913b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com centerPoint = xps_point(info.fPoint[0], localMatrix); 914b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradientOrigin = xps_point(info.fPoint[0], localMatrix); 91574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 916b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar radius = info.fRadius[0]; 917b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector vec[2]; 91874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 919b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com vec[0].set(radius, 0); 920b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com vec[1].set(0, radius); 921b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix.mapVectors(vec, 2); 92274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 923b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar d0 = vec[0].length(); 924b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar d1 = vec[1].length(); 92574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 926b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.width = SkScalarToFLOAT(d0); 927b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com radiiSizes.height = SkScalarToFLOAT(d1); 928b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 92974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 930b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMRadialGradientBrush> gradientBrush; 931b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateRadialGradientBrush(gradStop0.get(), 932b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com gradStop1.get(), 933b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ¢erPoint, 934b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientOrigin, 935b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &radiiSizes, 936b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradientBrush), 937b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create radial gradient brush."); 93849f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsMatrix) { 939b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetTransformLocal(xpsMatrix), 940b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on radial gradient brush."); 941b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 94274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 943b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 944b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->GetGradientStops(&gradStopCollection), 945b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get radial gradient stop collection."); 946b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (int i = 2; i < info.fColorCount; ++i) { 947b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGradientStop> gradStop; 948b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(createXpsGradientStop(info.fColors[i], 949b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets[i], 950b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &gradStop)); 951b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradStopCollection->Append(gradStop.get()), 952b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add radial gradient stop."); 953b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 95474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 955b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 956b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set spread method of radial gradient."); 95774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 958b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->SetOpacity(alpha / 255.0f), 959b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set opacity of radial gradient brush."); 960b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed."); 96174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 962b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 963b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 964b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 965b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint, 966b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMBrush** brush, 967b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix* parentTransform) { 968b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader *shader = skPaint.getShader(); 96996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == shader) { 970b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 971b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 972b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 97374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 974b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Gradient shaders. 975b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::GradientInfo info; 976b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorCount = 0; 97796fcdcc219d2a0d3579719b84b28bede76efba64halcanary info.fColors = nullptr; 97896fcdcc219d2a0d3579719b84b28bede76efba64halcanary info.fColorOffsets = nullptr; 979b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::GradientType gradientType = shader->asAGradient(&info); 98074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 981b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kNone_GradientType == gradientType) { 982b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Nothing to see, move along. 98374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 984b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else if (SkShader::kColor_GradientType == gradientType) { 985b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkASSERT(1 == info.fColorCount); 986b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkColor color; 987b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColors = &color; 988b58a639b2fbe919489654bb506efdb024a308a8ebsalomon@google.com shader->asAGradient(&info); 989b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAlpha alpha = skPaint.getAlpha(); 990b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, alpha, brush)); 991b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 99274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 993b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 994b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (info.fColorCount == 0) { 995b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkColor color = skPaint.getColor(); 996b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, 0xFF, brush)); 997b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 998b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 99974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1000b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoTArray<SkColor> colors(info.fColorCount); 1001b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoTArray<SkScalar> colorOffsets(info.fColorCount); 1002b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColors = colors.get(); 1003b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com info.fColorOffsets = colorOffsets.get(); 1004b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com shader->asAGradient(&info); 100574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1006b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (1 == info.fColorCount) { 1007b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkColor color = info.fColors[0]; 1008b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAlpha alpha = skPaint.getAlpha(); 1009b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsSolidColorBrush(color, alpha, brush)); 1010b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1011b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 101274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1013f94b3a4cebd4adab09c40ebe23c02a615e10c394bsalomon@google.com SkMatrix localMatrix = shader->getLocalMatrix(); 101449f085dddff10473b6ebf832a974288300224e60bsalomon if (parentTransform) { 1015b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix.preConcat(*parentTransform); 1016b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1017b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 1018b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 101974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1020b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kLinear_GradientType == gradientType) { 1021b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsLinearGradient(info, 1022b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skPaint.getAlpha(), 1023b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix, 1024b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsMatrixToUse.get(), 1025b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brush)); 1026b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1027b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 102874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1029b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kRadial_GradientType == gradientType) { 1030b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsRadialGradient(info, 1031b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skPaint.getAlpha(), 1032b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com localMatrix, 1033b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsMatrixToUse.get(), 1034b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com brush)); 1035b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1036b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 103774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 103871a6cbfc585959738dc0b375603696ca7f60605freed if (SkShader::kConical_GradientType == gradientType) { 1039b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //simple if affine and one is 0, otherwise will have to fake 1040b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 104174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1042b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkShader::kSweep_GradientType == gradientType) { 1043b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //have to fake 1044b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1045b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 104674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1047b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap outTexture; 1048b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix outMatrix; 1049b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::TileMode xy[2]; 1050627778d5ba4fd6f4a4a1238bbf7a1b561469fe21Mike Reed SkImage* image = shader->isAImage(&outMatrix, xy); 10514f5a79c676757c0f218156077fb0575d46a6583cCary Clark if (image && image->asLegacyBitmap(&outTexture)) { 1052f5822825ec2d5dd24ab476fdd42db2a6573f9756reed //TODO: outMatrix?? 1053f5822825ec2d5dd24ab476fdd42db2a6573f9756reed SkMatrix localMatrix = shader->getLocalMatrix(); 1054f5822825ec2d5dd24ab476fdd42db2a6573f9756reed if (parentTransform) { 1055bc21243343b24ffb62b83cdfa0a2bb6c60f07c0fHal Canary localMatrix.postConcat(*parentTransform); 1056b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 105774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1058f5822825ec2d5dd24ab476fdd42db2a6573f9756reed SkTScopedComPtr<IXpsOMTileBrush> tileBrush; 1059f5822825ec2d5dd24ab476fdd42db2a6573f9756reed HR(this->createXpsImageBrush(outTexture, 1060f5822825ec2d5dd24ab476fdd42db2a6573f9756reed localMatrix, 1061f5822825ec2d5dd24ab476fdd42db2a6573f9756reed xy, 1062f5822825ec2d5dd24ab476fdd42db2a6573f9756reed skPaint.getAlpha(), 1063f5822825ec2d5dd24ab476fdd42db2a6573f9756reed &tileBrush)); 1064f5822825ec2d5dd24ab476fdd42db2a6573f9756reed 1065f5822825ec2d5dd24ab476fdd42db2a6573f9756reed HRM(tileBrush->QueryInterface<IXpsOMBrush>(brush), "QI failed."); 1066f5822825ec2d5dd24ab476fdd42db2a6573f9756reed } else { 1067f5822825ec2d5dd24ab476fdd42db2a6573f9756reed HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 1068f5822825ec2d5dd24ab476fdd42db2a6573f9756reed } 1069b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1070b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1071b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1072b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic bool rect_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 1073b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool zeroWidth = (0 == paint.getStrokeWidth()); 1074b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool stroke = (SkPaint::kFill_Style != paint.getStyle()); 107574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1076b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return paint.getPathEffect() || 1077b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getMaskFilter() || 1078b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (stroke && ( 1079b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (matrix.hasPerspective() && !zeroWidth) || 1080b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPaint::kMiter_Join != paint.getStrokeJoin() || 1081b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com (SkPaint::kMiter_Join == paint.getStrokeJoin() && 1082b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getStrokeMiter() < SK_ScalarSqrt2) 1083b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com )) 1084b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ; 1085b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1086b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1087b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsRect(const SkRect& rect, BOOL stroke, BOOL fill, 1088b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure** xpsRect) { 1089b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPoint points[4] = { 1090b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fLeft, rect.fTop }, 1091b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fRight, rect.fTop }, 1092b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fRight, rect.fBottom }, 1093b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { rect.fLeft, rect.fBottom }, 1094b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1095b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return this->createXpsQuad(points, stroke, fill, xpsRect); 1096b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1097b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4], 1098b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, 1099b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure** xpsQuad) { 1100b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the start point. 1101b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint = xps_point(points[0]); 110274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1103b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Create the figure. 1104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, xpsQuad), 1105b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create quad geometry figure."); 110674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1107b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the type of each segment. 1108b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE segmentTypes[3] = { 1109b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1110b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1111b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_SEGMENT_TYPE_LINE, 1112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 111374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1114b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the x and y coordinates of each corner of the figure. 1115b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FLOAT segmentData[6] = { 1116b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[1].fX), SkScalarToFLOAT(points[1].fY), 1117b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[2].fX), SkScalarToFLOAT(points[2].fY), 1118b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(points[3].fX), SkScalarToFLOAT(points[3].fY), 1119b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 112074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1121b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Describe if the segments are stroked. 1122b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL segmentStrokes[3] = { 1123b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, stroke, stroke, 1124b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 112574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1126b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the segment data to the figure. 1127b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetSegments( 1128b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 3, 6, 1129b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes , segmentData, segmentStrokes), 1130b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add segment data to quad."); 113174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1132b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Set the closed and filled properties of the figure. 1133b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetIsClosed(stroke), "Could not set quad close."); 1134b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM((*xpsQuad)->SetIsFilled(fill), "Could not set quad fill."); 113574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1136b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1137b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1138b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1139a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedtemplate <typename F, typename... Args> 1140a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid draw(SkClipStackDevice* dev, F f, Args&&... args) { 1141a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkIRect r = dev->devClipBounds(); 1142a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkRasterClip rc(r); 1143a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkDraw draw; 1144a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed draw.fMatrix = &dev->ctm(); 1145a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0); 1146a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed draw.fRC = &rc; 1147a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed (draw.*f)(std::forward<Args>(args)...); 1148a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed} 1149a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1150a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1151a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawPoints(SkCanvas::PointMode mode, 1152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com size_t count, const SkPoint points[], 1153b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1154a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed draw(this, &SkDraw::drawPoints, mode, count, points, paint, this); 1155b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1156b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 11572f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reedvoid SkXPSDevice::drawVertices(const SkVertices* v, SkBlendMode blendMode, const SkPaint& paint) { 11582f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(), 11592f6b5a47a50cdd218bc3302273be3a4a71add8fbMike Reed v->colors(), blendMode, v->indices(), v->indexCount(), paint); 1160b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1161b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1162a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawPaint(const SkPaint& origPaint) { 1163b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize); 116474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1165b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //If trying to paint with a stroke, ignore that and fill. 11665dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkPaint* fillPaint = const_cast<SkPaint*>(&origPaint); 11675dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 11685dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com if (paint->getStyle() != SkPaint::kFill_Style) { 11695dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com paint.writable()->setStyle(SkPaint::kFill_Style); 1170b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 117174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1172a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->internalDrawRect(r, false, *fillPaint); 1173b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1174b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1175a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawRect(const SkRect& r, 1176b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1177a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->internalDrawRect(r, true, paint); 1178b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1179b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1180a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawRRect(const SkRRect& rr, 1181cac8d01eabd05d11365f56b6af3f30bccb173487scroggo@google.com const SkPaint& paint) { 1182cac8d01eabd05d11365f56b6af3f30bccb173487scroggo@google.com SkPath path; 1183cac8d01eabd05d11365f56b6af3f30bccb173487scroggo@google.com path.addRRect(rr); 1184a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->drawPath(path, paint, nullptr, true); 1185cac8d01eabd05d11365f56b6af3f30bccb173487scroggo@google.com} 1186cac8d01eabd05d11365f56b6af3f30bccb173487scroggo@google.com 1187a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedstatic SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; } 1188a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed 1189a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::internalDrawRect(const SkRect& r, 1190b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool transformRect, 1191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Exit early if there is nothing to draw. 1193a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (this->cs().isEmpty(size(*this)) || 1194374772bd61951f01bf84fe17bf53d8867681c9aereed (paint.getAlpha() == 0 && paint.isSrcOver())) { 1195b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1196b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 119774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1198b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Path the rect if we can't optimize it. 1199a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (rect_must_be_pathed(paint, this->ctm())) { 1200b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath tmp; 1201b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com tmp.addRect(r); 1202b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com tmp.setFillType(SkPath::kWinding_FillType); 1203a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->drawPath(tmp, paint, nullptr, true); 1204b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1205b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 120674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1207b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded path. 1208b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1209b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1210b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded path for rect."); 121174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1212b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded geometry. 1213b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1214b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1215b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded geometry for rect."); 121674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1217b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the geometry to the shaded path. 1218b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1219b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set shaded geometry for rect."); 122074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1221b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the brushes. 1222b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL fill = FALSE; 1223b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke = FALSE; 1224a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->shadePath(shadedPath.get(), paint, this->ctm(), &fill, &stroke)); 122574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1226b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool xpsTransformsPath = true; 1227b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Transform the geometry. 1228b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (transformRect && xpsTransformsPath) { 1229b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1230a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->createXpsTransform(this->ctm(), &xpsTransform)); 1231b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1232b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1233b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for rect."); 1234b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1235b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1236b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1237b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 123874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1239b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the figure. 1240b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 1241b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { 1242b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint points[4] = { 1243b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fLeft, r.fTop }, 1244b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fLeft, r.fBottom }, 1245b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fRight, r.fBottom }, 1246b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com { r.fRight, r.fTop }, 1247b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1248b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!xpsTransformsPath && transformRect) { 1249a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->ctm().mapPoints(points, SK_ARRAY_COUNT(points)); 1250b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1251b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsQuad(points, stroke, fill, &rectFigure)); 1252b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 125374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1254b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures of the shaded geometry. 1255b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1256b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1257b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded figures for rect."); 125874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1259b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the figure to the shaded geometry figures. 1260b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(rectFigure.get()), 1261b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add shaded figure for rect."); 126274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1263a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->clip(shadedPath.get())); 126474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1265b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the shaded path to the current visuals. 1266b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1267b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1268b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for rect."); 1269b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1270b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add rect to current visuals."); 1271b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1272b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1273b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic HRESULT close_figure(const SkTDArray<XPS_SEGMENT_TYPE>& segmentTypes, 1274b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkTDArray<BOOL>& segmentStrokes, 1275b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkTDArray<FLOAT>& segmentData, 1276b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, 1277b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigure* figure, 1278b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigureCollection* figures) { 1279b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the segment data to the figure. 1280b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetSegments(segmentTypes.count(), segmentData.count(), 1281b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.begin() , segmentData.begin(), 1282b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.begin()), 1283b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set path segments."); 128474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1285b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Set the closed and filled properties of the figure. 1286b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetIsClosed(stroke), "Could not set path closed."); 1287b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figure->SetIsFilled(fill), "Could not set path fill."); 128874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1289b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Add the figure created above to this geometry. 1290b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(figures->Append(figure), "Could not add path to geometry."); 1291b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1292b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1293b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1294b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::addXpsPathGeometry( 1295b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMGeometryFigureCollection* xpsFigures, 1296b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke, BOOL fill, const SkPath& path) { 1297b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<XPS_SEGMENT_TYPE> segmentTypes; 1298b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<BOOL> segmentStrokes; 1299b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTDArray<FLOAT> segmentData; 130074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1301b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> xpsFigure; 1302b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath::Iter iter(path, true); 1303b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPoint points[4]; 1304b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath::Verb verb; 1305b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com while ((verb = iter.next(points)) != SkPath::kDone_Verb) { 1306b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com switch (verb) { 1307b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kMove_Verb: { 130849f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsFigure.get()) { 1309b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1310b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, 1311b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.get() , xpsFigures)); 1312b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.reset(); 1313b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.rewind(); 1314b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.rewind(); 1315b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.rewind(); 1316b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1317b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Define the start point. 1318b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT startPoint = xps_point(points[0]); 1319b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // Create the figure. 1320b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, 1321b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFigure), 1322b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create path geometry figure."); 1323b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1324b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1325b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kLine_Verb: 1326b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (iter.isCloseLine()) break; //ignore the line, auto-closed 1327b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_LINE); 1328b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1329b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1330b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1331b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1332b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kQuad_Verb: 1333b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER); 1334b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1335b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1336b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1337b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fX)); 1338b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fY)); 1339b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1340b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kCubic_Verb: 1341b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentTypes.push(XPS_SEGMENT_TYPE_BEZIER); 1342b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentStrokes.push(stroke); 1343b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fX)); 1344b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[1].fY)); 1345b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fX)); 1346b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[2].fY)); 1347b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[3].fX)); 1348b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com segmentData.push(SkScalarToFLOAT(points[3].fY)); 1349b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 135047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary case SkPath::kConic_Verb: { 135147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary const SkScalar tol = SK_Scalar1 / 4; 135247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary SkAutoConicToQuads converter; 135347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary const SkPoint* quads = 135447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary converter.computeQuads(points, iter.conicWeight(), tol); 135547ef4d5d934bba86848aa238efab21f54a160c1ahalcanary for (int i = 0; i < converter.countQuads(); ++i) { 135647ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER); 135747ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentStrokes.push(stroke); 135847ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentData.push(SkScalarToFLOAT(quads[2 * i + 1].fX)); 135947ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentData.push(SkScalarToFLOAT(quads[2 * i + 1].fY)); 136047ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentData.push(SkScalarToFLOAT(quads[2 * i + 2].fX)); 136147ef4d5d934bba86848aa238efab21f54a160c1ahalcanary segmentData.push(SkScalarToFLOAT(quads[2 * i + 2].fY)); 136247ef4d5d934bba86848aa238efab21f54a160c1ahalcanary } 136347ef4d5d934bba86848aa238efab21f54a160c1ahalcanary break; 136447ef4d5d934bba86848aa238efab21f54a160c1ahalcanary } 1365b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kClose_Verb: 1366b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // we ignore these, and just get the whole segment from 1367b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // the corresponding line/quad/cubic verbs 1368b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1369b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 1370330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("unexpected verb"); 1371b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1372b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1373b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 137449f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsFigure.get()) { 1375b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1376b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, 1377b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFigure.get(), xpsFigures)); 1378b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1379b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1380b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1381b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1382b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comvoid SkXPSDevice::convertToPpm(const SkMaskFilter* filter, 1383b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix* matrix, 1384b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector* ppuScale, 1385b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkIRect& clip, SkIRect* clipIRect) { 1386b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //This action is in unit space, but the ppm is specified in physical space. 138780ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed ppuScale->set(fCurrentPixelsPerMeter.fX / fCurrentUnitsPerMeter.fX, 138880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed fCurrentPixelsPerMeter.fY / fCurrentUnitsPerMeter.fY); 138974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1390b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com matrix->postScale(ppuScale->fX, ppuScale->fY); 139174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1392b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkIRect& irect = clip; 13938be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkRect clipRect = SkRect::MakeLTRB(SkIntToScalar(irect.fLeft) * ppuScale->fX, 13948be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkIntToScalar(irect.fTop) * ppuScale->fY, 13958be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkIntToScalar(irect.fRight) * ppuScale->fX, 13968be952ad8c9deefe19cff36f9ad217563400f817Mike Reed SkIntToScalar(irect.fBottom) * ppuScale->fY); 1397b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com clipRect.roundOut(clipIRect); 1398b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1399b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1400a1361364e64138adda3dc5f71d50d7503838bb6dMike ReedHRESULT SkXPSDevice::applyMask(const SkMask& mask, 1401b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkVector& ppuScale, 1402b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMPath* shadedPath) { 1403b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the geometry object. 1404b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1405b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->GetGeometry(&shadedGeometry), 1406b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask shaded geometry."); 140774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1408b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures from the geometry. 1409b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1410b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedGeometry->GetFigures(&shadedFigures), 1411b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask shaded figures."); 141274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1413b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMatrix m; 1414b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.reset(); 1415b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.setTranslate(SkIntToScalar(mask.fBounds.fLeft), 1416b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIntToScalar(mask.fBounds.fTop)); 1417b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com m.postScale(SkScalarInvert(ppuScale.fX), SkScalarInvert(ppuScale.fY)); 141874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1419b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::TileMode xy[2]; 1420b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy[0] = (SkShader::TileMode)3; 1421b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy[1] = (SkShader::TileMode)3; 142274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1423b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkBitmap bm; 1424a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bm.installMaskPixels(mask); 142574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1426b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMTileBrush> maskBrush; 1427b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsImageBrush(bm, m, xy, 0xFF, &maskBrush)); 1428b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetOpacityMaskBrushLocal(maskBrush.get()), 1429b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set mask."); 143074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1431b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect universeRect = SkRect::MakeLTRB(0, 0, 1432b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight); 1433b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure; 1434b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure), 1435b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create mask shaded figure."); 1436b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedFigures->Append(shadedFigure.get()), 1437b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add mask shaded figure."); 143874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1439a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HR(this->clip(shadedPath)); 144074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1441b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the path to the active visual collection. 1442b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1443b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1444b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get mask current visuals."); 1445b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(currentVisuals->Append(shadedPath), 1446b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add masked shaded path to current visuals."); 144774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1448b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1449b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1450b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1451b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath, 1452b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& shaderPaint, 1453b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& matrix, 1454b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL* fill, BOOL* stroke) { 1455b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *fill = FALSE; 1456b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *stroke = FALSE; 145774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1458b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint::Style style = shaderPaint.getStyle(); 1459b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool hasFill = SkPaint::kFill_Style == style 1460b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style; 1461b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const bool hasStroke = SkPaint::kStroke_Style == style 1462b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style; 146374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1464b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO(bungeman): use dictionaries and lookups. 1465b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (hasFill) { 1466b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *fill = TRUE; 1467b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> fillBrush; 1468b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush(shaderPaint, &fillBrush, &matrix)); 1469b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetFillBrushLocal(fillBrush.get()), 1470b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill for shaded path."); 1471b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 147274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1473b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (hasStroke) { 1474b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *stroke = TRUE; 1475b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> strokeBrush; 1476b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush(shaderPaint, &strokeBrush, &matrix)); 1477b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeBrushLocal(strokeBrush.get()), 1478b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set stroke brush for shaded path."); 1479b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeThickness( 1480b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(shaderPaint.getStrokeWidth())), 1481b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set shaded path stroke thickness."); 148274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1483b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (0 == shaderPaint.getStrokeWidth()) { 1484b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS hair width is a hack. (XPS Spec 11.6.12). 1485b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMDashCollection> dashes; 1486b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->GetStrokeDashes(&dashes), 1487b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set dashes for shaded path."); 1488b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_DASH dash; 1489b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com dash.length = 1.0; 1490b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com dash.gap = 0.0; 1491b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(dashes->Append(&dash), "Could not add dashes to shaded path."); 1492b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(shadedPath->SetStrokeDashOffset(-2.0), 1493b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set dash offset for shaded path."); 1494b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1495b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1496b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1497b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1498b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1499a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawPath(const SkPath& platonicPath, 15005dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com const SkPaint& origPaint, 1501b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix* prePathMatrix, 1502b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool pathIsMutable) { 15035dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 15045dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com 1505b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com // nothing to draw 1506a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (this->cs().isEmpty(size(*this)) || 1507374772bd61951f01bf84fe17bf53d8867681c9aereed (paint->getAlpha() == 0 && paint->isSrcOver())) { 1508b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1509b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 151074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1511b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath modifiedPath; 15125dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com const bool paintHasPathEffect = paint->getPathEffect() 15135dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com || paint->getStyle() != SkPaint::kFill_Style; 151474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1515b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Apply pre-path matrix [Platonic-path -> Skeletal-path]. 1516a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkMatrix matrix = this->ctm(); 1517b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath); 1518b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (prePathMatrix) { 15198ad91a9bf896d728b905124847d74787aac698a7Mike Reed if (paintHasPathEffect) { 1520b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!pathIsMutable) { 1521b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com skeletalPath = &modifiedPath; 1522b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com pathIsMutable = true; 1523b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1524b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com platonicPath.transform(*prePathMatrix, skeletalPath); 1525b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 152692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.org matrix.preConcat(*prePathMatrix); 1527b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1528b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 152974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1530b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Apply path effect [Skeletal-path -> Fillable-path]. 1531b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* fillablePath = skeletalPath; 1532b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (paintHasPathEffect) { 1533b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!pathIsMutable) { 1534b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath = &modifiedPath; 1535b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com pathIsMutable = true; 1536b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 15375dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com bool fill = paint->getFillPath(*skeletalPath, fillablePath); 153874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 15395dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkPaint* writablePaint = paint.writable(); 154096fcdcc219d2a0d3579719b84b28bede76efba64halcanary writablePaint->setPathEffect(nullptr); 1541b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (fill) { 15425dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com writablePaint->setStyle(SkPaint::kFill_Style); 1543b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 15445dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com writablePaint->setStyle(SkPaint::kStroke_Style); 15455dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com writablePaint->setStrokeWidth(0); 1546b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1547b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 154874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1549b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded path. This will be the path which is painted. 1550b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1551b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1552b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded path for path."); 155374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1554b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the geometry for the shaded path. 1555b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1556b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1557b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create shaded geometry for path."); 155874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1559b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the geometry to the shaded path. 1560b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1561b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add the shaded geometry to shaded path."); 156274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 15635dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com SkMaskFilter* filter = paint->getMaskFilter(); 1564d998cbdbb73ac11b10081a640e0a7975ac05262cbungeman@google.com 1565d998cbdbb73ac11b10081a640e0a7975ac05262cbungeman@google.com //Determine if we will draw or shade and mask. 15668ad91a9bf896d728b905124847d74787aac698a7Mike Reed if (filter) { 15675dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com if (paint->getStyle() != SkPaint::kFill_Style) { 15685dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com paint.writable()->setStyle(SkPaint::kFill_Style); 1569d998cbdbb73ac11b10081a640e0a7975ac05262cbungeman@google.com } 1570d998cbdbb73ac11b10081a640e0a7975ac05262cbungeman@google.com } 1571d998cbdbb73ac11b10081a640e0a7975ac05262cbungeman@google.com 1572b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the brushes. 1573b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL fill; 1574b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com BOOL stroke; 1575b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->shadePath(shadedPath.get(), 15765dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com *paint, 1577a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->ctm(), 1578b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &fill, 1579b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &stroke)); 158074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1581b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Mask filter 1582b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (filter) { 1583b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIRect clipIRect; 1584b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkVector ppuScale; 1585b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->convertToPpm(filter, 1586b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &matrix, 1587b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &ppuScale, 1588a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->cs().bounds(size(*this)).roundOut(), 1589b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect); 159074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1591b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Pixel-path] 1592b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath* pixelPath = pathIsMutable ? fillablePath : &modifiedPath; 1593b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com fillablePath->transform(matrix, pixelPath); 159474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 159596fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkMask* mask = nullptr; 159674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1597055e192adc0072ae2548ef5431ceee652945f9c2bsalomon SkASSERT(SkPaint::kFill_Style == paint->getStyle() || 1598055e192adc0072ae2548ef5431ceee652945f9c2bsalomon (SkPaint::kStroke_Style == paint->getStyle() && 0 == paint->getStrokeWidth())); 1599055e192adc0072ae2548ef5431ceee652945f9c2bsalomon SkStrokeRec::InitStyle style = (SkPaint::kFill_Style == paint->getStyle()) 1600055e192adc0072ae2548ef5431ceee652945f9c2bsalomon ? SkStrokeRec::kFill_InitStyle 1601055e192adc0072ae2548ef5431ceee652945f9c2bsalomon : SkStrokeRec::kHairline_InitStyle; 1602b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Pixel-path -> Mask] 1603b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask rasteredMask; 1604b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (SkDraw::DrawToMask( 1605b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *pixelPath, 1606b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &clipIRect, 1607b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com filter, //just to compute how much to draw. 1608b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &matrix, 1609b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &rasteredMask, 16102ac4ef5e6e0c9c95c9200408ba25a95ca758eac2junov@chromium.org SkMask::kComputeBoundsAndRenderImage_CreateMode, 1611055e192adc0072ae2548ef5431ceee652945f9c2bsalomon style)) { 161274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1613b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage); 1614b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &rasteredMask; 161574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1616b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Mask -> Mask] 1617b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkMask filteredMask; 161880747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed if (as_MFB(filter)->filterMask(&filteredMask, rasteredMask, matrix, nullptr)) { 1619b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com mask = &filteredMask; 1620b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1621b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkAutoMaskFreeImage filteredAmi(filteredMask.fImage); 162274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1623b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Draw mask. 1624a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->applyMask(*mask, ppuScale, shadedPath.get())); 1625b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1626b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1627b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 162874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1629b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figures from the shaded geometry. 1630b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1631b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1632b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get shaded figures for shaded path."); 163374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1634b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool xpsTransformsPath = true; 163574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1636b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Set the fill rule. 163776db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman SkPath* xpsCompatiblePath = fillablePath; 1638b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FILL_RULE xpsFillRule; 163976db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman switch (fillablePath->getFillType()) { 1640b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kWinding_FillType: 1641b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_NONZERO; 1642b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1643b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kEvenOdd_FillType: 1644b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_EVENODD; 1645b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1646b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kInverseWinding_FillType: { 164776db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman //[Fillable-path (inverse winding) -> XPS-path (inverse even odd)] 164876db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman if (!pathIsMutable) { 164976db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman xpsCompatiblePath = &modifiedPath; 165076db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman pathIsMutable = true; 165176db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman } 165276db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman if (!Simplify(*fillablePath, xpsCompatiblePath)) { 165376db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman SkDEBUGF(("Could not simplify inverse winding path.")); 165476db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman return; 165576db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman } 1656b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 165776db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman // The xpsCompatiblePath is noW inverse even odd, so fall through. 1658b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com case SkPath::kInverseEvenOdd_FillType: { 1659b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect universe = SkRect::MakeLTRB( 1660b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 0, 0, 1661b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fWidth, 1662b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentCanvasSize.fHeight); 1663b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure; 1664b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure)); 1665b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(addOneFigure.get()), 1666b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add even-odd flip figure to shaded path."); 1667b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1668b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsFillRule = XPS_FILL_RULE_EVENODD; 1669b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com break; 1670b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1671b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com default: 1672330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("Unknown SkPath::FillType."); 1673b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1674b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetFillRule(xpsFillRule), 1675b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill rule for shaded path."); 167674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1677b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the XPS transform, if possible. 1678b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransformsPath) { 1679b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1680b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsTransform(matrix, &xpsTransform)); 168174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1682b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1683b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1684b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform on shaded path."); 1685b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1686b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xpsTransformsPath = false; 1687b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1688b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 168974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 169076db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman SkPath* devicePath = xpsCompatiblePath; 1691b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!xpsTransformsPath) { 1692b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //[Fillable-path -> Device-path] 169376db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath; 169476db31a2ca11da4dd45016e964b2e49f39f3dd49bungeman xpsCompatiblePath->transform(matrix, devicePath); 1695b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1696b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->addXpsPathGeometry(shadedFigures.get(), 1697b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com stroke, fill, *devicePath)); 169874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1699a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->clip(shadedPath.get())); 170074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1701b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the path to the active visual collection. 1702b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1703b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1704b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for shaded path."); 1705b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1706b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add shaded path to current visuals."); 1707b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1708b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1709a1361364e64138adda3dc5f71d50d7503838bb6dMike ReedHRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) { 1710b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath clipPath; 1711a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // clipPath.addRect(this->cs().bounds(size(*this))); 1712a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed (void)this->cs().asPath(&clipPath); 1713b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD); 1714b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1715b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual, 1716b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPath& clipPath, 1717b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FILL_RULE fillRule) { 1718b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the geometry. 1719b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> clipGeometry; 1720b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateGeometry(&clipGeometry), 1721b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create clip geometry."); 172274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1723b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the figure collection of the geometry. 1724b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> clipFigures; 1725b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clipGeometry->GetFigures(&clipFigures), 1726b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get the clip figures."); 172774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1728b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the figures into the geometry. 1729b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->addXpsPathGeometry( 1730b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com clipFigures.get(), 1731b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FALSE, TRUE, clipPath)); 173274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1733b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(clipGeometry->SetFillRule(fillRule), 1734b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill rule."); 1735b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(xpsVisual->SetClipGeometryLocal(clipGeometry.get()), 1736b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set clip geometry."); 173774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1738b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1739b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1740b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1741a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawBitmap(const SkBitmap& bitmap, 1742b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary SkScalar x, 1743b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary SkScalar y, 1744b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary const SkPaint& paint) { 1745a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (this->cs().isEmpty(size(*this))) { 1746b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 1747b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 174874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1749b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIRect srcRect; 17509bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com srcRect.set(0, 0, bitmap.width(), bitmap.height()); 175174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1752b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the new shaded path. 1753b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMPath> shadedPath; 1754b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1755b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create path for bitmap."); 175674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1757b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Create the shaded geometry. 1758b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1759b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1760b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create geometry for bitmap."); 176174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1762b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Add the shaded geometry to the shaded path. 1763b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1764b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set the geometry for bitmap."); 176574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1766b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the shaded figures from the shaded geometry. 1767b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1768b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->GetFigures(&shadedFigures), 1769b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get the figures for bitmap."); 177074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1771b964238f0bded00bae59c26c5f366a7780a0ef5fHal Canary SkMatrix transform = SkMatrix::MakeTrans(x, y); 1772a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed transform.postConcat(this->ctm()); 177374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1774b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1775b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsTransform(transform, &xpsTransform)); 1776b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsTransform.get()) { 1777b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1778b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform for bitmap."); 1779b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1780b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: perspective that bitmap! 1781b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 178274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1783b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 178449f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsTransform.get()) { 1785b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkShader::TileMode xy[2] = { 1786b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode, 1787b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkShader::kClamp_TileMode, 1788b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 1789b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMTileBrush> xpsImageBrush; 17909bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com HRV(this->createXpsImageBrush(bitmap, 1791b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com transform, 1792b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com xy, 1793b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getAlpha(), 1794b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsImageBrush)); 1795b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedPath->SetFillBrushLocal(xpsImageBrush.get()), 1796b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set bitmap brush."); 179774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1798b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkRect bitmapRect = SkRect::MakeLTRB(0, 0, 1799b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1800b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(this->createXpsRect(bitmapRect, FALSE, TRUE, &rectFigure)); 1801b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1802b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(shadedFigures->Append(rectFigure.get()), 1803b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add bitmap figure."); 180474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1805b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the current visual collection and add the shaded path to it. 1806b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1807b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1808b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for bitmap"); 1809b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(shadedPath.get()), 1810b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add bitmap to current visuals."); 181174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1812a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(this->clip(shadedPath.get())); 1813b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1814b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1815a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { 1816b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: override this for XPS 1817b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkDEBUGF(("XPS drawSprite not yet implemented.")); 1818b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1819b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1820b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comHRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint, 1821b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse** typefaceUse) { 1822398de9ad9cb1ed3aa97aaf023d7f8287b8e62601reed@google.com SkAutoResolveDefaultTypeface typeface(paint.getTypeface()); 182374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1824b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Check cache. 1825398de9ad9cb1ed3aa97aaf023d7f8287b8e62601reed@google.com const SkFontID typefaceID = typeface->uniqueID(); 1826b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!this->fTypefaces.empty()) { 1827b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* current = &this->fTypefaces.front(); 1828b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const TypefaceUse* last = &this->fTypefaces.back(); 1829b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com for (; current <= last; ++current) { 1830b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (current->typefaceId == typefaceID) { 1831b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *typefaceUse = current; 1832b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1833b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1834b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1835b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 183674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1837b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: create glyph only fonts 1838b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //and let the host deal with what kind of font we're looking at. 1839b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_RESTRICTED; 184074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1841b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IStream> fontStream; 1842b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org int ttcIndex; 1843b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org SkStream* fontData = typeface->openStream(&ttcIndex); 1844635091f0a98b7d86a74baff11ae5e304062d8420bungeman@google.com //TODO: cannot handle FON fonts. 18458cddc8d0ea02b3476fd57668cf9b25ba5b9770d8bungeman@google.com HRM(SkIStream::CreateFromSkStream(fontData, true, &fontStream), 1846b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font stream."); 184774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1848b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const size_t size = 1849b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SK_ARRAY_COUNT(L"/Resources/Fonts/" L_GUID_ID L".odttf"); 1850b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t buffer[size]; 1851b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com wchar_t id[GUID_ID_LEN]; 1852da5a1b8cd80bbea1dfdb474c6917a1f13a0e7f9eBen Wagner HR(this->createId(id, GUID_ID_LEN)); 1853b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com swprintf_s(buffer, size, L"/Resources/Fonts/%s.odttf", id); 185474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1855b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IOpcPartUri> partUri; 1856b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 1857b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font resource part uri."); 185874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1859b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMFontResource> xpsFontResource; 1860b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateFontResource(fontStream.get(), 1861b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com embedding, 1862b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com partUri.get(), 1863b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FALSE, 1864b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFontResource), 1865b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create font resource."); 186674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1867b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org //TODO: change openStream to return -1 for non-ttc, get rid of this. 1868b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org uint8_t* data = (uint8_t*)fontData->getMemoryBase(); 1869b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org bool isTTC = (data && 1870b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org fontData->getLength() >= sizeof(SkTTCFHeader) && 1871b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org ((SkTTCFHeader*)data)->ttcTag == SkTTCFHeader::TAG); 1872b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org 1873b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse& newTypefaceUse = this->fTypefaces.push_back(); 1874b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.typefaceId = typefaceID; 1875b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org newTypefaceUse.ttcIndex = isTTC ? ttcIndex : -1; 1876b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.fontData = fontData; 1877b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.xpsFont = xpsFontResource.release(); 187874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 18798e0c1500a78f450115ce1a8de438d66e2e892cdcrobertphillips SkAutoGlyphCache agc(paint, &this->surfaceProps(), &SkMatrix::I()); 1880b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkGlyphCache* glyphCache = agc.getCache(); 1881b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com unsigned int glyphCount = glyphCache->getGlyphCount(); 1882b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount); 188374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1884b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com *typefaceUse = &newTypefaceUse; 1885b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1886b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1887b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1888a1361364e64138adda3dc5f71d50d7503838bb6dMike ReedHRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory, 1889b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com IXpsOMCanvas* canvas, 1890b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org TypefaceUse* font, 1891b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com LPCWSTR text, 1892b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_GLYPH_INDEX* xpsGlyphs, 1893b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com UINT32 xpsGlyphsLen, 1894b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT *origin, 1895b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com FLOAT fontSize, 1896b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION sims, 1897b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkMatrix& transform, 1898b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 1899b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGlyphs> glyphs; 1900b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org HRM(xpsFactory->CreateGlyphs(font->xpsFont, &glyphs), "Could not create glyphs."); 1901b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org HRM(glyphs->SetFontFaceIndex(font->ttcIndex), "Could not set glyph font face index."); 190274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1903b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //XPS uses affine transformations for everything... 1904b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //...except positioning text. 1905b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com bool useCanvasForClip; 1906b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if ((transform.getType() & ~SkMatrix::kTranslate_Mask) == 0) { 1907b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com origin->x += SkScalarToFLOAT(transform.getTranslateX()); 1908b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com origin->y += SkScalarToFLOAT(transform.getTranslateY()); 1909b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = false; 1910b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1911b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 1912b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsTransform(transform, &xpsMatrixToUse)); 1913b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (xpsMatrixToUse.get()) { 1914b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetTransformLocal(xpsMatrixToUse.get()), 1915b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set transform matrix."); 1916b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = true; 1917b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1918330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com SkDEBUGFAIL("Attempt to add glyphs in perspective."); 1919b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com useCanvasForClip = false; 1920b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1921b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 192274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1923b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor; 1924b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor."); 192574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 192649f085dddff10473b6ebf832a974288300224e60bsalomon if (text) { 1927b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->SetUnicodeString(text), 1928b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set unicode string."); 1929b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 193074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 193149f085dddff10473b6ebf832a974288300224e60bsalomon if (xpsGlyphs) { 1932b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->SetGlyphIndices(xpsGlyphsLen, xpsGlyphs), 1933b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set glyphs."); 1934b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 193574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1936b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphsEditor->ApplyEdits(), "Could not apply glyph edits."); 193774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1938b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMBrush> xpsFillBrush; 1939b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HR(this->createXpsBrush( 1940b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint, 1941b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &xpsFillBrush, 194296fcdcc219d2a0d3579719b84b28bede76efba64halcanary useCanvasForClip ? nullptr : &transform)); 194374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1944b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetFillBrushLocal(xpsFillBrush.get()), 1945b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set fill brush."); 194674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1947b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetOrigin(origin), "Could not set glyph origin."); 194874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1949b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetFontRenderingEmSize(fontSize), 1950b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set font size."); 195174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1952b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphs->SetStyleSimulations(sims), 1953b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set style simulations."); 195474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1955b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> visuals; 1956b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals."); 195774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1958b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (!useCanvasForClip) { 1959a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HR(this->clip(glyphs.get())); 1960b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas."); 1961b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } else { 1962b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMCanvas> glyphCanvas; 1963b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(this->fXpsFactory->CreateCanvas(&glyphCanvas), 1964b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create glyph canvas."); 196574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1966b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> glyphCanvasVisuals; 1967b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphCanvas->GetVisuals(&glyphCanvasVisuals), 1968b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get glyph visuals collection."); 196974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1970b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(glyphCanvasVisuals->Append(glyphs.get()), 1971b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add glyphs to page."); 1972a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HR(this->clip(glyphCanvas.get())); 197374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1974b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRM(visuals->Append(glyphCanvas.get()), 1975b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add glyph canvas to page."); 1976b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 197774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1978b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return S_OK; 1979b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1980b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1981bda26436faacf21ae2afd572aacd45eaa79fd0a6herbstatic int num_glyph_guess(SkPaint::TextEncoding encoding, const void* text, size_t byteLength) { 1982bda26436faacf21ae2afd572aacd45eaa79fd0a6herb switch (encoding) { 1983bda26436faacf21ae2afd572aacd45eaa79fd0a6herb case SkPaint::kUTF8_TextEncoding: 1984889d521d8715f4934accb630097bc09bf7ad1a32Mike Reed return SkUTF8_CountUnichars(text, byteLength); 1985bda26436faacf21ae2afd572aacd45eaa79fd0a6herb case SkPaint::kUTF16_TextEncoding: 1986889d521d8715f4934accb630097bc09bf7ad1a32Mike Reed return SkUTF16_CountUnichars(text, byteLength); 1987bda26436faacf21ae2afd572aacd45eaa79fd0a6herb case SkPaint::kGlyphID_TextEncoding: 1988bda26436faacf21ae2afd572aacd45eaa79fd0a6herb return SkToInt(byteLength / 2); 1989bda26436faacf21ae2afd572aacd45eaa79fd0a6herb default: 1990f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollen SK_ABORT("Invalid Text Encoding"); 1991b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 1992bda26436faacf21ae2afd572aacd45eaa79fd0a6herb return 0; 1993b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 1994b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 1995b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comstatic bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 1996b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint::Style style = paint.getStyle(); 1997b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return matrix.hasPerspective() 1998b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStroke_Style == style 1999b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || SkPaint::kStrokeAndFill_Style == style 2000b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com || paint.getMaskFilter() 2001b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com ; 2002b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2003b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2004bda26436faacf21ae2afd572aacd45eaa79fd0a6herbtypedef SkTDArray<XPS_GLYPH_INDEX> GlyphRun; 2005bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2006bda26436faacf21ae2afd572aacd45eaa79fd0a6herbclass ProcessOneGlyph { 2007bda26436faacf21ae2afd572aacd45eaa79fd0a6herbpublic: 2008bda26436faacf21ae2afd572aacd45eaa79fd0a6herb ProcessOneGlyph(FLOAT centemPerUnit, SkBitSet* glyphUse, GlyphRun* xpsGlyphs) 2009bda26436faacf21ae2afd572aacd45eaa79fd0a6herb : fCentemPerUnit(centemPerUnit) 2010bda26436faacf21ae2afd572aacd45eaa79fd0a6herb , fGlyphUse(glyphUse) 2011bda26436faacf21ae2afd572aacd45eaa79fd0a6herb , fXpsGlyphs(xpsGlyphs) { } 2012bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2013bda26436faacf21ae2afd572aacd45eaa79fd0a6herb void operator()(const SkGlyph& glyph, SkPoint position, SkPoint) { 2014bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); 2015bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2016bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkScalar x = position.fX; 2017bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkScalar y = position.fY; 2018bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2019bda26436faacf21ae2afd572aacd45eaa79fd0a6herb XPS_GLYPH_INDEX* xpsGlyph = fXpsGlyphs->append(); 2020bda26436faacf21ae2afd572aacd45eaa79fd0a6herb uint16_t glyphID = glyph.getGlyphID(); 2021e2348ccb477b97847cd147161a57fbbbfc8bba10halcanary fGlyphUse->set(glyphID); 2022bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->index = glyphID; 2023bda26436faacf21ae2afd572aacd45eaa79fd0a6herb if (1 == fXpsGlyphs->count()) { 2024bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->advanceWidth = 0.0f; 2025bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->horizontalOffset = SkScalarToFloat(x) * fCentemPerUnit; 2026bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->verticalOffset = SkScalarToFloat(y) * -fCentemPerUnit; 2027bda26436faacf21ae2afd572aacd45eaa79fd0a6herb } 2028bda26436faacf21ae2afd572aacd45eaa79fd0a6herb else { 2029bda26436faacf21ae2afd572aacd45eaa79fd0a6herb const XPS_GLYPH_INDEX& first = (*fXpsGlyphs)[0]; 2030bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->advanceWidth = 0.0f; 2031bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * fCentemPerUnit) 2032bda26436faacf21ae2afd572aacd45eaa79fd0a6herb - first.horizontalOffset; 2033bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -fCentemPerUnit) 2034bda26436faacf21ae2afd572aacd45eaa79fd0a6herb - first.verticalOffset; 2035bda26436faacf21ae2afd572aacd45eaa79fd0a6herb } 2036bda26436faacf21ae2afd572aacd45eaa79fd0a6herb } 2037bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2038bda26436faacf21ae2afd572aacd45eaa79fd0a6herbprivate: 2039bda26436faacf21ae2afd572aacd45eaa79fd0a6herb /** [in] Advance width and offsets for glyphs measured in 2040bda26436faacf21ae2afd572aacd45eaa79fd0a6herb hundredths of the font em size (XPS Spec 5.1.3). */ 2041bda26436faacf21ae2afd572aacd45eaa79fd0a6herb const FLOAT fCentemPerUnit; 2042bda26436faacf21ae2afd572aacd45eaa79fd0a6herb /** [in,out] The accumulated glyphs used in the current typeface. */ 2043bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkBitSet* const fGlyphUse; 2044bda26436faacf21ae2afd572aacd45eaa79fd0a6herb /** [out] The glyphs to draw. */ 2045bda26436faacf21ae2afd572aacd45eaa79fd0a6herb GlyphRun* const fXpsGlyphs; 2046bda26436faacf21ae2afd572aacd45eaa79fd0a6herb}; 2047bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2048a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawText(const void* text, size_t byteLen, 2049b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalar x, SkScalar y, 2050b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint& paint) { 2051b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (byteLen < 1) return; 205274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2053a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (text_must_be_pathed(paint, this->ctm())) { 2054b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath path; 2055b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint.getTextPath(text, byteLen, x, y, &path); 2056a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->drawPath(path, paint, nullptr, true); 2057b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: add automation "text" 2058b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 2059b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 206074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2061b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* typeface; 2062b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(CreateTypefaceUse(paint, &typeface)); 206374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2064bda26436faacf21ae2afd572aacd45eaa79fd0a6herb const SkMatrix& matrix = SkMatrix::I(); 2065bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2066bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix); 2067bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkGlyphCache* cache = autoCache.getCache(); 2068bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2069bda26436faacf21ae2afd572aacd45eaa79fd0a6herb // Advance width and offsets for glyphs measured in hundredths of the font em size 2070bda26436faacf21ae2afd572aacd45eaa79fd0a6herb // (XPS Spec 5.1.3). 2071bda26436faacf21ae2afd572aacd45eaa79fd0a6herb FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); 2072bda26436faacf21ae2afd572aacd45eaa79fd0a6herb GlyphRun xpsGlyphs; 2073bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(), 2074bda26436faacf21ae2afd572aacd45eaa79fd0a6herb static_cast<const char*>(text), byteLen)); 207574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2076bda26436faacf21ae2afd572aacd45eaa79fd0a6herb ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs); 2077089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2078bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkFindAndPlaceGlyph::ProcessText( 2079bda26436faacf21ae2afd572aacd45eaa79fd0a6herb paint.getTextEncoding(), static_cast<const char*>(text), byteLen, 2080bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkPoint{ x, y }, matrix, paint.getTextAlign(), cache, processOneGlyph); 2081bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2082bda26436faacf21ae2afd572aacd45eaa79fd0a6herb if (xpsGlyphs.count() == 0) { 2083089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com return; 2084089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com } 2085089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2086b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT origin = { 2087bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].horizontalOffset / centemPerUnit, 2088bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].verticalOffset / -centemPerUnit, 2089b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 2090bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].horizontalOffset = 0.0f; 2091bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].verticalOffset = 0.0f; 209274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2093a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(AddGlyphs(this->fXpsFactory.get(), 2094b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.get(), 2095b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org typeface, 209696fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 2097bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs.begin(), xpsGlyphs.count(), 2098b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &origin, 2099b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(paint.getTextSize()), 2100b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION_NONE, 2101a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->ctm(), 2102b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint)); 2103b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2104b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2105a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawPosText(const void* text, size_t byteLen, 210605c4a4322e7d4f3417b7df33825bab8603d52051fmalita const SkScalar pos[], int scalarsPerPos, 210705c4a4322e7d4f3417b7df33825bab8603d52051fmalita const SkPoint& offset, const SkPaint& paint) { 2108b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com if (byteLen < 1) return; 210974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2110a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed if (text_must_be_pathed(paint, this->ctm())) { 2111b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkPath path; 2112b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: make this work, Draw currently does not handle as well. 2113b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //paint.getTextPath(text, byteLength, x, y, &path); 2114a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed //this->drawPath(path, paint, nullptr, true); 2115b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //TODO: add automation "text" 2116b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com return; 2117b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 211874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2119b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com TypefaceUse* typeface; 2120b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRV(CreateTypefaceUse(paint, &typeface)); 212174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2122bda26436faacf21ae2afd572aacd45eaa79fd0a6herb const SkMatrix& matrix = SkMatrix::I(); 2123bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2124bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix); 2125bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkGlyphCache* cache = autoCache.getCache(); 2126bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2127bda26436faacf21ae2afd572aacd45eaa79fd0a6herb // Advance width and offsets for glyphs measured in hundredths of the font em size 2128bda26436faacf21ae2afd572aacd45eaa79fd0a6herb // (XPS Spec 5.1.3). 2129bda26436faacf21ae2afd572aacd45eaa79fd0a6herb FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); 2130bda26436faacf21ae2afd572aacd45eaa79fd0a6herb GlyphRun xpsGlyphs; 2131bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(), 2132bda26436faacf21ae2afd572aacd45eaa79fd0a6herb static_cast<const char*>(text), byteLen)); 2133bda26436faacf21ae2afd572aacd45eaa79fd0a6herb 2134bda26436faacf21ae2afd572aacd45eaa79fd0a6herb ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs); 213574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2136bda26436faacf21ae2afd572aacd45eaa79fd0a6herb SkFindAndPlaceGlyph::ProcessPosText( 2137bda26436faacf21ae2afd572aacd45eaa79fd0a6herb paint.getTextEncoding(), static_cast<const char*>(text), byteLen, 2138bda26436faacf21ae2afd572aacd45eaa79fd0a6herb offset, matrix, pos, scalarsPerPos, paint.getTextAlign(), cache, processOneGlyph); 213974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2140bda26436faacf21ae2afd572aacd45eaa79fd0a6herb if (xpsGlyphs.count() == 0) { 2141089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com return; 2142089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com } 2143089130c24e29dd0ffc53f0396acdc8f0b50dabd4reed@google.com 2144b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_POINT origin = { 2145bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].horizontalOffset / centemPerUnit, 2146bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].verticalOffset / -centemPerUnit, 2147b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com }; 2148bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].horizontalOffset = 0.0f; 2149bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs[0].verticalOffset = 0.0f; 215074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2151a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed HRV(AddGlyphs(this->fXpsFactory.get(), 2152b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com this->fCurrentXpsCanvas.get(), 2153b5e34e22aa0e019e25f9f913f0e119a9a97e5562commit-bot@chromium.org typeface, 215496fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 2155bda26436faacf21ae2afd572aacd45eaa79fd0a6herb xpsGlyphs.begin(), xpsGlyphs.count(), 2156b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com &origin, 2157b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkScalarToFLOAT(paint.getTextSize()), 2158b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com XPS_STYLE_SIMULATION_NONE, 2159a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->ctm(), 2160b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com paint)); 2161b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2162b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2163a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawDevice( SkBaseDevice* dev, 2164b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com int x, int y, 2165b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com const SkPaint&) { 2166b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkXPSDevice* that = static_cast<SkXPSDevice*>(dev); 216774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2168b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 2169a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed // TODO(halcanary): assert that current transform is identity rather than calling setter. 2170a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed XPS_MATRIX rawTransform = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; 2171b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform), 2172b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not create layer transform."); 2173b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()), 2174b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not set layer transform."); 217574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2176b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //Get the current visual collection and add the layer to it. 2177b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 2178b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 2179b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not get current visuals for layer."); 2180b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com HRVM(currentVisuals->Append(that->fCurrentXpsCanvas.get()), 2181b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com "Could not add layer to current visuals."); 2182b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2183b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 218476033be81b82c44fd5d4fdf2672eb22e505da1f0reedSkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*) { 2185635091f0a98b7d86a74baff11ae5e304062d8420bungeman@google.com//Conditional for bug compatibility with PDF device. 2186635091f0a98b7d86a74baff11ae5e304062d8420bungeman@google.com#if 0 21876987dcaf257dd7c2c8e0014cf7452fde82bcba5bfmalita if (SkBaseDevice::kGeneral_Usage == info.fUsage) { 218896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 2189b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //To what stream do we write? 2190b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //SkXPSDevice* dev = new SkXPSDevice(this); 2191b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //SkSize s = SkSize::Make(width, height); 2192b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //dev->BeginCanvas(s, s, SkMatrix::I()); 2193b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com //return dev; 2194b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com } 2195635091f0a98b7d86a74baff11ae5e304062d8420bungeman@google.com#endif 2196abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary SkXPSDevice* dev = new SkXPSDevice(info.fInfo.dimensions()); 2197abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary // TODO(halcanary) implement copy constructor on SkTScopedCOmPtr 2198abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary dev->fXpsFactory.reset(SkRefComPtr(fXpsFactory.get())); 2199abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary SkAssertResult(dev->createCanvasForLayer()); 2200abc88d26365efa14b58d26ca3b8fbfb58a7dcbadHal Canary return dev; 2201b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com} 2202b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com 2203a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) { 2204b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkPath path; 2205b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary path.addOval(o); 2206a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed this->drawPath(path, p, nullptr, true); 2207b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary} 2208b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary 2209a1361364e64138adda3dc5f71d50d7503838bb6dMike Reedvoid SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap, 2210a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkRect* src, 2211a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkRect& dst, 2212a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed const SkPaint& paint, 2213a1361364e64138adda3dc5f71d50d7503838bb6dMike Reed SkCanvas::SrcRectConstraint constraint) { 22147da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary SkRect bitmapBounds = SkRect::Make(bitmap.bounds()); 22157da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary SkRect srcBounds = src ? *src : bitmapBounds; 2216b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkMatrix matrix = SkMatrix::MakeRectToRect(srcBounds, dst, SkMatrix::kFill_ScaleToFit); 22177da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary SkRect actualDst; 22187da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary if (!src || bitmapBounds.contains(*src)) { 22197da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary actualDst = dst; 22207da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary } else { 22217da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary if (!srcBounds.intersect(bitmapBounds)) { 22227da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary return; 22237da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary } 22247da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary matrix.mapRect(&actualDst, srcBounds); 22257da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary } 2226b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary auto bitmapShader = SkMakeBitmapShader(bitmap, SkShader::kClamp_TileMode, 2227b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkShader::kClamp_TileMode, &matrix, 2228bfdc87a62193aae20fac0bce37bed7b656f299bbHerb Derby kNever_SkCopyPixelsMode); 2229b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkASSERT(bitmapShader); 2230b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary if (!bitmapShader) { return; } 2231b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary SkPaint paintWithShader(paint); 2232b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary paintWithShader.setStyle(SkPaint::kFill_Style); 2233b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary paintWithShader.setShader(std::move(bitmapShader)); 22347da8d646a2114b252e79a0c93a4aeb153d2e1390Hal Canary this->drawRect(actualDst, paintWithShader); 2235b39b09e4477f5c51b27015a17c7ac699028c4d87Hal Canary} 22368f11d4dcafef4447fa68ea0ab28a72589241e9fdMike Klein#endif//defined(SK_BUILD_FOR_WIN) 2237