1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if defined(SK_BUILD_FOR_WIN) 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkLeanWindows.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef UNICODE 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define UNICODE 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef _UNICODE 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define _UNICODE 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <ObjBase.h> 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <XpsObjectModel.h> 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <T2EmbApi.h> 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <FontSub.h> 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <limits> 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColor.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkData.h" 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkDraw.h" 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkEndian.h" 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkFindAndPlaceGlyph.h" 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGeometry.h" 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGlyphCache.h" 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkHRESULT.h" 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkIStream.h" 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImage.h" 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImageEncoder.h" 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImagePriv.h" 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMaskFilterBase.h" 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h" 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathEffect.h" 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOps.h" 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPoint.h" 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRasterClip.h" 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSFNTHeader.h" 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h" 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSize.h" 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkStream.h" 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTDArray.h" 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTLazy.h" 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTScopedComPtr.h" 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTTCFHeader.h" 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypefacePriv.h" 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkUtils.h" 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkVertices.h" 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkXPSDevice.h" 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Windows defines a FLOAT type, 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//make it clear when converting a scalar that this is what is wanted. 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkScalarToFLOAT(n) SkScalarToFloat(n) 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Dummy representation of a GUID from createId. 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define L_GUID_ID L"XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX" 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Length of GUID representation from createId, including nullptr terminator. 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define GUID_ID_LEN SK_ARRAY_COUNT(L_GUID_ID) 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/** 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Formats a GUID and places it into buffer. 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot buffer should have space for at least GUID_ID_LEN wide characters. 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot The string will always be wchar null terminated. 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XXXXXXXXsXXXXsXXXXsXXXXsXXXXXXXXXXXX0 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot @return -1 if there was an error, > 0 if success. 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic int format_guid(const GUID& guid, 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t* buffer, size_t bufferSize, 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t sep = '-') { 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(bufferSize >= GUID_ID_LEN); 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return swprintf_s(buffer, 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bufferSize, 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot L"%08lX%c%04X%c%04X%c%02X%02X%c%02X%02X%02X%02X%02X%02X", 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data1, 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sep, 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data2, 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sep, 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data3, 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sep, 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[0], 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[1], 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sep, 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[2], 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[3], 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[4], 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[5], 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[6], 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[7]); 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createId(wchar_t* buffer, size_t bufferSize, wchar_t sep) { 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GUID guid = {}; 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_XPS_USE_DETERMINISTIC_IDS 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data1 = fNextId++; 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The following make this a valid Type4 UUID. 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data3 = 0x4000; 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot guid.Data4[0] = 0x80; 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(CoCreateGuid(&guid), "Could not create GUID for id."); 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (format_guid(guid, buffer, bufferSize, sep) == -1) { 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(E_UNEXPECTED, "Could not format GUID into id."); 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkXPSDevice::SkXPSDevice(SkISize s) 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(SkImageInfo::MakeUnknown(s.width(), s.height()), 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSurfaceProps(0, kUnknown_SkPixelGeometry)) 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fCurrentPage(0) {} 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkXPSDevice::~SkXPSDevice() {} 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkXPSDevice::TypefaceUse::TypefaceUse() 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : typefaceId(0xffffffff) 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fontData(nullptr) 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , xpsFont(nullptr) 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , glyphsUsed(nullptr) {} 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkXPSDevice::TypefaceUse::~TypefaceUse() { 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //xpsFont owns fontData ref 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->xpsFont->Release(); 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot delete this->glyphsUsed; 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkXPSDevice::beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory* factory) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(factory); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fXpsFactory.reset(SkRefComPtr(factory)); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRB(SkWIStream::CreateFromSkWStream(outputStream, &this->fOutputStream)); 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkXPSDevice::beginSheet( 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& unitsPerMeter, 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& pixelsPerMeter, 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkSize& trimSize, 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect* mediaBox, 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect* bleedBox, 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect* artBox, 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect* cropBox) { 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++this->fCurrentPage; 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //For simplicity, just write everything out in geometry units, 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //then have a base canvas do the scale to physical units. 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentCanvasSize = trimSize; 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentUnitsPerMeter = unitsPerMeter; 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentPixelsPerMeter = pixelsPerMeter; 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->createCanvasForLayer(); 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkXPSDevice::createCanvasForLayer() { 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fXpsFactory); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCurrentXpsCanvas.reset(); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRB(fXpsFactory->CreateCanvas(&fCurrentXpsCanvas)); 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename T> static constexpr size_t sk_digits_in() { 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<size_t>(std::numeric_limits<T>::digits10 + 1); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsThumbnail(IXpsOMPage* page, 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const unsigned int pageNum, 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMImageResource** image) { 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMThumbnailGenerator> thumbnailGenerator; 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(CoCreateInstance( 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CLSID_XpsOMThumbnailGenerator, 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CLSCTX_INPROC_SERVER, 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IID_PPV_ARGS(&thumbnailGenerator)), 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create thumbnail generator."); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr size_t size = SkTMax( 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(L"/Documents/1/Metadata/.png") + sk_digits_in<decltype(pageNum)>(), 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(L"/Metadata/" L_GUID_ID L".png")); 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t buffer[size]; 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (pageNum > 0) { 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot swprintf_s(buffer, size, L"/Documents/1/Metadata/%u.png", pageNum); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t id[GUID_ID_LEN]; 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createId(id, GUID_ID_LEN)); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot swprintf_s(buffer, size, L"/Metadata/%s.png", id); 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create thumbnail part uri."); 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(thumbnailGenerator->GenerateThumbnail(page, 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_IMAGE_TYPE_PNG, 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_THUMBNAIL_SIZE_LARGE, 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot partUri.get(), 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot image), 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not generate thumbnail."); 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsPage(const XPS_SIZE& pageSize, 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMPage** page) { 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot constexpr size_t size = 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(L"/Documents/1/Pages/.fpage") 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot + sk_digits_in<decltype(fCurrentPage)>(); 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t buffer[size]; 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot swprintf_s(buffer, size, L"/Documents/1/Pages/%u.fpage", 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentPage); 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create page part uri."); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //If the language is unknown, use "und" (XPS Spec 2.3.5.1). 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePage(&pageSize, 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot L"und", 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot partUri.get(), 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot page), 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create page."); 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::initXpsDocumentWriter(IXpsOMImageResource* image) { 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create package writer. 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri(L"/FixedDocumentSequence.fdseq", 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &partUri), 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create document sequence part uri."); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePackageWriterOnStream( 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fOutputStream.get(), 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TRUE, 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_INTERLEAVING_OFF, //XPS_INTERLEAVING_ON, 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot partUri.get(), 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot image, 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &this->fPackageWriter), 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create package writer."); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Begin the lone document. 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri( 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot L"/Documents/1/FixedDocument.fdoc", 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &partUri), 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create fixed document part uri."); 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fPackageWriter->StartNewDocument(partUri.get(), 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr), 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not start document."); 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkXPSDevice::endSheet() { 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //XPS is fixed at 96dpi (XPS Spec 11.1). 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const float xpsDPI = 96.0f; 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const float inchesPerMeter = 10000.0f / 254.0f; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static const float targetUnitsPerMeter = xpsDPI * inchesPerMeter; 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const float scaleX = targetUnitsPerMeter 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fX); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const float scaleY = targetUnitsPerMeter 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot / SkScalarToFLOAT(this->fCurrentUnitsPerMeter.fY); 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the scale canvas. 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMCanvas> scaleCanvas; 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(this->fXpsFactory->CreateCanvas(&scaleCanvas), 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create scale canvas."); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> scaleCanvasVisuals; 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(scaleCanvas->GetVisuals(&scaleCanvasVisuals), 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get scale canvas visuals."); 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> geomToPhys; 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_MATRIX rawGeomToPhys = { scaleX, 0, 0, scaleY, 0, 0, }; 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(this->fXpsFactory->CreateMatrixTransform(&rawGeomToPhys, &geomToPhys), 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create geometry to physical transform."); 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(scaleCanvas->SetTransformLocal(geomToPhys.get()), 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform on scale canvas."); 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the content canvas to the scale canvas. 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(scaleCanvasVisuals->Append(this->fCurrentXpsCanvas.get()), 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add base canvas to scale canvas."); 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the page. 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SIZE pageSize = { 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(this->fCurrentCanvasSize.width()) * scaleX, 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(this->fCurrentCanvasSize.height()) * scaleY, 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPage> page; 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRB(this->createXpsPage(pageSize, &page)); 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> pageVisuals; 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(page->GetVisuals(&pageVisuals), "Could not get page visuals."); 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the scale canvas to the page. 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(pageVisuals->Append(scaleCanvas.get()), 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add scale canvas to page."); 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the package writer if it hasn't been created yet. 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == this->fPackageWriter.get()) { 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMImageResource> image; 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Ignore return, thumbnail is completely optional. 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->createXpsThumbnail(page.get(), 0, &image); 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRB(this->initXpsDocumentWriter(image.get())); 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(this->fPackageWriter->AddPage(page.get(), 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &pageSize, 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr), 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not write the page."); 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentXpsCanvas.reset(); 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic HRESULT subset_typeface(SkXPSDevice::TypefaceUse* current) { 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //CreateFontPackage wants unsigned short. 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Microsoft, Y U NO stdint.h? 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<unsigned short> keepList; 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot current->glyphsUsed->exportTo(&keepList); 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int ttcCount = (current->ttcIndex + 1); 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //The following are declared with the types required by CreateFontPackage. 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned char *fontPackageBufferRaw = nullptr; 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned long fontPackageBufferSize; 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned long bytesWritten; 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned long result = CreateFontPackage( 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (unsigned char *) current->fontData->getMemoryBase(), 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (unsigned long) current->fontData->getLength(), 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fontPackageBufferRaw, 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fontPackageBufferSize, 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &bytesWritten, 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST | (ttcCount > 0 ? TTFCFP_FLAGS_TTC : 0), 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot current->ttcIndex, 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TTFCFP_SUBSET, 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0, 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0, 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0, 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot keepList.begin(), 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot keepList.count(), 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_malloc_throw, 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_realloc_throw, 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_free, 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr); 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoTMalloc<unsigned char> fontPackageBuffer(fontPackageBufferRaw); 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (result != NO_ERROR) { 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGF(("CreateFontPackage Error %lu", result)); 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return E_UNEXPECTED; 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If it was originally a ttc, keep it a ttc. 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // CreateFontPackage over-allocates, realloc usually decreases the size substantially. 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t extra; 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (ttcCount > 0) { 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Create space for a ttc header. 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot extra = sizeof(SkTTCFHeader) + (ttcCount * sizeof(SK_OT_ULONG)); 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fontPackageBuffer.realloc(bytesWritten + extra); 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //overlap is certain, use memmove 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memmove(fontPackageBuffer.get() + extra, fontPackageBuffer.get(), bytesWritten); 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Write the ttc header. 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTTCFHeader* ttcfHeader = reinterpret_cast<SkTTCFHeader*>(fontPackageBuffer.get()); 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ttcfHeader->ttcTag = SkTTCFHeader::TAG; 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ttcfHeader->version = SkTTCFHeader::version_1; 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ttcfHeader->numOffsets = SkEndian_SwapBE32(ttcCount); 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_OT_ULONG* offsetPtr = SkTAfter<SK_OT_ULONG>(ttcfHeader); 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < ttcCount; ++i, ++offsetPtr) { 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *offsetPtr = SkEndian_SwapBE32(SkToU32(extra)); 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Fix up offsets in sfnt table entries. 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSFNTHeader* sfntHeader = SkTAddOffset<SkSFNTHeader>(fontPackageBuffer.get(), extra); 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int numTables = SkEndian_SwapBE16(sfntHeader->numTables); 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkSFNTHeader::TableDirectoryEntry* tableDirectory = 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader); 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < numTables; ++i, ++tableDirectory) { 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tableDirectory->offset = SkEndian_SwapBE32( 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkToU32(SkEndian_SwapBE32(SkToU32(tableDirectory->offset)) + extra)); 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot extra = 0; 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fontPackageBuffer.realloc(bytesWritten); 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot std::unique_ptr<SkMemoryStream> newStream(new SkMemoryStream()); 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newStream->setMemoryOwned(fontPackageBuffer.release(), bytesWritten + extra); 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IStream> newIStream; 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIStream::CreateFromSkStream(newStream.release(), true, &newIStream); 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_FONT_EMBEDDING embedding; 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(current->xpsFont->GetEmbeddingOption(&embedding), 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get embedding option from font."); 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(current->xpsFont->GetPartName(&partUri), 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get part uri from font."); 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(current->xpsFont->SetContent( 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newIStream.get(), 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot embedding, 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot partUri.get()), 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set new stream for subsetted font."); 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool SkXPSDevice::endPortfolio() { 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Subset fonts 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->fTypefaces.empty()) { 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkXPSDevice::TypefaceUse* current = &this->fTypefaces.front(); 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const TypefaceUse* last = &this->fTypefaces.back(); 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (; current <= last; ++current) { 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Ignore return for now, if it didn't subset, let it be. 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot subset_typeface(current); 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRBM(this->fPackageWriter->Close(), "Could not close writer."); 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic XPS_COLOR xps_color(const SkColor skColor) { 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //XPS uses non-pre-multiplied alpha (XPS Spec 11.4). 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_COLOR xpsColor; 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsColor.colorType = XPS_COLOR_TYPE_SRGB; 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsColor.value.sRGB.alpha = SkColorGetA(skColor); 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsColor.value.sRGB.red = SkColorGetR(skColor); 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsColor.value.sRGB.green = SkColorGetG(skColor); 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsColor.value.sRGB.blue = SkColorGetB(skColor); 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return xpsColor; 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic XPS_POINT xps_point(const SkPoint& point) { 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT xpsPoint = { 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(point.fX), 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(point.fY), 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return xpsPoint; 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic XPS_POINT xps_point(const SkPoint& point, const SkMatrix& matrix) { 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint skTransformedPoint; 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot matrix.mapXY(point.fX, point.fY, &skTransformedPoint); 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return xps_point(skTransformedPoint); 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic XPS_SPREAD_METHOD xps_spread_method(SkShader::TileMode tileMode) { 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (tileMode) { 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkShader::kClamp_TileMode: 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return XPS_SPREAD_METHOD_PAD; 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkShader::kRepeat_TileMode: 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return XPS_SPREAD_METHOD_REPEAT; 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkShader::kMirror_TileMode: 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return XPS_SPREAD_METHOD_REFLECT; 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Unknown tile mode."); 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return XPS_SPREAD_METHOD_PAD; 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void transform_offsets(SkScalar* stopOffsets, const int numOffsets, 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint& start, const SkPoint& end, 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& transform) { 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint startTransformed; 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform.mapXY(start.fX, start.fY, &startTransformed); 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint endTransformed; 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform.mapXY(end.fX, end.fY, &endTransformed); 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Manhattan distance between transformed start and end. 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar startToEnd = (endTransformed.fX - startTransformed.fX) 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot + (endTransformed.fY - startTransformed.fY); 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkScalarNearlyZero(startToEnd)) { 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < numOffsets; ++i) { 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stopOffsets[i] = 0; 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < numOffsets; ++i) { 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint stop; 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stop.fX = (end.fX - start.fX) * stopOffsets[i]; 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stop.fY = (end.fY - start.fY) * stopOffsets[i]; 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint stopTransformed; 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform.mapXY(stop.fX, stop.fY, &stopTransformed); 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Manhattan distance between transformed start and stop. 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar startToStop = (stopTransformed.fX - startTransformed.fX) 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot + (stopTransformed.fY - startTransformed.fY); 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Percentage along transformed line. 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stopOffsets[i] = startToStop / startToEnd; 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsTransform(const SkMatrix& matrix, 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMMatrixTransform** xpsTransform) { 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar affine[6]; 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!matrix.asAffine(affine)) { 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *xpsTransform = nullptr; 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_FALSE; 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_MATRIX rawXpsMatrix = { 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kAScaleX]), 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kASkewY]), 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kASkewX]), 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kAScaleY]), 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kATransX]), 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(affine[SkMatrix::kATransY]), 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateMatrixTransform(&rawXpsMatrix, xpsTransform), 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create transform."); 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createPath(IXpsOMGeometryFigure* figure, 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMVisualCollection* visuals, 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMPath** path) { 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> geometry; 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateGeometry(&geometry), 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create geometry."); 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> figureCollection; 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(geometry->GetFigures(&figureCollection), "Could not get figures."); 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(figureCollection->Append(figure), "Could not add figure."); 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePath(path), "Could not create path."); 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM((*path)->SetGeometryLocal(geometry.get()), "Could not set geometry"); 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(visuals->Append(*path), "Could not add path to visuals."); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsSolidColorBrush(const SkColor skColor, 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkAlpha alpha, 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMBrush** xpsBrush) { 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_COLOR xpsColor = xps_color(skColor); 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMSolidColorBrush> solidBrush; 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateSolidColorBrush(&xpsColor, nullptr, &solidBrush), 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create solid color brush."); 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(solidBrush->SetOpacity(alpha / 255.0f), "Could not set opacity."); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(solidBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI Fail."); 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::sideOfClamp(const SkRect& areaToFill, 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const XPS_RECT& imageViewBox, 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMImageResource* image, 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMVisualCollection* visuals) { 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> areaToFillPath; 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMImageBrush> areaToFillBrush; 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateImageBrush(image, 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &imageViewBox, 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &imageViewBox, 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &areaToFillBrush), 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create brush for side of clamp."); 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(areaToFillBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set tile mode for side of clamp."); 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set brush for side of clamp"); 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::cornerOfClamp(const SkRect& areaToFill, 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor color, 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMVisualCollection* visuals) { 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> areaToFillFigure; 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsRect(areaToFill, FALSE, TRUE, &areaToFillFigure)); 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> areaToFillPath; 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createPath(areaToFillFigure.get(), visuals, &areaToFillPath)); 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMBrush> areaToFillBrush; 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(color, 0xFF, &areaToFillBrush)); 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(areaToFillPath->SetFillBrushLocal(areaToFillBrush.get()), 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set brush for corner of clamp."); 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const XPS_TILE_MODE XTM_N = XPS_TILE_MODE_NONE; 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const XPS_TILE_MODE XTM_T = XPS_TILE_MODE_TILE; 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const XPS_TILE_MODE XTM_X = XPS_TILE_MODE_FLIPX; 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const XPS_TILE_MODE XTM_Y = XPS_TILE_MODE_FLIPY; 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const XPS_TILE_MODE XTM_XY = XPS_TILE_MODE_FLIPXY; 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//TODO(bungeman): In the future, should skia add None, 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//handle None+Mirror and None+Repeat correctly. 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//None is currently an internal hack so masks don't repeat (None+None only). 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic XPS_TILE_MODE SkToXpsTileMode[SkShader::kTileModeCount+1] 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot [SkShader::kTileModeCount+1] = { 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Clamp //Repeat //Mirror //None 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /*Clamp */ {XTM_N, XTM_T, XTM_Y, XTM_N}, 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /*Repeat*/ {XTM_T, XTM_T, XTM_Y, XTM_N}, 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /*Mirror*/ {XTM_X, XTM_X, XTM_XY, XTM_X}, 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /*None */ {XTM_N, XTM_N, XTM_Y, XTM_N}, 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsImageBrush( 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkBitmap& bitmap, 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& localMatrix, 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkShader::TileMode (&xy)[2], 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkAlpha alpha, 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMTileBrush** xpsBrush) { 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDynamicMemoryWStream write; 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkEncodeImage(&write, bitmap, SkEncodedImageFormat::kPNG, 100)) { 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(E_FAIL, "Unable to encode bitmap as png."); 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMemoryStream* read = new SkMemoryStream; 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot read->setData(write.detachAsData()); 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IStream> readWrapper; 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(SkIStream::CreateFromSkStream(read, true, &readWrapper), 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create stream from png data."); 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t size = 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(L"/Documents/1/Resources/Images/" L_GUID_ID L".png"); 641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t buffer[size]; 642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t id[GUID_ID_LEN]; 643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createId(id, GUID_ID_LEN)); 644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot swprintf_s(buffer, size, L"/Documents/1/Resources/Images/%s.png", id); 645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> imagePartUri; 647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri(buffer, &imagePartUri), 648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create image part uri."); 649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMImageResource> imageResource; 651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateImageResource( 652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot readWrapper.get(), 653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_IMAGE_TYPE_PNG, 654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot imagePartUri.get(), 655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &imageResource), 656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create image resource."); 657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT bitmapRect = { 659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0.0, 0.0, 660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<FLOAT>(bitmap.width()), static_cast<FLOAT>(bitmap.height()) 661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMImageBrush> xpsImageBrush; 663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateImageBrush(imageResource.get(), 664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &bitmapRect, &bitmapRect, 665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &xpsImageBrush), 666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create image brush."); 667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kClamp_TileMode != xy[0] && 669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode != xy[1]) { 670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsImageBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set image tile mode"); 673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsImageBrush->SetOpacity(alpha / 255.0f), 674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set image opacity."); 675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsImageBrush->QueryInterface(xpsBrush), "QI failed."); 676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO(bungeman): compute how big this really needs to be. 678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar BIG = SkIntToScalar(1000); //SK_ScalarMax; 679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const FLOAT BIG_F = SkScalarToFLOAT(BIG); 680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar bWidth = SkIntToScalar(bitmap.width()); 681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar bHeight = SkIntToScalar(bitmap.height()); 682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //create brush canvas 684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMCanvas> brushCanvas; 685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateCanvas(&brushCanvas), 686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create image brush canvas."); 687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> brushVisuals; 688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(brushCanvas->GetVisuals(&brushVisuals), 689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get image brush canvas visuals collection."); 690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //create central figure 692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect bitmapPoints = SkRect::MakeLTRB(0, 0, bWidth, bHeight); 693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> centralFigure; 694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsRect(bitmapPoints, FALSE, TRUE, ¢ralFigure)); 695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> centralPath; 697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createPath(centralFigure.get(), 698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brushVisuals.get(), 699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ¢ralPath)); 700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsImageBrush->SetTileMode(XPS_TILE_MODE_FLIPXY), 701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set tile mode for image brush central path."); 702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(centralPath->SetFillBrushLocal(xpsImageBrush.get()), 703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set fill brush for image brush central path."); 704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //add left/right 706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kClamp_TileMode == xy[0]) { 707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect leftArea = SkRect::MakeLTRB(-BIG, 0, 0, bHeight); 708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT leftImageViewBox = { 709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0.0, 0.0, 710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1.0, static_cast<FLOAT>(bitmap.height()), 711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->sideOfClamp(leftArea, leftImageViewBox, 713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot imageResource.get(), 714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brushVisuals.get())); 715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect rightArea = SkRect::MakeLTRB(bWidth, 0, BIG, bHeight); 717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT rightImageViewBox = { 718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bitmap.width() - 1.0f, 0.0f, 719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1.0f, static_cast<FLOAT>(bitmap.height()), 720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->sideOfClamp(rightArea, rightImageViewBox, 722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot imageResource.get(), 723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brushVisuals.get())); 724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //add top/bottom 727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kClamp_TileMode == xy[1]) { 728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect topArea = SkRect::MakeLTRB(0, -BIG, bWidth, 0); 729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT topImageViewBox = { 730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0.0, 0.0, 731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<FLOAT>(bitmap.width()), 1.0, 732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->sideOfClamp(topArea, topImageViewBox, 734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot imageResource.get(), 735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brushVisuals.get())); 736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bottomArea = SkRect::MakeLTRB(0, bHeight, bWidth, BIG); 738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT bottomImageViewBox = { 739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0.0f, bitmap.height() - 1.0f, 740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<FLOAT>(bitmap.width()), 1.0f, 741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->sideOfClamp(bottomArea, bottomImageViewBox, 743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot imageResource.get(), 744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brushVisuals.get())); 745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //add tl, tr, bl, br 748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kClamp_TileMode == xy[0] && 749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode == xy[1]) { 750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor tlColor = bitmap.getColor(0,0); 752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect tlArea = SkRect::MakeLTRB(-BIG, -BIG, 0, 0); 753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->cornerOfClamp(tlArea, tlColor, brushVisuals.get())); 754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor trColor = bitmap.getColor(bitmap.width()-1,0); 756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect trArea = SkRect::MakeLTRB(bWidth, -BIG, BIG, 0); 757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->cornerOfClamp(trArea, trColor, brushVisuals.get())); 758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor brColor = bitmap.getColor(bitmap.width()-1, 760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bitmap.height()-1); 761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect brArea = SkRect::MakeLTRB(bWidth, bHeight, BIG, BIG); 762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->cornerOfClamp(brArea, brColor, brushVisuals.get())); 763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor blColor = bitmap.getColor(0,bitmap.height()-1); 765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect blArea = SkRect::MakeLTRB(-BIG, bHeight, 0, BIG); 766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->cornerOfClamp(blArea, blColor, brushVisuals.get())); 767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //create visual brush from canvas 770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_RECT bound = {}; 771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kClamp_TileMode == xy[0] && 772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode == xy[1]) { 773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.x = BIG_F / -2; 775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.y = BIG_F / -2; 776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.width = BIG_F; 777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.height = BIG_F; 778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (SkShader::kClamp_TileMode == xy[0]) { 779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.x = BIG_F / -2; 780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.y = 0.0f; 781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.width = BIG_F; 782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.height = static_cast<FLOAT>(bitmap.height()); 783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (SkShader::kClamp_TileMode == xy[1]) { 784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.x = 0; 785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.y = BIG_F / -2; 786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.width = static_cast<FLOAT>(bitmap.width()); 787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bound.height = BIG_F; 788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualBrush> clampBrush; 790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateVisualBrush(&bound, &bound, &clampBrush), 791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create visual brush for image brush."); 792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clampBrush->SetVisualLocal(brushCanvas.get()), 793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set canvas on visual brush for image brush."); 794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clampBrush->SetTileMode(SkToXpsTileMode[xy[0]][xy[1]]), 795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set tile mode on visual brush for image brush."); 796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clampBrush->SetOpacity(alpha / 255.0f), 797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set opacity on visual brush for image brush."); 798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clampBrush->QueryInterface(xpsBrush), "QI failed."); 800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrixToUse.get()) { 805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM((*xpsBrush)->SetTransformLocal(xpsMatrixToUse.get()), 806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform for image brush."); 807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO(bungeman): perspective bitmaps in general. 809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsGradientStop(const SkColor skColor, 815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar offset, 816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGradientStop** xpsGradStop) { 817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_COLOR gradStopXpsColor = xps_color(skColor); 818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateGradientStop(&gradStopXpsColor, 819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(offset), 821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGradStop), 822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create gradient stop."); 823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsLinearGradient(SkShader::GradientInfo info, 827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkAlpha alpha, 828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& localMatrix, 829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMMatrixTransform* xpsMatrix, 830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMBrush** xpsBrush) { 831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT startPoint; 832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT endPoint; 833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrix) { 834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot startPoint = xps_point(info.fPoint[0]); 835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot endPoint = xps_point(info.fPoint[1]); 836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform_offsets(info.fColorOffsets, info.fColorCount, 838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fPoint[0], info.fPoint[1], 839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix); 840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot startPoint = xps_point(info.fPoint[0], localMatrix); 841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot endPoint = xps_point(info.fPoint[1], localMatrix); 842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[0], 846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[0], 847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop0)); 848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[1], 851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[1], 852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop1)); 853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMLinearGradientBrush> gradientBrush; 855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateLinearGradientBrush(gradStop0.get(), 856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot gradStop1.get(), 857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &startPoint, 858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &endPoint, 859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradientBrush), 860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create linear gradient brush."); 861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrix) { 862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetTransformLocal(xpsMatrix), 863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform on linear gradient brush."); 864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->GetGradientStops(&gradStopCollection), 868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get linear gradient stop collection."); 869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 2; i < info.fColorCount; ++i) { 870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop; 871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[i], 872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[i], 873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop)); 874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradStopCollection->Append(gradStop.get()), 875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add linear gradient stop."); 876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set spread method of linear gradient."); 880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetOpacity(alpha / 255.0f), 882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set opacity of linear gradient brush."); 883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed"); 884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsRadialGradient(SkShader::GradientInfo info, 889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkAlpha alpha, 890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& localMatrix, 891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMMatrixTransform* xpsMatrix, 892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMBrush** xpsBrush) { 893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop0; 894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[0], 895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[0], 896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop0)); 897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop1; 899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[1], 900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[1], 901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop1)); 902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: figure out how to fake better if not affine 904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT centerPoint; 905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT gradientOrigin; 906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SIZE radiiSizes; 907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrix) { 908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot centerPoint = xps_point(info.fPoint[0]); 909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot gradientOrigin = xps_point(info.fPoint[0]); 910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot radiiSizes.width = SkScalarToFLOAT(info.fRadius[0]); 911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot radiiSizes.height = SkScalarToFLOAT(info.fRadius[0]); 912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot centerPoint = xps_point(info.fPoint[0], localMatrix); 914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot gradientOrigin = xps_point(info.fPoint[0], localMatrix); 915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar radius = info.fRadius[0]; 917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector vec[2]; 918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vec[0].set(radius, 0); 920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot vec[1].set(0, radius); 921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix.mapVectors(vec, 2); 922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar d0 = vec[0].length(); 924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar d1 = vec[1].length(); 925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot radiiSizes.width = SkScalarToFLOAT(d0); 927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot radiiSizes.height = SkScalarToFLOAT(d1); 928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMRadialGradientBrush> gradientBrush; 931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateRadialGradientBrush(gradStop0.get(), 932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot gradStop1.get(), 933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ¢erPoint, 934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradientOrigin, 935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &radiiSizes, 936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradientBrush), 937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create radial gradient brush."); 938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrix) { 939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetTransformLocal(xpsMatrix), 940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform on radial gradient brush."); 941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStopCollection> gradStopCollection; 944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->GetGradientStops(&gradStopCollection), 945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get radial gradient stop collection."); 946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 2; i < info.fColorCount; ++i) { 947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGradientStop> gradStop; 948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(createXpsGradientStop(info.fColors[i], 949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets[i], 950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &gradStop)); 951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradStopCollection->Append(gradStop.get()), 952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add radial gradient stop."); 953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetSpreadMethod(xps_spread_method(info.fTileMode)), 956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set spread method of radial gradient."); 957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->SetOpacity(alpha / 255.0f), 959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set opacity of radial gradient brush."); 960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(gradientBrush->QueryInterface<IXpsOMBrush>(xpsBrush), "QI failed."); 961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsBrush(const SkPaint& skPaint, 966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMBrush** brush, 967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix* parentTransform) { 968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkShader *shader = skPaint.getShader(); 969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == shader) { 970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Gradient shaders. 975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::GradientInfo info; 976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorCount = 0; 977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColors = nullptr; 978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets = nullptr; 979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::GradientType gradientType = shader->asAGradient(&info); 980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kNone_GradientType == gradientType) { 982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Nothing to see, move along. 983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (SkShader::kColor_GradientType == gradientType) { 985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(1 == info.fColorCount); 986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor color; 987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColors = &color; 988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot shader->asAGradient(&info); 989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAlpha alpha = skPaint.getAlpha(); 990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(color, alpha, brush)); 991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (info.fColorCount == 0) { 995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkColor color = skPaint.getColor(); 996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(color, 0xFF, brush)); 997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoTArray<SkColor> colors(info.fColorCount); 1001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoTArray<SkScalar> colorOffsets(info.fColorCount); 1002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColors = colors.get(); 1003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot info.fColorOffsets = colorOffsets.get(); 1004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot shader->asAGradient(&info); 1005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == info.fColorCount) { 1007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkColor color = info.fColors[0]; 1008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAlpha alpha = skPaint.getAlpha(); 1009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(color, alpha, brush)); 1010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix localMatrix = shader->getLocalMatrix(); 1014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (parentTransform) { 1015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix.preConcat(*parentTransform); 1016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 1018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsTransform(localMatrix, &xpsMatrixToUse)); 1019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kLinear_GradientType == gradientType) { 1021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsLinearGradient(info, 1022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot skPaint.getAlpha(), 1023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix, 1024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsMatrixToUse.get(), 1025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brush)); 1026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kRadial_GradientType == gradientType) { 1030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsRadialGradient(info, 1031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot skPaint.getAlpha(), 1032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix, 1033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsMatrixToUse.get(), 1034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot brush)); 1035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kConical_GradientType == gradientType) { 1039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //simple if affine and one is 0, otherwise will have to fake 1040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkShader::kSweep_GradientType == gradientType) { 1043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //have to fake 1044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap outTexture; 1048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix outMatrix; 1049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::TileMode xy[2]; 1050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkImage* image = shader->isAImage(&outMatrix, xy); 1051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (image && image->asLegacyBitmap(&outTexture, SkImage::kRO_LegacyBitmapMode)) { 1052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: outMatrix?? 1053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix localMatrix = shader->getLocalMatrix(); 1054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (parentTransform) { 1055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix.postConcat(*parentTransform); 1056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMTileBrush> tileBrush; 1059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsImageBrush(outTexture, 1060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot localMatrix, 1061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xy, 1062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot skPaint.getAlpha(), 1063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &tileBrush)); 1064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(tileBrush->QueryInterface<IXpsOMBrush>(brush), "QI failed."); 1066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsSolidColorBrush(skPaint.getColor(), 0xFF, brush)); 1068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool rect_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 1073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool zeroWidth = (0 == paint.getStrokeWidth()); 1074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool stroke = (SkPaint::kFill_Style != paint.getStyle()); 1075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return paint.getPathEffect() || 1077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getMaskFilter() || 1078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (stroke && ( 1079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (matrix.hasPerspective() && !zeroWidth) || 1080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint::kMiter_Join != paint.getStrokeJoin() || 1081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (SkPaint::kMiter_Join == paint.getStrokeJoin() && 1082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getStrokeMiter() < SK_ScalarSqrt2) 1083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot )) 1084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ; 1085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsRect(const SkRect& rect, BOOL stroke, BOOL fill, 1088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGeometryFigure** xpsRect) { 1089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint points[4] = { 1090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { rect.fLeft, rect.fTop }, 1091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { rect.fRight, rect.fTop }, 1092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { rect.fRight, rect.fBottom }, 1093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { rect.fLeft, rect.fBottom }, 1094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->createXpsQuad(points, stroke, fill, xpsRect); 1096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4], 1098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL stroke, BOOL fill, 1099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGeometryFigure** xpsQuad) { 1100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Define the start point. 1101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT startPoint = xps_point(points[0]); 1102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Create the figure. 1104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, xpsQuad), 1105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create quad geometry figure."); 1106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Define the type of each segment. 1108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SEGMENT_TYPE segmentTypes[3] = { 1109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SEGMENT_TYPE_LINE, 1110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SEGMENT_TYPE_LINE, 1111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_SEGMENT_TYPE_LINE, 1112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Define the x and y coordinates of each corner of the figure. 1115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FLOAT segmentData[6] = { 1116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(points[1].fX), SkScalarToFLOAT(points[1].fY), 1117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(points[2].fX), SkScalarToFLOAT(points[2].fY), 1118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(points[3].fX), SkScalarToFLOAT(points[3].fY), 1119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Describe if the segments are stroked. 1122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL segmentStrokes[3] = { 1123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke, stroke, stroke, 1124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Add the segment data to the figure. 1127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM((*xpsQuad)->SetSegments( 1128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 3, 6, 1129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes , segmentData, segmentStrokes), 1130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add segment data to quad."); 1131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Set the closed and filled properties of the figure. 1133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM((*xpsQuad)->SetIsClosed(stroke), "Could not set quad close."); 1134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM((*xpsQuad)->SetIsFilled(fill), "Could not set quad fill."); 1135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <typename F, typename... Args> 1140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid draw(SkClipStackDevice* dev, F f, Args&&... args) { 1141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect r = dev->devClipBounds(); 1142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRasterClip rc(r); 1143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDraw draw; 1144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fMatrix = &dev->ctm(); 1145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0); 1146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw.fRC = &rc; 1147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (draw.*f)(std::forward<Args>(args)...); 1148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawPoints(SkCanvas::PointMode mode, 1152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t count, const SkPoint points[], 1153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw(this, &SkDraw::drawPoints, mode, count, points, paint, this); 1155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawVertices(const SkVertices* v, SkBlendMode blendMode, const SkPaint& paint) { 1158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(), 1159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot v->colors(), blendMode, v->indices(), v->indexCount(), paint); 1160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawPaint(const SkPaint& origPaint) { 1163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize); 1164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //If trying to paint with a stroke, ignore that and fill. 1166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint* fillPaint = const_cast<SkPaint*>(&origPaint); 1167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 1168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (paint->getStyle() != SkPaint::kFill_Style) { 1169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.writable()->setStyle(SkPaint::kFill_Style); 1170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->internalDrawRect(r, false, *fillPaint); 1173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawRect(const SkRect& r, 1176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->internalDrawRect(r, true, paint); 1178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawRRect(const SkRRect& rr, 1181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 1183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.addRRect(rr); 1184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->drawPath(path, paint, nullptr, true); 1185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; } 1188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::internalDrawRect(const SkRect& r, 1190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool transformRect, 1191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Exit early if there is nothing to draw. 1193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->cs().isEmpty(size(*this)) || 1194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (paint.getAlpha() == 0 && paint.isSrcOver())) { 1195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Path the rect if we can't optimize it. 1199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (rect_must_be_pathed(paint, this->ctm())) { 1200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath tmp; 1201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.addRect(r); 1202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot tmp.setFillType(SkPath::kWinding_FillType); 1203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->drawPath(tmp, paint, nullptr, true); 1204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the shaded path. 1208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> shadedPath; 1209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create shaded path for rect."); 1211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the shaded geometry. 1213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create shaded geometry for rect."); 1216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the geometry to the shaded path. 1218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set shaded geometry for rect."); 1220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Set the brushes. 1222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL fill = FALSE; 1223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL stroke = FALSE; 1224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->shadePath(shadedPath.get(), paint, this->ctm(), &fill, &stroke)); 1225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool xpsTransformsPath = true; 1227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Transform the geometry. 1228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (transformRect && xpsTransformsPath) { 1229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsTransform(this->ctm(), &xpsTransform)); 1231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsTransform.get()) { 1232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform for rect."); 1234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsTransformsPath = false; 1236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the figure. 1240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 1241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 1242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint points[4] = { 1243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { r.fLeft, r.fTop }, 1244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { r.fLeft, r.fBottom }, 1245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { r.fRight, r.fBottom }, 1246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { r.fRight, r.fTop }, 1247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!xpsTransformsPath && transformRect) { 1249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->ctm().mapPoints(points, SK_ARRAY_COUNT(points)); 1250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsQuad(points, stroke, fill, &rectFigure)); 1252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the figures of the shaded geometry. 1255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->GetFigures(&shadedFigures), 1257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get shaded figures for rect."); 1258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the figure to the shaded geometry figures. 1260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedFigures->Append(rectFigure.get()), 1261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add shaded figure for rect."); 1262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->clip(shadedPath.get())); 1264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the shaded path to the current visuals. 1266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get current visuals for rect."); 1269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(currentVisuals->Append(shadedPath.get()), 1270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add rect to current visuals."); 1271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic HRESULT close_figure(const SkTDArray<XPS_SEGMENT_TYPE>& segmentTypes, 1274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkTDArray<BOOL>& segmentStrokes, 1275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkTDArray<FLOAT>& segmentData, 1276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL stroke, BOOL fill, 1277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGeometryFigure* figure, 1278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGeometryFigureCollection* figures) { 1279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Add the segment data to the figure. 1280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(figure->SetSegments(segmentTypes.count(), segmentData.count(), 1281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.begin() , segmentData.begin(), 1282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.begin()), 1283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set path segments."); 1284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Set the closed and filled properties of the figure. 1286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(figure->SetIsClosed(stroke), "Could not set path closed."); 1287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(figure->SetIsFilled(fill), "Could not set path fill."); 1288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Add the figure created above to this geometry. 1290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(figures->Append(figure), "Could not add path to geometry."); 1291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::addXpsPathGeometry( 1295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMGeometryFigureCollection* xpsFigures, 1296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL stroke, BOOL fill, const SkPath& path) { 1297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<XPS_SEGMENT_TYPE> segmentTypes; 1298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<BOOL> segmentStrokes; 1299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<FLOAT> segmentData; 1300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> xpsFigure; 1302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath::Iter iter(path, true); 1303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint points[4]; 1304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath::Verb verb; 1305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while ((verb = iter.next(points)) != SkPath::kDone_Verb) { 1306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (verb) { 1307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kMove_Verb: { 1308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsFigure.get()) { 1309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke, fill, 1311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFigure.get() , xpsFigures)); 1312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFigure.reset(); 1313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.rewind(); 1314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.rewind(); 1315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.rewind(); 1316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Define the start point. 1318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT startPoint = xps_point(points[0]); 1319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Create the figure. 1320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateGeometryFigure(&startPoint, 1321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &xpsFigure), 1322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create path geometry figure."); 1323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kLine_Verb: 1326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (iter.isCloseLine()) break; //ignore the line, auto-closed 1327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.push(XPS_SEGMENT_TYPE_LINE); 1328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.push(stroke); 1329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fX)); 1330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fY)); 1331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kQuad_Verb: 1333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER); 1334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.push(stroke); 1335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fX)); 1336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fY)); 1337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[2].fX)); 1338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[2].fY)); 1339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kCubic_Verb: 1341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.push(XPS_SEGMENT_TYPE_BEZIER); 1342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.push(stroke); 1343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fX)); 1344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[1].fY)); 1345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[2].fX)); 1346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[2].fY)); 1347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[3].fX)); 1348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(points[3].fY)); 1349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kConic_Verb: { 1351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar tol = SK_Scalar1 / 4; 1352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoConicToQuads converter; 1353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint* quads = 1354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot converter.computeQuads(points, iter.conicWeight(), tol); 1355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < converter.countQuads(); ++i) { 1356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentTypes.push(XPS_SEGMENT_TYPE_QUADRATIC_BEZIER); 1357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentStrokes.push(stroke); 1358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(quads[2 * i + 1].fX)); 1359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(quads[2 * i + 1].fY)); 1360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(quads[2 * i + 2].fX)); 1361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot segmentData.push(SkScalarToFLOAT(quads[2 * i + 2].fY)); 1362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kClose_Verb: 1366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // we ignore these, and just get the whole segment from 1367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the corresponding line/quad/cubic verbs 1368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 1370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("unexpected verb"); 1371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsFigure.get()) { 1375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(close_figure(segmentTypes, segmentStrokes, segmentData, 1376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke, fill, 1377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFigure.get(), xpsFigures)); 1378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::convertToPpm(const SkMaskFilter* filter, 1383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix* matrix, 1384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector* ppuScale, 1385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect& clip, SkIRect* clipIRect) { 1386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //This action is in unit space, but the ppm is specified in physical space. 1387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ppuScale->set(fCurrentPixelsPerMeter.fX / fCurrentUnitsPerMeter.fX, 1388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCurrentPixelsPerMeter.fY / fCurrentUnitsPerMeter.fY); 1389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot matrix->postScale(ppuScale->fX, ppuScale->fY); 1391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkIRect& irect = clip; 1393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect clipRect = SkRect::MakeLTRB(SkIntToScalar(irect.fLeft) * ppuScale->fX, 1394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(irect.fTop) * ppuScale->fY, 1395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(irect.fRight) * ppuScale->fX, 1396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(irect.fBottom) * ppuScale->fY); 1397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipRect.roundOut(clipIRect); 1398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::applyMask(const SkMask& mask, 1401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkVector& ppuScale, 1402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMPath* shadedPath) { 1403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the geometry object. 1404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->GetGeometry(&shadedGeometry), 1406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get mask shaded geometry."); 1407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the figures from the geometry. 1409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedGeometry->GetFigures(&shadedFigures), 1411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get mask shaded figures."); 1412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix m; 1414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot m.reset(); 1415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot m.setTranslate(SkIntToScalar(mask.fBounds.fLeft), 1416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(mask.fBounds.fTop)); 1417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot m.postScale(SkScalarInvert(ppuScale.fX), SkScalarInvert(ppuScale.fY)); 1418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::TileMode xy[2]; 1420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xy[0] = (SkShader::TileMode)3; 1421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xy[1] = (SkShader::TileMode)3; 1422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitmap bm; 1424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bm.installMaskPixels(mask); 1425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMTileBrush> maskBrush; 1427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsImageBrush(bm, m, xy, 0xFF, &maskBrush)); 1428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->SetOpacityMaskBrushLocal(maskBrush.get()), 1429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set mask."); 1430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect universeRect = SkRect::MakeLTRB(0, 0, 1432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentCanvasSize.fWidth, this->fCurrentCanvasSize.fHeight); 1433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> shadedFigure; 1434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->createXpsRect(universeRect, FALSE, TRUE, &shadedFigure), 1435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create mask shaded figure."); 1436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedFigures->Append(shadedFigure.get()), 1437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add mask shaded figure."); 1438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->clip(shadedPath)); 1440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the path to the active visual collection. 1442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get mask current visuals."); 1445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(currentVisuals->Append(shadedPath), 1446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add masked shaded path to current visuals."); 1447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath, 1452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& shaderPaint, 1453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& matrix, 1454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL* fill, BOOL* stroke) { 1455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *fill = FALSE; 1456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *stroke = FALSE; 1457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint::Style style = shaderPaint.getStyle(); 1459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool hasFill = SkPaint::kFill_Style == style 1460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || SkPaint::kStrokeAndFill_Style == style; 1461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool hasStroke = SkPaint::kStroke_Style == style 1462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || SkPaint::kStrokeAndFill_Style == style; 1463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO(bungeman): use dictionaries and lookups. 1465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (hasFill) { 1466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *fill = TRUE; 1467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMBrush> fillBrush; 1468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsBrush(shaderPaint, &fillBrush, &matrix)); 1469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->SetFillBrushLocal(fillBrush.get()), 1470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set fill for shaded path."); 1471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (hasStroke) { 1474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *stroke = TRUE; 1475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMBrush> strokeBrush; 1476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsBrush(shaderPaint, &strokeBrush, &matrix)); 1477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->SetStrokeBrushLocal(strokeBrush.get()), 1478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set stroke brush for shaded path."); 1479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->SetStrokeThickness( 1480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(shaderPaint.getStrokeWidth())), 1481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set shaded path stroke thickness."); 1482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (0 == shaderPaint.getStrokeWidth()) { 1484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //XPS hair width is a hack. (XPS Spec 11.6.12). 1485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMDashCollection> dashes; 1486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->GetStrokeDashes(&dashes), 1487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set dashes for shaded path."); 1488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_DASH dash; 1489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dash.length = 1.0; 1490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dash.gap = 0.0; 1491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(dashes->Append(&dash), "Could not add dashes to shaded path."); 1492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(shadedPath->SetStrokeDashOffset(-2.0), 1493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set dash offset for shaded path."); 1494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawPath(const SkPath& platonicPath, 1500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& origPaint, 1501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix* prePathMatrix, 1502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool pathIsMutable) { 1503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 1504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // nothing to draw 1506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->cs().isEmpty(size(*this)) || 1507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (paint->getAlpha() == 0 && paint->isSrcOver())) { 1508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath modifiedPath; 1512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const bool paintHasPathEffect = paint->getPathEffect() 1513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || paint->getStyle() != SkPaint::kFill_Style; 1514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Apply pre-path matrix [Platonic-path -> Skeletal-path]. 1516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix matrix = this->ctm(); 1517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath); 1518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (prePathMatrix) { 1519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (paintHasPathEffect) { 1520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!pathIsMutable) { 1521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot skeletalPath = &modifiedPath; 1522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pathIsMutable = true; 1523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot platonicPath.transform(*prePathMatrix, skeletalPath); 1525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot matrix.preConcat(*prePathMatrix); 1527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Apply path effect [Skeletal-path -> Fillable-path]. 1531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath* fillablePath = skeletalPath; 1532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (paintHasPathEffect) { 1533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!pathIsMutable) { 1534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fillablePath = &modifiedPath; 1535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pathIsMutable = true; 1536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fill = paint->getFillPath(*skeletalPath, fillablePath); 1538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint* writablePaint = paint.writable(); 1540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot writablePaint->setPathEffect(nullptr); 1541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fill) { 1542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot writablePaint->setStyle(SkPaint::kFill_Style); 1543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot writablePaint->setStyle(SkPaint::kStroke_Style); 1545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot writablePaint->setStrokeWidth(0); 1546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the shaded path. This will be the path which is painted. 1550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> shadedPath; 1551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create shaded path for path."); 1553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the geometry for the shaded path. 1555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create shaded geometry for path."); 1558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the geometry to the shaded path. 1560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add the shaded geometry to shaded path."); 1562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMaskFilter* filter = paint->getMaskFilter(); 1564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Determine if we will draw or shade and mask. 1566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (filter) { 1567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (paint->getStyle() != SkPaint::kFill_Style) { 1568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.writable()->setStyle(SkPaint::kFill_Style); 1569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Set the brushes. 1573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL fill; 1574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot BOOL stroke; 1575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->shadePath(shadedPath.get(), 1576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *paint, 1577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->ctm(), 1578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &fill, 1579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &stroke)); 1580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Mask filter 1582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (filter) { 1583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect clipIRect; 1584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkVector ppuScale; 1585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->convertToPpm(filter, 1586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &matrix, 1587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &ppuScale, 1588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->cs().bounds(size(*this)).roundOut(), 1589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &clipIRect); 1590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //[Fillable-path -> Pixel-path] 1592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath* pixelPath = pathIsMutable ? fillablePath : &modifiedPath; 1593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fillablePath->transform(matrix, pixelPath); 1594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask* mask = nullptr; 1596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(SkPaint::kFill_Style == paint->getStyle() || 1598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (SkPaint::kStroke_Style == paint->getStyle() && 0 == paint->getStrokeWidth())); 1599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkStrokeRec::InitStyle style = (SkPaint::kFill_Style == paint->getStyle()) 1600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? SkStrokeRec::kFill_InitStyle 1601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : SkStrokeRec::kHairline_InitStyle; 1602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //[Pixel-path -> Mask] 1603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask rasteredMask; 1604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkDraw::DrawToMask( 1605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *pixelPath, 1606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &clipIRect, 1607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot filter, //just to compute how much to draw. 1608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &matrix, 1609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &rasteredMask, 1610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask::kComputeBoundsAndRenderImage_CreateMode, 1611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot style)) { 1612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoMaskFreeImage rasteredAmi(rasteredMask.fImage); 1614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mask = &rasteredMask; 1615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //[Mask -> Mask] 1617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMask filteredMask; 1618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (as_MFB(filter)->filterMask(&filteredMask, rasteredMask, matrix, nullptr)) { 1619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mask = &filteredMask; 1620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoMaskFreeImage filteredAmi(filteredMask.fImage); 1622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Draw mask. 1624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->applyMask(*mask, ppuScale, shadedPath.get())); 1625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the figures from the shaded geometry. 1630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->GetFigures(&shadedFigures), 1632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get shaded figures for shaded path."); 1633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool xpsTransformsPath = true; 1635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Set the fill rule. 1637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath* xpsCompatiblePath = fillablePath; 1638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_FILL_RULE xpsFillRule; 1639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (fillablePath->getFillType()) { 1640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kWinding_FillType: 1641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFillRule = XPS_FILL_RULE_NONZERO; 1642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kEvenOdd_FillType: 1644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFillRule = XPS_FILL_RULE_EVENODD; 1645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kInverseWinding_FillType: { 1647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //[Fillable-path (inverse winding) -> XPS-path (inverse even odd)] 1648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!pathIsMutable) { 1649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsCompatiblePath = &modifiedPath; 1650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot pathIsMutable = true; 1651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!Simplify(*fillablePath, xpsCompatiblePath)) { 1653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGF(("Could not simplify inverse winding path.")); 1654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The xpsCompatiblePath is noW inverse even odd, so fall through. 1658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPath::kInverseEvenOdd_FillType: { 1659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect universe = SkRect::MakeLTRB( 1660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 0, 0, 1661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentCanvasSize.fWidth, 1662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentCanvasSize.fHeight); 1663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> addOneFigure; 1664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsRect(universe, FALSE, TRUE, &addOneFigure)); 1665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedFigures->Append(addOneFigure.get()), 1666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add even-odd flip figure to shaded path."); 1667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsTransformsPath = false; 1668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsFillRule = XPS_FILL_RULE_EVENODD; 1669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 1670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 1672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Unknown SkPath::FillType."); 1673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->SetFillRule(xpsFillRule), 1675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set fill rule for shaded path."); 1676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the XPS transform, if possible. 1678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsTransformsPath) { 1679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsTransform(matrix, &xpsTransform)); 1681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsTransform.get()) { 1683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform on shaded path."); 1685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsTransformsPath = false; 1687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath* devicePath = xpsCompatiblePath; 1691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!xpsTransformsPath) { 1692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //[Fillable-path -> Device-path] 1693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot devicePath = pathIsMutable ? xpsCompatiblePath : &modifiedPath; 1694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsCompatiblePath->transform(matrix, devicePath); 1695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->addXpsPathGeometry(shadedFigures.get(), 1697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke, fill, *devicePath)); 1698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->clip(shadedPath.get())); 1700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the path to the active visual collection. 1702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get current visuals for shaded path."); 1705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(currentVisuals->Append(shadedPath.get()), 1706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add shaded path to current visuals."); 1707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) { 1710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath clipPath; 1711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // clipPath.addRect(this->cs().bounds(size(*this))); 1712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (void)this->cs().asPath(&clipPath); 1713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD); 1714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual, 1716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPath& clipPath, 1717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_FILL_RULE fillRule) { 1718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the geometry. 1719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> clipGeometry; 1720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateGeometry(&clipGeometry), 1721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create clip geometry."); 1722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the figure collection of the geometry. 1724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> clipFigures; 1725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clipGeometry->GetFigures(&clipFigures), 1726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get the clip figures."); 1727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the figures into the geometry. 1729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->addXpsPathGeometry( 1730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot clipFigures.get(), 1731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FALSE, TRUE, clipPath)); 1732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(clipGeometry->SetFillRule(fillRule), 1734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set fill rule."); 1735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsVisual->SetClipGeometryLocal(clipGeometry.get()), 1736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set clip geometry."); 1737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawBitmap(const SkBitmap& bitmap, 1742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar x, 1743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar y, 1744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (this->cs().isEmpty(size(*this))) { 1746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 1747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect srcRect; 1750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot srcRect.set(0, 0, bitmap.width(), bitmap.height()); 1751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the new shaded path. 1753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMPath> shadedPath; 1754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreatePath(&shadedPath), 1755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create path for bitmap."); 1756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Create the shaded geometry. 1758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometry> shadedGeometry; 1759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreateGeometry(&shadedGeometry), 1760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create geometry for bitmap."); 1761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Add the shaded geometry to the shaded path. 1763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedPath->SetGeometryLocal(shadedGeometry.get()), 1764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set the geometry for bitmap."); 1765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the shaded figures from the shaded geometry. 1767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigureCollection> shadedFigures; 1768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->GetFigures(&shadedFigures), 1769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get the figures for bitmap."); 1770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix transform = SkMatrix::MakeTrans(x, y); 1772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform.postConcat(this->ctm()); 1773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 1775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsTransform(transform, &xpsTransform)); 1776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsTransform.get()) { 1777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()), 1778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform for bitmap."); 1779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: perspective that bitmap! 1781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGeometryFigure> rectFigure; 1784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsTransform.get()) { 1785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkShader::TileMode xy[2] = { 1786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode, 1787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode, 1788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 1789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMTileBrush> xpsImageBrush; 1790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsImageBrush(bitmap, 1791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot transform, 1792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xy, 1793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getAlpha(), 1794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &xpsImageBrush)); 1795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedPath->SetFillBrushLocal(xpsImageBrush.get()), 1796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set bitmap brush."); 1797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect bitmapRect = SkRect::MakeLTRB(0, 0, 1799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->createXpsRect(bitmapRect, FALSE, TRUE, &rectFigure)); 1801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(shadedFigures->Append(rectFigure.get()), 1803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add bitmap figure."); 1804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the current visual collection and add the shaded path to it. 1806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 1807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 1808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get current visuals for bitmap"); 1809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(currentVisuals->Append(shadedPath.get()), 1810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add bitmap to current visuals."); 1811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(this->clip(shadedPath.get())); 1813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { 1816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: override this for XPS 1817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGF(("XPS drawSprite not yet implemented.")); 1818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint, 1821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse** typefaceUse) { 1822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoResolveDefaultTypeface typeface(paint.getTypeface()); 1823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Check cache. 1825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkFontID typefaceID = typeface->uniqueID(); 1826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->fTypefaces.empty()) { 1827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse* current = &this->fTypefaces.front(); 1828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const TypefaceUse* last = &this->fTypefaces.back(); 1829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (; current <= last; ++current) { 1830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (current->typefaceId == typefaceID) { 1831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *typefaceUse = current; 1832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: create glyph only fonts 1838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //and let the host deal with what kind of font we're looking at. 1839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_FONT_EMBEDDING embedding = XPS_FONT_EMBEDDING_RESTRICTED; 1840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IStream> fontStream; 1842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int ttcIndex; 1843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkStream* fontData = typeface->openStream(&ttcIndex); 1844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: cannot handle FON fonts. 1845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(SkIStream::CreateFromSkStream(fontData, true, &fontStream), 1846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create font stream."); 1847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t size = 1849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ARRAY_COUNT(L"/Resources/Fonts/" L_GUID_ID L".odttf"); 1850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t buffer[size]; 1851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot wchar_t id[GUID_ID_LEN]; 1852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createId(id, GUID_ID_LEN)); 1853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot swprintf_s(buffer, size, L"/Resources/Fonts/%s.odttf", id); 1854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IOpcPartUri> partUri; 1856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreatePartUri(buffer, &partUri), 1857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create font resource part uri."); 1858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMFontResource> xpsFontResource; 1860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateFontResource(fontStream.get(), 1861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot embedding, 1862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot partUri.get(), 1863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FALSE, 1864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &xpsFontResource), 1865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create font resource."); 1866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: change openStream to return -1 for non-ttc, get rid of this. 1868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint8_t* data = (uint8_t*)fontData->getMemoryBase(); 1869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool isTTC = (data && 1870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fontData->getLength() >= sizeof(SkTTCFHeader) && 1871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ((SkTTCFHeader*)data)->ttcTag == SkTTCFHeader::TAG); 1872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse& newTypefaceUse = this->fTypefaces.push_back(); 1874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newTypefaceUse.typefaceId = typefaceID; 1875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newTypefaceUse.ttcIndex = isTTC ? ttcIndex : -1; 1876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newTypefaceUse.fontData = fontData; 1877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newTypefaceUse.xpsFont = xpsFontResource.release(); 1878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoGlyphCache agc(paint, &this->surfaceProps(), &SkMatrix::I()); 1880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkGlyphCache* glyphCache = agc.getCache(); 1881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot unsigned int glyphCount = glyphCache->getGlyphCount(); 1882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount); 1883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *typefaceUse = &newTypefaceUse; 1885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotHRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory, 1889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot IXpsOMCanvas* canvas, 1890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse* font, 1891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot LPCWSTR text, 1892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_GLYPH_INDEX* xpsGlyphs, 1893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot UINT32 xpsGlyphsLen, 1894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT *origin, 1895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FLOAT fontSize, 1896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_STYLE_SIMULATION sims, 1897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& transform, 1898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 1899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGlyphs> glyphs; 1900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(xpsFactory->CreateGlyphs(font->xpsFont, &glyphs), "Could not create glyphs."); 1901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetFontFaceIndex(font->ttcIndex), "Could not set glyph font face index."); 1902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //XPS uses affine transformations for everything... 1904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //...except positioning text. 1905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool useCanvasForClip; 1906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ((transform.getType() & ~SkMatrix::kTranslate_Mask) == 0) { 1907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot origin->x += SkScalarToFLOAT(transform.getTranslateX()); 1908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot origin->y += SkScalarToFLOAT(transform.getTranslateY()); 1909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot useCanvasForClip = false; 1910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsMatrixToUse; 1912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsTransform(transform, &xpsMatrixToUse)); 1913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsMatrixToUse.get()) { 1914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetTransformLocal(xpsMatrixToUse.get()), 1915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set transform matrix."); 1916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot useCanvasForClip = true; 1917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Attempt to add glyphs in perspective."); 1919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot useCanvasForClip = false; 1920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMGlyphsEditor> glyphsEditor; 1924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->GetGlyphsEditor(&glyphsEditor), "Could not get glyph editor."); 1925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (text) { 1927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphsEditor->SetUnicodeString(text), 1928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set unicode string."); 1929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsGlyphs) { 1932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphsEditor->SetGlyphIndices(xpsGlyphsLen, xpsGlyphs), 1933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set glyphs."); 1934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphsEditor->ApplyEdits(), "Could not apply glyph edits."); 1937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMBrush> xpsFillBrush; 1939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->createXpsBrush( 1940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint, 1941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &xpsFillBrush, 1942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot useCanvasForClip ? nullptr : &transform)); 1943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetFillBrushLocal(xpsFillBrush.get()), 1945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set fill brush."); 1946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetOrigin(origin), "Could not set glyph origin."); 1948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetFontRenderingEmSize(fontSize), 1950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set font size."); 1951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphs->SetStyleSimulations(sims), 1953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set style simulations."); 1954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> visuals; 1956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals."); 1957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!useCanvasForClip) { 1959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->clip(glyphs.get())); 1960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas."); 1961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 1962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMCanvas> glyphCanvas; 1963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(this->fXpsFactory->CreateCanvas(&glyphCanvas), 1964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create glyph canvas."); 1965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> glyphCanvasVisuals; 1967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphCanvas->GetVisuals(&glyphCanvasVisuals), 1968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get glyph visuals collection."); 1969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(glyphCanvasVisuals->Append(glyphs.get()), 1971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add glyphs to page."); 1972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HR(this->clip(glyphCanvas.get())); 1973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRM(visuals->Append(glyphCanvas.get()), 1975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add glyph canvas to page."); 1976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return S_OK; 1979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic int num_glyph_guess(SkPaint::TextEncoding encoding, const void* text, size_t byteLength) { 1982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (encoding) { 1983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPaint::kUTF8_TextEncoding: 1984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkUTF8_CountUnichars(text, byteLength); 1985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPaint::kUTF16_TextEncoding: 1986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkUTF16_CountUnichars(text, byteLength); 1987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case SkPaint::kGlyphID_TextEncoding: 1988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkToInt(byteLength / 2); 1989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot default: 1990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ABORT("Invalid Text Encoding"); 1991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 1992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return 0; 1993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 1994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 1995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { 1996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint::Style style = paint.getStyle(); 1997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return matrix.hasPerspective() 1998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || SkPaint::kStroke_Style == style 1999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || SkPaint::kStrokeAndFill_Style == style 2000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || paint.getMaskFilter() 2001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ; 2002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef SkTDArray<XPS_GLYPH_INDEX> GlyphRun; 2005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass ProcessOneGlyph { 2007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 2008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ProcessOneGlyph(FLOAT centemPerUnit, SkBitSet* glyphUse, GlyphRun* xpsGlyphs) 2009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fCentemPerUnit(centemPerUnit) 2010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fGlyphUse(glyphUse) 2011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fXpsGlyphs(xpsGlyphs) { } 2012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void operator()(const SkGlyph& glyph, SkPoint position, SkPoint) { 2014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); 2015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar x = position.fX; 2017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar y = position.fY; 2018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_GLYPH_INDEX* xpsGlyph = fXpsGlyphs->append(); 2020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint16_t glyphID = glyph.getGlyphID(); 2021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGlyphUse->set(glyphID); 2022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->index = glyphID; 2023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (1 == fXpsGlyphs->count()) { 2024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->advanceWidth = 0.0f; 2025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->horizontalOffset = SkScalarToFloat(x) * fCentemPerUnit; 2026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->verticalOffset = SkScalarToFloat(y) * -fCentemPerUnit; 2027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot else { 2029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const XPS_GLYPH_INDEX& first = (*fXpsGlyphs)[0]; 2030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->advanceWidth = 0.0f; 2031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * fCentemPerUnit) 2032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot - first.horizontalOffset; 2033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -fCentemPerUnit) 2034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot - first.verticalOffset; 2035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 2039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** [in] Advance width and offsets for glyphs measured in 2040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot hundredths of the font em size (XPS Spec 5.1.3). */ 2041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const FLOAT fCentemPerUnit; 2042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** [in,out] The accumulated glyphs used in the current typeface. */ 2043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkBitSet* const fGlyphUse; 2044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot /** [out] The glyphs to draw. */ 2045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GlyphRun* const fXpsGlyphs; 2046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 2047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawText(const void* text, size_t byteLen, 2049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalar x, SkScalar y, 2050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint) { 2051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (byteLen < 1) return; 2052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (text_must_be_pathed(paint, this->ctm())) { 2054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 2055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getTextPath(text, byteLen, x, y, &path); 2056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->drawPath(path, paint, nullptr, true); 2057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: add automation "text" 2058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 2059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse* typeface; 2062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(CreateTypefaceUse(paint, &typeface)); 2063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& matrix = SkMatrix::I(); 2065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix); 2067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkGlyphCache* cache = autoCache.getCache(); 2068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Advance width and offsets for glyphs measured in hundredths of the font em size 2070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // (XPS Spec 5.1.3). 2071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); 2072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GlyphRun xpsGlyphs; 2073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(), 2074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<const char*>(text), byteLen)); 2075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs); 2077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFindAndPlaceGlyph::ProcessText( 2079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getTextEncoding(), static_cast<const char*>(text), byteLen, 2080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPoint{ x, y }, matrix, paint.getTextAlign(), cache, processOneGlyph); 2081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsGlyphs.count() == 0) { 2083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 2084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT origin = { 2087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].horizontalOffset / centemPerUnit, 2088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].verticalOffset / -centemPerUnit, 2089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 2090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].horizontalOffset = 0.0f; 2091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].verticalOffset = 0.0f; 2092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(AddGlyphs(this->fXpsFactory.get(), 2094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentXpsCanvas.get(), 2095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typeface, 2096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 2097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs.begin(), xpsGlyphs.count(), 2098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &origin, 2099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(paint.getTextSize()), 2100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_STYLE_SIMULATION_NONE, 2101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->ctm(), 2102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint)); 2103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawPosText(const void* text, size_t byteLen, 2106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkScalar pos[], int scalarsPerPos, 2107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPoint& offset, const SkPaint& paint) { 2108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (byteLen < 1) return; 2109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (text_must_be_pathed(paint, this->ctm())) { 2111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 2112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: make this work, Draw currently does not handle as well. 2113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //paint.getTextPath(text, byteLength, x, y, &path); 2114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //this->drawPath(path, paint, nullptr, true); 2115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //TODO: add automation "text" 2116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 2117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TypefaceUse* typeface; 2120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(CreateTypefaceUse(paint, &typeface)); 2121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkMatrix& matrix = SkMatrix::I(); 2123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAutoGlyphCache autoCache(paint, &this->surfaceProps(), &matrix); 2125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkGlyphCache* cache = autoCache.getCache(); 2126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Advance width and offsets for glyphs measured in hundredths of the font em size 2128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // (XPS Spec 5.1.3). 2129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); 2130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GlyphRun xpsGlyphs; 2131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(), 2132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<const char*>(text), byteLen)); 2133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs); 2135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkFindAndPlaceGlyph::ProcessPosText( 2137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.getTextEncoding(), static_cast<const char*>(text), byteLen, 2138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot offset, matrix, pos, scalarsPerPos, paint.getTextAlign(), cache, processOneGlyph); 2139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (xpsGlyphs.count() == 0) { 2141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 2142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_POINT origin = { 2145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].horizontalOffset / centemPerUnit, 2146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].verticalOffset / -centemPerUnit, 2147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 2148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].horizontalOffset = 0.0f; 2149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs[0].verticalOffset = 0.0f; 2150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRV(AddGlyphs(this->fXpsFactory.get(), 2152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->fCurrentXpsCanvas.get(), 2153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot typeface, 2154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr, 2155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot xpsGlyphs.begin(), xpsGlyphs.count(), 2156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &origin, 2157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkScalarToFLOAT(paint.getTextSize()), 2158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_STYLE_SIMULATION_NONE, 2159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->ctm(), 2160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint)); 2161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawDevice( SkBaseDevice* dev, 2164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int x, int y, 2165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint&) { 2166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkXPSDevice* that = static_cast<SkXPSDevice*>(dev); 2167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform; 2169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO(halcanary): assert that current transform is identity rather than calling setter. 2170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot XPS_MATRIX rawTransform = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; 2171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform), 2172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not create layer transform."); 2173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()), 2174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not set layer transform."); 2175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //Get the current visual collection and add the layer to it. 2177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals; 2178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(this->fCurrentXpsCanvas->GetVisuals(¤tVisuals), 2179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not get current visuals for layer."); 2180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot HRVM(currentVisuals->Append(that->fCurrentXpsCanvas.get()), 2181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot "Could not add layer to current visuals."); 2182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotSkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*) { 2185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//Conditional for bug compatibility with PDF device. 2186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 2187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBaseDevice::kGeneral_Usage == info.fUsage) { 2188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 2189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //To what stream do we write? 2190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //SkXPSDevice* dev = new SkXPSDevice(this); 2191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //SkSize s = SkSize::Make(width, height); 2192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //dev->BeginCanvas(s, s, SkMatrix::I()); 2193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot //return dev; 2194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 2196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkXPSDevice* dev = new SkXPSDevice(info.fInfo.dimensions()); 2197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO(halcanary) implement copy constructor on SkTScopedCOmPtr 2198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot dev->fXpsFactory.reset(SkRefComPtr(fXpsFactory.get())); 2199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkAssertResult(dev->createCanvasForLayer()); 2200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return dev; 2201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) { 2204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath path; 2205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.addOval(o); 2206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->drawPath(path, p, nullptr, true); 2207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 2209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap, 2210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect* src, 2211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkRect& dst, 2212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPaint& paint, 2213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkCanvas::SrcRectConstraint constraint) { 2214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect bitmapBounds = SkRect::Make(bitmap.bounds()); 2215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect srcBounds = src ? *src : bitmapBounds; 2216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix matrix = SkMatrix::MakeRectToRect(srcBounds, dst, SkMatrix::kFill_ScaleToFit); 2217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect actualDst; 2218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!src || bitmapBounds.contains(*src)) { 2219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot actualDst = dst; 2220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 2221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!srcBounds.intersect(bitmapBounds)) { 2222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 2223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot matrix.mapRect(&actualDst, srcBounds); 2225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 2226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot auto bitmapShader = SkMakeBitmapShader(bitmap, SkShader::kClamp_TileMode, 2227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkShader::kClamp_TileMode, &matrix, 2228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kNever_SkCopyPixelsMode); 2229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(bitmapShader); 2230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!bitmapShader) { return; } 2231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPaint paintWithShader(paint); 2232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paintWithShader.setStyle(SkPaint::kFill_Style); 2233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paintWithShader.setShader(std::move(bitmapShader)); 2234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->drawRect(actualDst, paintWithShader); 2235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 2236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif//defined(SK_BUILD_FOR_WIN) 2237