MozReview-Commit-ID: HCapLqbD816
This commit is contained in:
Wes Kocher 2017-05-11 17:30:41 -07:00
Родитель d23a68d914 37bcd40492
Коммит f1c0f35ea6
3414 изменённых файлов: 246293 добавлений и 120095 удалений

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1356927 - Mac builds in automation require a clobber for a change in which ranlib they use
Bug 1340627 - clobber for Skia update

Просмотреть файл

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.8.331
Current extension version is: 1.8.346
Taken from upstream commit: 0dbc68a6
Taken from upstream commit: 15425d5b

Просмотреть файл

@ -101,12 +101,17 @@ return /******/ (function(modules) { // webpackBootstrap
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
__w_pdfjs_require__(14);
var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : undefined;
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
const NativeImageDecoding = {
NONE: 'none',
DECODE: 'decode',
DISPLAY: 'display'
};
var TextRenderingMode = {
FILL: 0,
STROKE: 1,
@ -1125,6 +1130,7 @@ exports.InvalidPDFException = InvalidPDFException;
exports.MessageHandler = MessageHandler;
exports.MissingDataException = MissingDataException;
exports.MissingPDFException = MissingPDFException;
exports.NativeImageDecoding = NativeImageDecoding;
exports.NotImplementedException = NotImplementedException;
exports.PageViewport = PageViewport;
exports.PasswordException = PasswordException;
@ -2170,9 +2176,16 @@ function getDocument(src, pdfDataRangeTransport, passwordCallback, progressCallb
params[key] = source[key];
}
params.rangeChunkSize = params.rangeChunkSize || DEFAULT_RANGE_CHUNK_SIZE;
params.disableNativeImageDecoder = params.disableNativeImageDecoder === true;
params.ignoreErrors = params.stopAtErrors !== true;
var CMapReaderFactory = params.CMapReaderFactory || _dom_utils.DOMCMapReaderFactory;
if (params.disableNativeImageDecoder !== undefined) {
(0, _util.deprecated)('parameter disableNativeImageDecoder, ' + 'use nativeImageDecoderSupport instead');
}
params.nativeImageDecoderSupport = params.nativeImageDecoderSupport || (params.disableNativeImageDecoder === true ? _util.NativeImageDecoding.NONE : _util.NativeImageDecoding.DECODE);
if (params.nativeImageDecoderSupport !== _util.NativeImageDecoding.DECODE && params.nativeImageDecoderSupport !== _util.NativeImageDecoding.NONE && params.nativeImageDecoderSupport !== _util.NativeImageDecoding.DISPLAY) {
(0, _util.warn)('Invalid parameter nativeImageDecoderSupport: ' + 'need a state of enum {NativeImageDecoding}');
params.nativeImageDecoderSupport = _util.NativeImageDecoding.DECODE;
}
if (!worker) {
var workerPort = (0, _dom_utils.getDefaultSetting)('workerPort');
worker = workerPort ? new PDFWorker(null, workerPort) : new PDFWorker();
@ -2215,7 +2228,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
disableCreateObjectURL: (0, _dom_utils.getDefaultSetting)('disableCreateObjectURL'),
postMessageTransfers: (0, _dom_utils.getDefaultSetting)('postMessageTransfers') && !isPostMessageTransfersDisabled,
docBaseUrl: source.docBaseUrl,
disableNativeImageDecoder: source.disableNativeImageDecoder,
nativeImageDecoderSupport: source.nativeImageDecoderSupport,
ignoreErrors: source.ignoreErrors
}).then(function (workerId) {
if (worker.destroyed) {
@ -3392,8 +3405,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
}();
var version, build;
{
exports.version = version = '1.8.331';
exports.build = build = '0dbc68a6';
exports.version = version = '1.8.346';
exports.build = build = '15425d5b';
}
exports.getDocument = getDocument;
exports.LoopbackPort = LoopbackPort;
@ -4395,8 +4408,8 @@ if (!_util.globalScope.PDFJS) {
}
var PDFJS = _util.globalScope.PDFJS;
{
PDFJS.version = '1.8.331';
PDFJS.build = '0dbc68a6';
PDFJS.version = '1.8.346';
PDFJS.build = '15425d5b';
}
PDFJS.pdfBug = false;
if (PDFJS.verbosity !== undefined) {
@ -6710,8 +6723,8 @@ exports.TilingPattern = TilingPattern;
"use strict";
var pdfjsVersion = '1.8.331';
var pdfjsBuild = '0dbc68a6';
var pdfjsVersion = '1.8.346';
var pdfjsBuild = '15425d5b';
var pdfjsSharedUtil = __w_pdfjs_require__(0);
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
@ -6734,6 +6747,7 @@ exports.PasswordResponses = pdfjsSharedUtil.PasswordResponses;
exports.InvalidPDFException = pdfjsSharedUtil.InvalidPDFException;
exports.MissingPDFException = pdfjsSharedUtil.MissingPDFException;
exports.SVGGraphics = pdfjsDisplaySVG.SVGGraphics;
exports.NativeImageDecoding = pdfjsSharedUtil.NativeImageDecoding;
exports.UnexpectedResponseException = pdfjsSharedUtil.UnexpectedResponseException;
exports.OPS = pdfjsSharedUtil.OPS;
exports.UNSUPPORTED_FEATURES = pdfjsSharedUtil.UNSUPPORTED_FEATURES;

Просмотреть файл

@ -101,12 +101,17 @@ return /******/ (function(modules) { // webpackBootstrap
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
exports.warn = exports.utf8StringToString = exports.stringToUTF8String = exports.stringToPDFString = exports.stringToBytes = exports.string32 = exports.shadow = exports.setVerbosityLevel = exports.removeNullCharacters = exports.readUint32 = exports.readUint16 = exports.readInt8 = exports.log2 = exports.loadJpegStream = exports.isEvalSupported = exports.isLittleEndian = exports.createValidAbsoluteUrl = exports.isSameOrigin = exports.isNodeJS = exports.isSpace = exports.isString = exports.isNum = exports.isInt = exports.isEmptyObj = exports.isBool = exports.isArrayBuffer = exports.isArray = exports.info = exports.globalScope = exports.getVerbosityLevel = exports.getLookupTableFactory = exports.error = exports.deprecated = exports.createObjectURL = exports.createPromiseCapability = exports.createBlob = exports.bytesToString = exports.assert = exports.arraysToBytes = exports.arrayByteLength = exports.XRefParseException = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.StatTimer = exports.PasswordResponses = exports.PasswordException = exports.PageViewport = exports.NotImplementedException = exports.NativeImageDecoding = exports.MissingPDFException = exports.MissingDataException = exports.MessageHandler = exports.InvalidPDFException = exports.CMapCompressionType = exports.ImageKind = exports.FontType = exports.AnnotationType = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.UNSUPPORTED_FEATURES = exports.VERBOSITY_LEVELS = exports.OPS = exports.IDENTITY_MATRIX = exports.FONT_IDENTITY_MATRIX = undefined;
__w_pdfjs_require__(36);
var globalScope = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : undefined;
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
const NativeImageDecoding = {
NONE: 'none',
DECODE: 'decode',
DISPLAY: 'display'
};
var TextRenderingMode = {
FILL: 0,
STROKE: 1,
@ -1125,6 +1130,7 @@ exports.InvalidPDFException = InvalidPDFException;
exports.MessageHandler = MessageHandler;
exports.MissingDataException = MissingDataException;
exports.MissingPDFException = MissingPDFException;
exports.NativeImageDecoding = NativeImageDecoding;
exports.NotImplementedException = NotImplementedException;
exports.PageViewport = PageViewport;
exports.PasswordException = PasswordException;
@ -16390,6 +16396,7 @@ var IDENTITY_MATRIX = sharedUtil.IDENTITY_MATRIX;
var UNSUPPORTED_FEATURES = sharedUtil.UNSUPPORTED_FEATURES;
var ImageKind = sharedUtil.ImageKind;
var OPS = sharedUtil.OPS;
var NativeImageDecoding = sharedUtil.NativeImageDecoding;
var TextRenderingMode = sharedUtil.TextRenderingMode;
var CMapCompressionType = sharedUtil.CMapCompressionType;
var Util = sharedUtil.Util;
@ -16450,7 +16457,7 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
forceDataSchema: false,
maxImageSize: -1,
disableFontFace: false,
disableNativeImageDecoder: false,
nativeImageDecoderSupport: NativeImageDecoding.DECODE,
ignoreErrors: false
};
function NativeImageDecoder(xref, resources, handler, forceDataSchema) {
@ -16724,17 +16731,17 @@ var PartialEvaluator = function PartialEvaluatorClosure() {
operatorList.addOp(OPS.paintInlineImageXObject, [imgData]);
return;
}
var useNativeImageDecoder = !this.options.disableNativeImageDecoder;
var nativeImageDecoderSupport = this.options.nativeImageDecoderSupport;
var objId = 'img_' + this.idFactory.createObjId();
operatorList.addDependency(objId);
args = [objId, w, h];
if (useNativeImageDecoder && !softMask && !mask && image instanceof JpegStream && NativeImageDecoder.isSupported(image, this.xref, resources)) {
if (nativeImageDecoderSupport !== NativeImageDecoding.NONE && !softMask && !mask && image instanceof JpegStream && NativeImageDecoder.isSupported(image, this.xref, resources)) {
operatorList.addOp(OPS.paintJpegXObject, args);
this.handler.send('obj', [objId, this.pageIndex, 'JpegStream', image.getIR(this.options.forceDataSchema)]);
return;
}
var nativeImageDecoder = null;
if (useNativeImageDecoder && (image instanceof JpegStream || mask instanceof JpegStream || softMask instanceof JpegStream)) {
if (nativeImageDecoderSupport === NativeImageDecoding.DECODE && (image instanceof JpegStream || mask instanceof JpegStream || softMask instanceof JpegStream)) {
nativeImageDecoder = new NativeImageDecoder(this.xref, resources, this.handler, this.options.forceDataSchema);
}
PDFImage.buildImage(this.handler, this.xref, resources, image, inline, nativeImageDecoder).then(imageObj => {
@ -23864,7 +23871,7 @@ var WorkerMessageHandler = {
forceDataSchema: data.disableCreateObjectURL,
maxImageSize: data.maxImageSize === undefined ? -1 : data.maxImageSize,
disableFontFace: data.disableFontFace,
disableNativeImageDecoder: data.disableNativeImageDecoder,
nativeImageDecoderSupport: data.nativeImageDecoderSupport,
ignoreErrors: data.ignoreErrors
};
getPdfManager(data, evaluatorOptions).then(function (newPdfManager) {
@ -36632,8 +36639,8 @@ exports.Type1Parser = Type1Parser;
"use strict";
var pdfjsVersion = '1.8.331';
var pdfjsBuild = '0dbc68a6';
var pdfjsVersion = '1.8.346';
var pdfjsBuild = '15425d5b';
var pdfjsCoreWorker = __w_pdfjs_require__(17);
;
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;

Просмотреть файл

@ -951,104 +951,103 @@ var PDFViewerApplication = {
})]).catch(function (reason) {});
},
_initializeViewerComponents() {
var self = this;
var appConfig = this.appConfig;
let appConfig = this.appConfig;
return new Promise((resolve, reject) => {
var eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)();
let eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)();
this.eventBus = eventBus;
var pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
pdfRenderingQueue.onIdle = self.cleanup.bind(self);
self.pdfRenderingQueue = pdfRenderingQueue;
var pdfLinkService = new _pdf_link_service.PDFLinkService({ eventBus });
self.pdfLinkService = pdfLinkService;
var downloadManager = self.externalServices.createDownloadManager();
self.downloadManager = downloadManager;
var container = appConfig.mainContainer;
var viewer = appConfig.viewerContainer;
self.pdfViewer = new _pdf_viewer.PDFViewer({
let pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue();
pdfRenderingQueue.onIdle = this.cleanup.bind(this);
this.pdfRenderingQueue = pdfRenderingQueue;
let pdfLinkService = new _pdf_link_service.PDFLinkService({ eventBus });
this.pdfLinkService = pdfLinkService;
let downloadManager = this.externalServices.createDownloadManager();
this.downloadManager = downloadManager;
let container = appConfig.mainContainer;
let viewer = appConfig.viewerContainer;
this.pdfViewer = new _pdf_viewer.PDFViewer({
container,
viewer,
eventBus,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService,
downloadManager,
renderer: self.viewerPrefs['renderer'],
enhanceTextSelection: self.viewerPrefs['enhanceTextSelection'],
renderInteractiveForms: self.viewerPrefs['renderInteractiveForms'],
enablePrintAutoRotate: self.viewerPrefs['enablePrintAutoRotate']
renderer: this.viewerPrefs['renderer'],
enhanceTextSelection: this.viewerPrefs['enhanceTextSelection'],
renderInteractiveForms: this.viewerPrefs['renderInteractiveForms'],
enablePrintAutoRotate: this.viewerPrefs['enablePrintAutoRotate']
});
pdfRenderingQueue.setViewer(self.pdfViewer);
pdfLinkService.setViewer(self.pdfViewer);
var thumbnailContainer = appConfig.sidebar.thumbnailView;
self.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
pdfRenderingQueue.setViewer(this.pdfViewer);
pdfLinkService.setViewer(this.pdfViewer);
let thumbnailContainer = appConfig.sidebar.thumbnailView;
this.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({
container: thumbnailContainer,
renderingQueue: pdfRenderingQueue,
linkService: pdfLinkService
});
pdfRenderingQueue.setThumbnailViewer(self.pdfThumbnailViewer);
self.pdfHistory = new _pdf_history.PDFHistory({
pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
this.pdfHistory = new _pdf_history.PDFHistory({
linkService: pdfLinkService,
eventBus
});
pdfLinkService.setHistory(self.pdfHistory);
self.findController = new _pdf_find_controller.PDFFindController({ pdfViewer: self.pdfViewer });
self.findController.onUpdateResultsCount = function (matchCount) {
if (self.supportsIntegratedFind) {
pdfLinkService.setHistory(this.pdfHistory);
this.findController = new _pdf_find_controller.PDFFindController({ pdfViewer: this.pdfViewer });
this.findController.onUpdateResultsCount = matchCount => {
if (this.supportsIntegratedFind) {
return;
}
self.findBar.updateResultsCount(matchCount);
this.findBar.updateResultsCount(matchCount);
};
self.findController.onUpdateState = function (state, previous, matchCount) {
if (self.supportsIntegratedFind) {
self.externalServices.updateFindControlState({
this.findController.onUpdateState = (state, previous, matchCount) => {
if (this.supportsIntegratedFind) {
this.externalServices.updateFindControlState({
result: state,
findPrevious: previous
});
} else {
self.findBar.updateUIState(state, previous, matchCount);
this.findBar.updateUIState(state, previous, matchCount);
}
};
self.pdfViewer.setFindController(self.findController);
var findBarConfig = Object.create(appConfig.findBar);
findBarConfig.findController = self.findController;
this.pdfViewer.setFindController(this.findController);
let findBarConfig = Object.create(appConfig.findBar);
findBarConfig.findController = this.findController;
findBarConfig.eventBus = eventBus;
self.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig);
self.overlayManager = _overlay_manager.OverlayManager;
self.handTool = new _hand_tool.HandTool({
this.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig);
this.overlayManager = _overlay_manager.OverlayManager;
this.handTool = new _hand_tool.HandTool({
container,
eventBus,
preferences: this.preferences
});
self.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties);
self.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus);
self.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
if (self.supportsFullscreen) {
self.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
this.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties);
this.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus);
this.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);
if (this.supportsFullscreen) {
this.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({
container,
viewer,
pdfViewer: self.pdfViewer,
pdfViewer: this.pdfViewer,
eventBus,
contextMenuItems: appConfig.fullscreen
});
}
self.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay);
self.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
this.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay);
this.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({
container: appConfig.sidebar.outlineView,
eventBus,
linkService: pdfLinkService
});
self.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
this.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({
container: appConfig.sidebar.attachmentsView,
eventBus,
downloadManager
});
var sidebarConfig = Object.create(appConfig.sidebar);
sidebarConfig.pdfViewer = self.pdfViewer;
sidebarConfig.pdfThumbnailViewer = self.pdfThumbnailViewer;
sidebarConfig.pdfOutlineViewer = self.pdfOutlineViewer;
let sidebarConfig = Object.create(appConfig.sidebar);
sidebarConfig.pdfViewer = this.pdfViewer;
sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;
sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;
sidebarConfig.eventBus = eventBus;
self.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig);
self.pdfSidebar.onToggled = self.forceRendering.bind(self);
this.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig);
this.pdfSidebar.onToggled = this.forceRendering.bind(this);
resolve(undefined);
});
},
@ -1193,14 +1192,14 @@ var PDFViewerApplication = {
}
return promise;
},
open: function pdfViewOpen(file, args) {
open(file, args) {
if (this.pdfLoadingTask) {
return this.close().then(() => {
this.preferences.reload();
return this.open(file, args);
});
}
var parameters = Object.create(null),
let parameters = Object.create(null),
scale;
if (typeof file === 'string') {
this.setTitleUsingUrl(file);
@ -1213,7 +1212,7 @@ var PDFViewerApplication = {
}
parameters.docBaseUrl = this.baseUrl;
if (args) {
for (var prop in args) {
for (let prop in args) {
parameters[prop] = args[prop];
}
if (args.scale) {
@ -1223,23 +1222,22 @@ var PDFViewerApplication = {
this.pdfDocumentProperties.setFileSize(args.length);
}
}
var self = this;
self.downloadComplete = false;
var loadingTask = (0, _pdfjs.getDocument)(parameters);
this.downloadComplete = false;
let loadingTask = (0, _pdfjs.getDocument)(parameters);
this.pdfLoadingTask = loadingTask;
loadingTask.onPassword = function passwordNeeded(updateCallback, reason) {
self.passwordPrompt.setUpdateCallback(updateCallback, reason);
self.passwordPrompt.open();
loadingTask.onPassword = (updateCallback, reason) => {
this.passwordPrompt.setUpdateCallback(updateCallback, reason);
this.passwordPrompt.open();
};
loadingTask.onProgress = function getDocumentProgress(progressData) {
self.progress(progressData.loaded / progressData.total);
loadingTask.onProgress = ({ loaded, total }) => {
this.progress(loaded / total);
};
loadingTask.onUnsupportedFeature = this.fallback.bind(this);
return loadingTask.promise.then(function getDocumentCallback(pdfDocument) {
self.load(pdfDocument, scale);
}, function getDocumentError(exception) {
var message = exception && exception.message;
var loadingErrorMessage = _ui_utils.mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.');
return loadingTask.promise.then(pdfDocument => {
this.load(pdfDocument, scale);
}, exception => {
let message = exception && exception.message;
let loadingErrorMessage = _ui_utils.mozL10n.get('loading_error', null, 'An error occurred while loading the PDF.');
if (exception instanceof _pdfjs.InvalidPDFException) {
loadingErrorMessage = _ui_utils.mozL10n.get('invalid_file_error', null, 'Invalid or corrupted PDF file.');
} else if (exception instanceof _pdfjs.MissingPDFException) {
@ -1247,8 +1245,7 @@ var PDFViewerApplication = {
} else if (exception instanceof _pdfjs.UnexpectedResponseException) {
loadingErrorMessage = _ui_utils.mozL10n.get('unexpected_response_error', null, 'Unexpected server response.');
}
var moreInfo = { message };
self.error(loadingErrorMessage, moreInfo);
this.error(loadingErrorMessage, { message });
throw new Error(loadingErrorMessage);
});
},
@ -1328,54 +1325,53 @@ var PDFViewerApplication = {
}
}
},
load: function pdfViewLoad(pdfDocument, scale) {
var self = this;
load(pdfDocument, scale) {
scale = scale || _ui_utils.UNKNOWN_SCALE;
this.pdfDocument = pdfDocument;
var downloadedPromise = pdfDocument.getDownloadInfo().then(function () {
self.downloadComplete = true;
self.loadingBar.hide();
pdfDocument.getDownloadInfo().then(() => {
this.downloadComplete = true;
this.loadingBar.hide();
firstPagePromise.then(() => {
this.eventBus.dispatch('documentload', { source: this });
});
});
this.toolbar.setPagesCount(pdfDocument.numPages, false);
this.secondaryToolbar.setPagesCount(pdfDocument.numPages);
var id = this.documentFingerprint = pdfDocument.fingerprint;
var store = this.store = new _view_history.ViewHistory(id);
var baseDocumentUrl;
let id = this.documentFingerprint = pdfDocument.fingerprint;
let store = this.store = new _view_history.ViewHistory(id);
let baseDocumentUrl;
baseDocumentUrl = this.baseUrl;
this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);
this.pdfDocumentProperties.setDocument(pdfDocument, this.url);
var pdfViewer = this.pdfViewer;
let pdfViewer = this.pdfViewer;
pdfViewer.currentScale = scale;
pdfViewer.setDocument(pdfDocument);
var firstPagePromise = pdfViewer.firstPagePromise;
var pagesPromise = pdfViewer.pagesPromise;
var onePageRendered = pdfViewer.onePageRendered;
let firstPagePromise = pdfViewer.firstPagePromise;
let pagesPromise = pdfViewer.pagesPromise;
let onePageRendered = pdfViewer.onePageRendered;
this.pageRotation = 0;
var pdfThumbnailViewer = this.pdfThumbnailViewer;
let pdfThumbnailViewer = this.pdfThumbnailViewer;
pdfThumbnailViewer.setDocument(pdfDocument);
firstPagePromise.then(pdfPage => {
downloadedPromise.then(function () {
self.eventBus.dispatch('documentload', { source: self });
});
self.loadingBar.setWidth(self.appConfig.viewerContainer);
if (!_pdfjs.PDFJS.disableHistory && !self.isViewerEmbedded) {
if (!self.viewerPrefs['showPreviousViewOnLoad']) {
self.pdfHistory.clearHistoryState();
this.loadingBar.setWidth(this.appConfig.viewerContainer);
if (!_pdfjs.PDFJS.disableHistory && !this.isViewerEmbedded) {
if (!this.viewerPrefs['showPreviousViewOnLoad']) {
this.pdfHistory.clearHistoryState();
}
self.pdfHistory.initialize(self.documentFingerprint);
if (self.pdfHistory.initialDestination) {
self.initialDestination = self.pdfHistory.initialDestination;
} else if (self.pdfHistory.initialBookmark) {
self.initialBookmark = self.pdfHistory.initialBookmark;
this.pdfHistory.initialize(this.documentFingerprint);
if (this.pdfHistory.initialDestination) {
this.initialDestination = this.pdfHistory.initialDestination;
} else if (this.pdfHistory.initialBookmark) {
this.initialBookmark = this.pdfHistory.initialBookmark;
}
}
var initialParams = {
let initialParams = {
destination: this.initialDestination,
bookmark: this.initialBookmark,
hash: null
};
var storedHash = this.viewerPrefs['defaultZoomValue'] ? 'zoom=' + this.viewerPrefs['defaultZoomValue'] : null;
var sidebarView = this.viewerPrefs['sidebarViewOnLoad'];
let storedHash = this.viewerPrefs['defaultZoomValue'] ? 'zoom=' + this.viewerPrefs['defaultZoomValue'] : null;
let sidebarView = this.viewerPrefs['sidebarViewOnLoad'];
new Promise((resolve, reject) => {
if (!this.viewerPrefs['showPreviousViewOnLoad']) {
resolve();
@ -1422,13 +1418,13 @@ var PDFViewerApplication = {
this.setInitialView(initialParams.hash);
});
});
pdfDocument.getPageLabels().then(function (labels) {
if (!labels || self.viewerPrefs['disablePageLabels']) {
pdfDocument.getPageLabels().then(labels => {
if (!labels || this.viewerPrefs['disablePageLabels']) {
return;
}
var i = 0,
let i = 0,
numLabels = labels.length;
if (numLabels !== self.pagesCount) {
if (numLabels !== this.pagesCount) {
console.error('The number of Page Labels does not match ' + 'the number of pages in the document.');
return;
}
@ -1440,46 +1436,45 @@ var PDFViewerApplication = {
}
pdfViewer.setPageLabels(labels);
pdfThumbnailViewer.setPageLabels(labels);
self.toolbar.setPagesCount(pdfDocument.numPages, true);
self.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
this.toolbar.setPagesCount(pdfDocument.numPages, true);
this.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
});
pagesPromise.then(function () {
if (self.supportsPrinting) {
pdfDocument.getJavaScript().then(function (javaScript) {
if (javaScript.length) {
console.warn('Warning: JavaScript is not supported');
self.fallback(_pdfjs.UNSUPPORTED_FEATURES.javaScript);
}
var regex = /\bprint\s*\(/;
for (var i = 0, ii = javaScript.length; i < ii; i++) {
var js = javaScript[i];
if (js && regex.test(js)) {
setTimeout(function () {
window.print();
});
return;
}
}
});
pagesPromise.then(() => {
if (!this.supportsPrinting) {
return;
}
});
Promise.all([onePageRendered, _ui_utils.animationStarted]).then(function () {
pdfDocument.getOutline().then(function (outline) {
self.pdfOutlineViewer.render({ outline });
});
pdfDocument.getAttachments().then(function (attachments) {
self.pdfAttachmentViewer.render({ attachments });
pdfDocument.getJavaScript().then(javaScript => {
if (javaScript.length) {
console.warn('Warning: JavaScript is not supported');
this.fallback(_pdfjs.UNSUPPORTED_FEATURES.javaScript);
}
let regex = /\bprint\s*\(/;
for (let i = 0, ii = javaScript.length; i < ii; i++) {
let js = javaScript[i];
if (js && regex.test(js)) {
setTimeout(function () {
window.print();
});
return;
}
}
});
});
pdfDocument.getMetadata().then(function (data) {
var info = data.info,
metadata = data.metadata;
self.documentInfo = info;
self.metadata = metadata;
Promise.all([onePageRendered, _ui_utils.animationStarted]).then(() => {
pdfDocument.getOutline().then(outline => {
this.pdfOutlineViewer.render({ outline });
});
pdfDocument.getAttachments().then(attachments => {
this.pdfAttachmentViewer.render({ attachments });
});
});
pdfDocument.getMetadata().then(({ info, metadata }) => {
this.documentInfo = info;
this.metadata = metadata;
console.log('PDF ' + pdfDocument.fingerprint + ' [' + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + ' (PDF.js: ' + (_pdfjs.version || '-') + (!_pdfjs.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');
var pdfTitle;
let pdfTitle;
if (metadata && metadata.has('dc:title')) {
var title = metadata.get('dc:title');
let title = metadata.get('dc:title');
if (title !== 'Untitled') {
pdfTitle = title;
}
@ -1488,15 +1483,15 @@ var PDFViewerApplication = {
pdfTitle = info['Title'];
}
if (pdfTitle) {
self.setTitle(pdfTitle + ' - ' + document.title);
this.setTitle(pdfTitle + ' - ' + document.title);
}
if (info.IsAcroFormPresent) {
console.warn('Warning: AcroForm/XFA is not supported');
self.fallback(_pdfjs.UNSUPPORTED_FEATURES.forms);
this.fallback(_pdfjs.UNSUPPORTED_FEATURES.forms);
}
var versionId = String(info.PDFFormatVersion).slice(-1) | 0;
var generatorId = 0;
var KNOWN_GENERATORS = ['acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle', 'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf', 'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince', 'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle', 'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf'];
let versionId = String(info.PDFFormatVersion).slice(-1) | 0;
let generatorId = 0;
const KNOWN_GENERATORS = ['acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle', 'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf', 'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince', 'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle', 'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf'];
if (info.Producer) {
KNOWN_GENERATORS.some(function (generator, s, i) {
if (generator.indexOf(s) < 0) {
@ -1506,8 +1501,8 @@ var PDFViewerApplication = {
return true;
}.bind(null, info.Producer.toLowerCase()));
}
var formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ? 'xfa' : 'acroform';
self.externalServices.reportTelemetry({
let formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ? 'xfa' : 'acroform';
this.externalServices.reportTelemetry({
type: 'documentInfo',
version: versionId,
generator: generatorId,
@ -2702,6 +2697,8 @@ Object.defineProperty(exports, "__esModule", {
});
exports.PDFFindController = exports.FindStates = undefined;
var _pdfjs = __webpack_require__(1);
var _ui_utils = __webpack_require__(0);
var FindStates = {
@ -2870,35 +2867,28 @@ var PDFFindController = function PDFFindControllerClosure() {
this.updateUIResultsCount();
}
},
extractText: function PDFFindController_extractText() {
extractText() {
if (this.startedTextExtraction) {
return;
}
this.startedTextExtraction = true;
this.pageContents = [];
var extractTextPromisesResolves = [];
var numPages = this.pdfViewer.pagesCount;
for (var i = 0; i < numPages; i++) {
this.extractTextPromises.push(new Promise(function (resolve) {
extractTextPromisesResolves.push(resolve);
}));
}
var self = this;
function extractPageText(pageIndex) {
self.pdfViewer.getPageTextContent(pageIndex).then(function textContentResolved(textContent) {
var textItems = textContent.items;
var str = [];
for (var i = 0, len = textItems.length; i < len; i++) {
str.push(textItems[i].str);
}
self.pageContents.push(str.join(''));
extractTextPromisesResolves[pageIndex](pageIndex);
if (pageIndex + 1 < self.pdfViewer.pagesCount) {
extractPageText(pageIndex + 1);
}
this.pageContents.length = 0;
let promise = Promise.resolve();
for (let i = 0, ii = this.pdfViewer.pagesCount; i < ii; i++) {
let extractTextCapability = (0, _pdfjs.createPromiseCapability)();
this.extractTextPromises[i] = extractTextCapability.promise;
promise = promise.then(() => {
return this.pdfViewer.getPageTextContent(i).then(textContent => {
let textItems = textContent.items;
let strBuf = [];
for (let j = 0, jj = textItems.length; j < jj; j++) {
strBuf.push(textItems[j].str);
}
this.pageContents[i] = strBuf.join('');
extractTextCapability.resolve(i);
});
});
}
extractPageText(0);
},
executeCommand: function PDFFindController_executeCommand(cmd, state) {
if (this.state === null || cmd !== 'findagain') {
@ -2940,14 +2930,13 @@ var PDFFindController = function PDFFindControllerClosure() {
this.pageMatches = [];
this.matchCount = 0;
this.pageMatchesLength = null;
var self = this;
for (var i = 0; i < numPages; i++) {
for (let i = 0; i < numPages; i++) {
this.updatePage(i);
if (!(i in this.pendingFindMatches)) {
this.pendingFindMatches[i] = true;
this.extractTextPromises[i].then(function (pageIdx) {
delete self.pendingFindMatches[pageIdx];
self.calcFindMatch(pageIdx);
this.extractTextPromises[i].then(pageIdx => {
delete this.pendingFindMatches[pageIdx];
this.calcFindMatch(pageIdx);
});
}
}
@ -3602,11 +3591,10 @@ var _grab_to_pan = __webpack_require__(11);
var _ui_utils = __webpack_require__(0);
var HandTool = function HandToolClosure() {
function HandTool(options) {
this.container = options.container;
this.eventBus = options.eventBus;
var preferences = options.preferences;
class HandTool {
constructor({ container, eventBus, preferences }) {
this.container = container;
this.eventBus = eventBus;
this.wasActive = false;
this.handTool = new _grab_to_pan.GrabToPan({
element: this.container,
@ -3615,11 +3603,12 @@ var HandTool = function HandToolClosure() {
}
});
this.eventBus.on('togglehandtool', this.toggle.bind(this));
Promise.all([_ui_utils.localized, preferences.get('enableHandToolOnLoad')]).then(values => {
let enableOnLoad = preferences.get('enableHandToolOnLoad');
Promise.all([_ui_utils.localized, enableOnLoad]).then(values => {
if (values[1] === true) {
this.handTool.activate();
}
}).catch(function rejected(reason) {});
}).catch(function (reason) {});
this.eventBus.on('presentationmodechanged', evt => {
if (evt.switchInProgress) {
return;
@ -3631,28 +3620,25 @@ var HandTool = function HandToolClosure() {
}
});
}
HandTool.prototype = {
get isActive() {
return !!this.handTool.active;
},
toggle: function HandTool_toggle() {
this.handTool.toggle();
},
enterPresentationMode: function HandTool_enterPresentationMode() {
if (this.isActive) {
this.wasActive = true;
this.handTool.deactivate();
}
},
exitPresentationMode: function HandTool_exitPresentationMode() {
if (this.wasActive) {
this.wasActive = false;
this.handTool.activate();
}
get isActive() {
return !!this.handTool.active;
}
toggle() {
this.handTool.toggle();
}
enterPresentationMode() {
if (this.isActive) {
this.wasActive = true;
this.handTool.deactivate();
}
};
return HandTool;
}();
}
exitPresentationMode() {
if (this.wasActive) {
this.wasActive = false;
this.handTool.activate();
}
}
}
exports.HandTool = HandTool;
/***/ }),
@ -6948,8 +6934,8 @@ exports.SecondaryToolbar = undefined;
var _ui_utils = __webpack_require__(0);
var SecondaryToolbar = function SecondaryToolbarClosure() {
function SecondaryToolbar(options, mainContainer, eventBus) {
class SecondaryToolbar {
constructor(options, mainContainer, eventBus) {
this.toolbar = options.toolbar;
this.toggleButton = options.toggleButton;
this.toolbarButtonContainer = options.toolbarButtonContainer;
@ -7014,98 +7000,94 @@ var SecondaryToolbar = function SecondaryToolbarClosure() {
this._bindHandToolListener(options.toggleHandToolButton);
this.eventBus.on('resize', this._setMaxHeight.bind(this));
}
SecondaryToolbar.prototype = {
get isOpen() {
return this.opened;
},
setPageNumber: function SecondaryToolbar_setPageNumber(pageNumber) {
this.pageNumber = pageNumber;
this._updateUIState();
},
setPagesCount: function SecondaryToolbar_setPagesCount(pagesCount) {
this.pagesCount = pagesCount;
this._updateUIState();
},
reset: function SecondaryToolbar_reset() {
this.pageNumber = 0;
this.pagesCount = 0;
this._updateUIState();
},
_updateUIState: function SecondaryToolbar_updateUIState() {
var items = this.items;
items.firstPage.disabled = this.pageNumber <= 1;
items.lastPage.disabled = this.pageNumber >= this.pagesCount;
items.pageRotateCw.disabled = this.pagesCount === 0;
items.pageRotateCcw.disabled = this.pagesCount === 0;
},
_bindClickListeners: function SecondaryToolbar_bindClickListeners() {
this.toggleButton.addEventListener('click', this.toggle.bind(this));
for (let button in this.buttons) {
let { element, eventName, close } = this.buttons[button];
element.addEventListener('click', evt => {
if (eventName !== null) {
this.eventBus.dispatch(eventName, { source: this });
}
if (close) {
this.close();
}
});
}
},
_bindHandToolListener: function SecondaryToolbar_bindHandToolListener(toggleHandToolButton) {
var isHandToolActive = false;
this.eventBus.on('handtoolchanged', function (e) {
if (isHandToolActive === e.isActive) {
return;
get isOpen() {
return this.opened;
}
setPageNumber(pageNumber) {
this.pageNumber = pageNumber;
this._updateUIState();
}
setPagesCount(pagesCount) {
this.pagesCount = pagesCount;
this._updateUIState();
}
reset() {
this.pageNumber = 0;
this.pagesCount = 0;
this._updateUIState();
}
_updateUIState() {
this.items.firstPage.disabled = this.pageNumber <= 1;
this.items.lastPage.disabled = this.pageNumber >= this.pagesCount;
this.items.pageRotateCw.disabled = this.pagesCount === 0;
this.items.pageRotateCcw.disabled = this.pagesCount === 0;
}
_bindClickListeners() {
this.toggleButton.addEventListener('click', this.toggle.bind(this));
for (let button in this.buttons) {
let { element, eventName, close } = this.buttons[button];
element.addEventListener('click', evt => {
if (eventName !== null) {
this.eventBus.dispatch(eventName, { source: this });
}
isHandToolActive = e.isActive;
if (isHandToolActive) {
toggleHandToolButton.title = _ui_utils.mozL10n.get('hand_tool_disable.title', null, 'Disable hand tool');
toggleHandToolButton.firstElementChild.textContent = _ui_utils.mozL10n.get('hand_tool_disable_label', null, 'Disable hand tool');
} else {
toggleHandToolButton.title = _ui_utils.mozL10n.get('hand_tool_enable.title', null, 'Enable hand tool');
toggleHandToolButton.firstElementChild.textContent = _ui_utils.mozL10n.get('hand_tool_enable_label', null, 'Enable hand tool');
if (close) {
this.close();
}
});
},
open: function SecondaryToolbar_open() {
if (this.opened) {
return;
}
this.opened = true;
this._setMaxHeight();
this.toggleButton.classList.add('toggled');
this.toolbar.classList.remove('hidden');
},
close: function SecondaryToolbar_close() {
if (!this.opened) {
return;
}
this.opened = false;
this.toolbar.classList.add('hidden');
this.toggleButton.classList.remove('toggled');
},
toggle: function SecondaryToolbar_toggle() {
if (this.opened) {
this.close();
} else {
this.open();
}
},
_setMaxHeight: function SecondaryToolbar_setMaxHeight() {
if (!this.opened) {
return;
}
this.containerHeight = this.mainContainer.clientHeight;
if (this.containerHeight === this.previousContainerHeight) {
return;
}
this.toolbarButtonContainer.setAttribute('style', 'max-height: ' + (this.containerHeight - _ui_utils.SCROLLBAR_PADDING) + 'px;');
this.previousContainerHeight = this.containerHeight;
}
};
return SecondaryToolbar;
}();
}
_bindHandToolListener(toggleHandToolButton) {
let isHandToolActive = false;
this.eventBus.on('handtoolchanged', function (evt) {
if (isHandToolActive === evt.isActive) {
return;
}
isHandToolActive = evt.isActive;
if (isHandToolActive) {
toggleHandToolButton.title = _ui_utils.mozL10n.get('hand_tool_disable.title', null, 'Disable hand tool');
toggleHandToolButton.firstElementChild.textContent = _ui_utils.mozL10n.get('hand_tool_disable_label', null, 'Disable hand tool');
} else {
toggleHandToolButton.title = _ui_utils.mozL10n.get('hand_tool_enable.title', null, 'Enable hand tool');
toggleHandToolButton.firstElementChild.textContent = _ui_utils.mozL10n.get('hand_tool_enable_label', null, 'Enable hand tool');
}
});
}
open() {
if (this.opened) {
return;
}
this.opened = true;
this._setMaxHeight();
this.toggleButton.classList.add('toggled');
this.toolbar.classList.remove('hidden');
}
close() {
if (!this.opened) {
return;
}
this.opened = false;
this.toolbar.classList.add('hidden');
this.toggleButton.classList.remove('toggled');
}
toggle() {
if (this.opened) {
this.close();
} else {
this.open();
}
}
_setMaxHeight() {
if (!this.opened) {
return;
}
this.containerHeight = this.mainContainer.clientHeight;
if (this.containerHeight === this.previousContainerHeight) {
return;
}
this.toolbarButtonContainer.setAttribute('style', 'max-height: ' + (this.containerHeight - _ui_utils.SCROLLBAR_PADDING) + 'px;');
this.previousContainerHeight = this.containerHeight;
}
}
exports.SecondaryToolbar = SecondaryToolbar;
/***/ }),

Просмотреть файл

@ -4,6 +4,33 @@
"use strict";
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
function* getNames(x) {
yield* Object.getOwnPropertyNames(x);
yield* Object.getOwnPropertySymbols(x);
}
// Utility function to get own properties descriptor map.
function getOwnPropertyDescriptors(...objects) {
let descriptors = {};
for (let object of objects) {
for (let name of getNames(object)) {
descriptors[name] = getOwnPropertyDescriptor(object, name);
}
}
return descriptors;
}
/**
* Returns a frozen object with that inherits from the given `prototype` and
* implements all own properties of the given `properties` object.
*/
function extend(prototype, properties) {
return Object.create(prototype,
getOwnPropertyDescriptors(properties));
}
/**
* Apply a 'flashed' background and foreground color to elements. Intended
* to be used with flashElementOff as a way of drawing attention to an element.
@ -127,6 +154,7 @@ function truncateString(str, maxLength) {
}
module.exports = {
extend,
flashElementOn,
flashElementOff,
getAutocompleteMaxWidth,

Просмотреть файл

@ -8,7 +8,6 @@ const PREVIEW_MAX_DIM_PREF = "devtools.inspector.imagePreviewTooltipSize";
const promise = require("promise");
const Services = require("Services");
const Heritage = require("sdk/core/heritage");
const {Task} = require("devtools/shared/task");
const nodeConstants = require("devtools/shared/dom-node-constants");
const clipboardHelper = require("devtools/shared/platform/clipboard");
@ -16,6 +15,7 @@ const {setImageTooltip, setBrokenImageTooltip} =
require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const MarkupContainer = require("devtools/client/inspector/markup/views/markup-container");
const ElementEditor = require("devtools/client/inspector/markup/views/element-editor");
const {extend} = require("devtools/client/inspector/markup/utils");
// Lazy load this module as _buildEventTooltipContent is only called on click
loader.lazyRequireGetter(this, "setEventTooltip",
@ -44,7 +44,7 @@ function MarkupElementContainer(markupView, node) {
this.tagLine.appendChild(this.editor.elt);
}
MarkupElementContainer.prototype = Heritage.extend(MarkupContainer.prototype, {
MarkupElementContainer.prototype = extend(MarkupContainer.prototype, {
_buildEventTooltipContent: Task.async(function* (target, tooltip) {
if (target.hasAttribute("data-event")) {
yield tooltip.hide();

Просмотреть файл

@ -4,9 +4,9 @@
"use strict";
const Heritage = require("sdk/core/heritage");
const ReadOnlyEditor = require("devtools/client/inspector/markup/views/read-only-editor");
const MarkupContainer = require("devtools/client/inspector/markup/views/markup-container");
const {extend} = require("devtools/client/inspector/markup/utils");
/**
* An implementation of MarkupContainer for Pseudo Elements,
@ -28,6 +28,6 @@ function MarkupReadOnlyContainer(markupView, node) {
}
MarkupReadOnlyContainer.prototype =
Heritage.extend(MarkupContainer.prototype, {});
extend(MarkupContainer.prototype, {});
module.exports = MarkupReadOnlyContainer;

Просмотреть файл

@ -4,10 +4,10 @@
"use strict";
const Heritage = require("sdk/core/heritage");
const nodeConstants = require("devtools/shared/dom-node-constants");
const TextEditor = require("devtools/client/inspector/markup/views/text-editor");
const MarkupContainer = require("devtools/client/inspector/markup/views/markup-container");
const {extend} = require("devtools/client/inspector/markup/utils");
/**
* An implementation of MarkupContainer for text node and comment nodes.
@ -35,6 +35,6 @@ function MarkupTextContainer(markupView, node) {
this.tagLine.appendChild(this.editor.elt);
}
MarkupTextContainer.prototype = Heritage.extend(MarkupContainer.prototype, {});
MarkupTextContainer.prototype = extend(MarkupContainer.prototype, {});
module.exports = MarkupTextContainer;

Просмотреть файл

@ -308,8 +308,11 @@ Converter.prototype = {
break;
case "save":
// The window ID is needed when the JSON Viewer is inside an iframe.
let windowID = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
childProcessMessageManager.sendAsyncMessage(
"devtools:jsonview:save", value);
"devtools:jsonview:save", {url: value, windowID: windowID});
}
},

Просмотреть файл

@ -15,6 +15,7 @@ define(function (require, exports, module) {
const headers = document.getElementById("headers");
let jsonData;
let prettyURL;
try {
jsonData = JSON.parse(json.textContent);
@ -45,7 +46,10 @@ define(function (require, exports, module) {
},
onSaveJson: function () {
dispatchEvent("save", input.prettified ? input.jsonPretty : input.jsonText);
if (input.prettified && !prettyURL) {
prettyURL = URL.createObjectURL(new window.Blob([input.jsonPretty]));
}
dispatchEvent("save", input.prettified ? prettyURL : null);
},
onCopyHeaders: function () {

Просмотреть файл

@ -7,11 +7,17 @@
"use strict";
const { Cu } = require("chrome");
const { Cu, Cc, Ci } = require("chrome");
const Services = require("Services");
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
XPCOMUtils.defineLazyGetter(this, "chrome", function () {
return Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
});
XPCOMUtils.defineLazyGetter(this, "JsonViewUtils", function () {
return require("devtools/client/jsonview/utils");
});
@ -50,9 +56,28 @@ var JsonView = {
* in the parent process.
*/
onSave: function (message) {
JsonViewUtils.getTargetFile().then(file => {
JsonViewUtils.saveToFile(file, message.data);
}, () => {});
let browser = chrome.gBrowser.selectedBrowser;
if (message.data.url === null) {
// Save original contents
chrome.saveBrowser(browser, false, message.data.windowID);
} else {
// The following code emulates saveBrowser, but:
// - Uses the given blob URL containing the custom contents to save.
// - Obtains the file name from the URL of the document, not the blob.
let persistable = browser.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader.QueryInterface(Ci.nsIWebBrowserPersistable);
persistable.startPersistence(message.data.windowID, {
onDocumentReady(doc) {
let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
chrome.internalSave(message.data.url, doc, filename, null, doc.contentType,
false, null, null, null, doc, false, null, undefined);
},
onError(status) {
throw new Error("JSON Viewer's onSave failed in startPersistence");
}
});
}
}
};

Просмотреть файл

@ -6,86 +6,9 @@
"use strict";
const { Cu, Cc, Ci } = require("chrome");
const { Cu } = require("chrome");
const Services = require("Services");
const OPEN_FLAGS = {
RDONLY: parseInt("0x01", 16),
WRONLY: parseInt("0x02", 16),
CREATE_FILE: parseInt("0x08", 16),
APPEND: parseInt("0x10", 16),
TRUNCATE: parseInt("0x20", 16),
EXCL: parseInt("0x80", 16)
};
let filePickerShown = false;
/**
* Open File Save As dialog and let the user to pick proper file location.
*/
exports.getTargetFile = function () {
return new Promise((resolve, reject) => {
if (filePickerShown) {
reject(null);
return;
}
filePickerShown = true;
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
let win = Services.wm.getMostRecentWindow("navigator:browser");
fp.init(win, null, Ci.nsIFilePicker.modeSave);
fp.appendFilter("JSON Files", "*.json; *.jsonp;");
fp.appendFilters(Ci.nsIFilePicker.filterText);
fp.appendFilters(Ci.nsIFilePicker.filterAll);
fp.filterIndex = 0;
fp.open(rv => {
filePickerShown = false;
if (rv == Ci.nsIFilePicker.returnOK || rv == Ci.nsIFilePicker.returnReplace) {
resolve(fp.file);
} else {
reject(null);
}
});
});
};
/**
* Save JSON to a file
*/
exports.saveToFile = function (file, jsonString) {
let foStream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
// write, create, truncate
let openFlags = OPEN_FLAGS.WRONLY | OPEN_FLAGS.CREATE_FILE |
OPEN_FLAGS.TRUNCATE;
let permFlags = parseInt("0666", 8);
foStream.init(file, openFlags, permFlags, 0);
let converter = Cc["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Ci.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
// The entire jsonString can be huge so, write the data in chunks.
let chunkLength = 1024 * 1204;
for (let i = 0; i <= jsonString.length; i++) {
let data = jsonString.substr(i, chunkLength + 1);
if (data) {
converter.writeString(data);
}
i = i + chunkLength;
}
// this closes foStream
converter.close();
};
/**
* Get the current theme from preferences.
*/

Просмотреть файл

@ -12,7 +12,7 @@ const {
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const Actions = require("../actions/index");
const { FILTER_SEARCH_DELAY } = require("../constants");
const { FILTER_SEARCH_DELAY, FILTER_FLAGS } = require("../constants");
const {
getDisplayedRequestsSummary,
getRequestFilterTypes,
@ -109,6 +109,7 @@ const Toolbar = createClass({
placeholder: SEARCH_PLACE_HOLDER,
type: "filter",
onChange: setRequestFilterText,
autocompleteList: FILTER_FLAGS.map((item) => `${item}:`),
}),
button({
className: toggleButtonClassName.join(" "),

Просмотреть файл

@ -158,6 +158,19 @@ const HEADERS = [
}
];
const HEADER_FILTERS = HEADERS
.filter(h => h.canFilter)
.map(h => h.filterKey || h.name);
const FILTER_FLAGS = [
...HEADER_FILTERS,
"mime-type",
"larger-than",
"is",
"has-response-header",
"regexp",
];
const REQUESTS_WATERFALL = {
BACKGROUND_TICKS_MULTIPLE: 5, // ms
BACKGROUND_TICKS_SCALES: 3,
@ -180,6 +193,7 @@ const general = {
EVENTS,
FILTER_SEARCH_DELAY: 200,
HEADERS,
FILTER_FLAGS,
SOURCE_EDITOR_SYNTAX_HIGHLIGHT_MAX_SIZE: 51200, // 50 KB in bytes
REQUESTS_WATERFALL,
};

Просмотреть файл

@ -30,23 +30,8 @@
"use strict";
const { HEADERS } = require("../constants");
const { FILTER_FLAGS } = require("../constants");
const { getFormattedIPAndPort } = require("./format-utils");
const HEADER_FILTERS = HEADERS
.filter(h => h.canFilter)
.map(h => h.filterKey || h.name);
const FILTER_FLAGS = [
...HEADER_FILTERS,
"set-cookie-domain",
"set-cookie-name",
"set-cookie-value",
"mime-type",
"larger-than",
"is",
"has-response-header",
"regexp",
];
/*
The function `parseFilters` is from:

Просмотреть файл

@ -42,6 +42,7 @@ let webpackConfig = {
"devtools/client/framework/menu": "devtools-modules/src/menu",
"devtools/client/framework/menu-item": path.join(__dirname, "../../client/framework/menu-item"),
"devtools/client/locales": path.join(__dirname, "../../client/locales/en-US"),
"devtools/client/shared/components/autocomplete-popup": path.join(__dirname, "../../client/shared/components/autocomplete-popup"),
"devtools/client/shared/components/reps/reps": path.join(__dirname, "../../client/shared/components/reps/reps"),
"devtools/client/shared/components/search-box": path.join(__dirname, "../../client/shared/components/search-box"),
"devtools/client/shared/components/splitter/draggable": path.join(__dirname, "../../client/shared/components/splitter/draggable"),

Просмотреть файл

@ -0,0 +1,122 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
module.exports = createClass({
displayName: "AutocompletePopup",
propTypes: {
list: PropTypes.array.isRequired,
filter: PropTypes.string.isRequired,
onItemSelected: PropTypes.func.isRequired,
},
getInitialState() {
return this.computeState(this.props);
},
componentWillReceiveProps(nextProps) {
if (this.props.filter === nextProps.filter) {
return;
}
this.setState(this.computeState(nextProps));
},
componentDidUpdate() {
if (this.refs.selected) {
this.refs.selected.scrollIntoView(false);
}
},
computeState({ filter, list }) {
let filteredList = list.filter((item) => {
return item.toLowerCase().startsWith(filter.toLowerCase())
&& item.toLowerCase() !== filter.toLowerCase();
}).sort();
let selectedIndex = filteredList.length == 1 ? 0 : -1;
return { filteredList, selectedIndex };
},
/**
* Use this method to select the top-most item
* This method is public, called outside of the autocomplete-popup component.
*/
jumpToTop() {
this.setState({ selectedIndex: 0 });
},
/**
* Use this method to select the bottom-most item
* This method is public.
*/
jumpToBottom() {
let selectedIndex = this.state.filteredList.length - 1;
this.setState({ selectedIndex });
},
/**
* Increment the selected index with the provided increment value. Will cycle to the
* beginning/end of the list if the index exceeds the list boundaries.
* This method is public.
*
* @param {number} increment - No. of hops in the direction
*/
jumpBy(increment = 1) {
let { filteredList, selectedIndex } = this.state;
let nextIndex = selectedIndex + increment;
if (increment > 0) {
// Positive cycling
nextIndex = nextIndex > filteredList.length - 1 ? 0 : nextIndex;
} else if (increment < 0) {
// Inverse cycling
nextIndex = nextIndex < 0 ? filteredList.length - 1 : nextIndex;
}
this.setState({selectedIndex: nextIndex});
},
/**
* Submit the currently selected item to the onItemSelected callback
* This method is public.
*/
select() {
if (this.refs.selected) {
this.props.onItemSelected(this.refs.selected.textContent);
}
},
onMouseDown(e) {
e.preventDefault();
this.setState({ selectedIndex: Number(e.target.dataset.index) }, this.select);
},
render() {
let { filteredList } = this.state;
return filteredList.length > 0 && dom.div(
{ className: "devtools-autocomplete-popup devtools-monospace" },
dom.ul(
{ className: "devtools-autocomplete-listbox" },
filteredList.map((item, i) => {
let isSelected = this.state.selectedIndex == i;
let itemClassList = ["autocomplete-item"];
if (isSelected) {
itemClassList.push("autocomplete-selected");
}
return dom.li({
key: i,
"data-index": i,
className: itemClassList.join(" "),
ref: isSelected ? "selected" : null,
onMouseDown: this.onMouseDown,
}, item);
})
)
);
}
});

Просмотреть файл

@ -12,6 +12,7 @@ DIRS += [
]
DevToolsModules(
'autocomplete-popup.js',
'frame.js',
'h-split-box.js',
'notification-box.css',

Просмотреть файл

@ -6,8 +6,9 @@
"use strict";
const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react");
const { DOM: dom, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react");
const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
const AutocompletePopup = createFactory(require("devtools/client/shared/components/autocomplete-popup"));
/**
* A generic search box component for use across devtools
@ -20,12 +21,20 @@ module.exports = createClass({
keyShortcut: PropTypes.string,
onChange: PropTypes.func,
placeholder: PropTypes.string,
type: PropTypes.string
type: PropTypes.string,
autocompleteList: PropTypes.array,
},
getDefaultProps() {
return {
autocompleteList: [],
};
},
getInitialState() {
return {
value: ""
value: "",
focused: false,
};
},
@ -56,7 +65,9 @@ module.exports = createClass({
onChange() {
if (this.state.value !== this.refs.input.value) {
this.setState({ value: this.refs.input.value });
this.setState({
value: this.refs.input.value,
});
}
if (!this.props.delay) {
@ -82,8 +93,59 @@ module.exports = createClass({
this.onChange();
},
onFocus() {
this.setState({ focused: true });
},
onBlur() {
this.setState({ focused: false });
},
onKeyDown(e) {
let { autocompleteList } = this.props;
let { autocomplete } = this.refs;
if (autocompleteList.length == 0) {
return;
}
switch (e.key) {
case "ArrowDown":
autocomplete.jumpBy(1);
break;
case "ArrowUp":
autocomplete.jumpBy(-1);
break;
case "PageDown":
autocomplete.jumpBy(5);
break;
case "PageUp":
autocomplete.jumpBy(-5);
break;
case "Enter":
case "Tab":
e.preventDefault();
autocomplete.select();
break;
case "Escape":
e.preventDefault();
this.onBlur();
break;
case "Home":
autocomplete.jumpToTop();
break;
case "End":
autocomplete.jumpToBottom();
break;
}
},
render() {
let { type = "search", placeholder } = this.props;
let {
type = "search",
placeholder,
autocompleteList
} = this.props;
let { value } = this.state;
let divClassList = ["devtools-searchbox", "has-clear-btn"];
let inputClassList = [`devtools-${type}input`];
@ -96,14 +158,27 @@ module.exports = createClass({
dom.input({
className: inputClassList.join(" "),
onChange: this.onChange,
onFocus: this.onFocus,
onBlur: this.onBlur,
onKeyDown: this.onKeyDown,
placeholder,
ref: "input",
value
value,
}),
dom.button({
className: "devtools-searchinput-clear",
hidden: value == "",
onClick: this.onClearButtonClick
}),
autocompleteList.length > 0 && this.state.focused &&
AutocompletePopup({
list: autocompleteList,
filter: value,
ref: "autocomplete",
onItemSelected: (itemValue) => {
this.setState({ value: itemValue });
this.onChange();
}
})
);
}

Просмотреть файл

@ -132,7 +132,7 @@ function setBrokenImageTooltip(tooltip, doc) {
div.className = "theme-comment devtools-tooltip-image-broken";
let message = L10N.getStr("previewTooltip.image.brokenImage");
div.textContent = message;
tooltip.setContent(div, {width: 150, height: 30});
tooltip.setContent(div);
}
module.exports.getImageDimensions = getImageDimensions;

Просмотреть файл

@ -82,35 +82,13 @@ html|button, html|select {
background-color: transparent;
border-radius: 4px;
padding: 1px 0;
}
.devtools-autocomplete-listbox .autocomplete-selected {
background-color: rgba(0,0,0,0.2);
}
.devtools-autocomplete-listbox.dark-theme .autocomplete-selected,
.devtools-autocomplete-listbox.dark-theme .autocomplete-item:hover {
background-color: rgba(0,0,0,0.5);
}
.devtools-autocomplete-listbox.dark-theme .autocomplete-selected > .autocomplete-value,
.devtools-autocomplete-listbox:focus.dark-theme .autocomplete-selected > .initial-value {
color: hsl(208,100%,60%);
}
.devtools-autocomplete-listbox.dark-theme .autocomplete-selected > span {
color: #eee;
}
.devtools-autocomplete-listbox.dark-theme .autocomplete-item > span {
color: #ccc;
cursor: default;
}
.devtools-autocomplete-listbox .autocomplete-item > .initial-value,
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-value {
margin: 0;
padding: 0;
cursor: default;
}
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-count {
@ -120,52 +98,60 @@ html|button, html|select {
/* Rest of the dark and light theme */
.devtools-autocomplete-popup,
.CodeMirror-hints,
.CodeMirror-Tern-tooltip {
border: 1px solid hsl(210,24%,90%);
background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset;
}
.theme-dark .devtools-autocomplete-popup,
.theme-dark .CodeMirror-hints,
.theme-dark .CodeMirror-Tern-tooltip {
border: 1px solid hsl(210,11%,10%);
background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
}
.devtools-autocomplete-popup.light-theme,
.light-theme .CodeMirror-hints,
.light-theme .CodeMirror-Tern-tooltip {
border: 1px solid hsl(210,24%,90%);
background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
}
.devtools-autocomplete-popup.light-theme {
box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset;
box-shadow: none;
}
.theme-firebug .devtools-autocomplete-popup {
border-color: var(--theme-splitter-color);
border-radius: 5px;
font-size: var(--theme-autompletion-font-size);
}
.devtools-autocomplete-popup.firebug-theme {
background: var(--theme-body-background);
}
.devtools-autocomplete-listbox.firebug-theme .autocomplete-selected,
.devtools-autocomplete-listbox.firebug-theme .autocomplete-item:hover,
.devtools-autocomplete-listbox.light-theme .autocomplete-selected,
.devtools-autocomplete-listbox.light-theme .autocomplete-item:hover {
.devtools-autocomplete-listbox .autocomplete-selected,
.devtools-autocomplete-listbox .autocomplete-item:hover {
background-color: rgba(128,128,128,0.3);
}
.devtools-autocomplete-listbox.firebug-theme .autocomplete-selected > .autocomplete-value,
.devtools-autocomplete-listbox:focus.firebug-theme .autocomplete-selected > .initial-value,
.devtools-autocomplete-listbox.light-theme .autocomplete-selected > .autocomplete-value,
.devtools-autocomplete-listbox:focus.light-theme .autocomplete-selected > .initial-value {
.theme-dark .devtools-autocomplete-listbox .autocomplete-selected,
.theme-dark .devtools-autocomplete-listbox .autocomplete-item:hover {
background-color: rgba(0,0,0,0.5);
}
.devtools-autocomplete-listbox .autocomplete-selected > .autocomplete-value,
.devtools-autocomplete-listbox:focus .autocomplete-selected > .initial-value {
color: #222;
}
.devtools-autocomplete-listbox.firebug-theme .autocomplete-item > span,
.devtools-autocomplete-listbox.light-theme .autocomplete-item > span {
.theme-dark .devtools-autocomplete-listbox .autocomplete-selected > .autocomplete-value,
.theme-dark .devtools-autocomplete-listbox:focus .autocomplete-selected > .initial-value {
color: hsl(208,100%,60%);
}
.devtools-autocomplete-listbox .autocomplete-item > span {
color: #666;
}
.theme-dark .devtools-autocomplete-listbox .autocomplete-item > span {
color: #ccc;
}
.theme-dark .devtools-autocomplete-listbox .autocomplete-selected > span {
color: #eee;
}
/* Autocomplete list clone used for accessibility. */
.devtools-autocomplete-list-aria-clone {
@ -493,6 +479,14 @@ checkbox:-moz-focusring {
outline: none;
}
.devtools-searchbox .devtools-autocomplete-popup {
position: absolute;
top: 100%;
width: 100%;
line-height: initial !important;
z-index: 999;
}
/* Don't add 'double spacing' for inputs that are at beginning / end
of a toolbar (since the toolbar has it's own spacing). */
.devtools-toolbar > .devtools-textinput:first-child,

Просмотреть файл

@ -452,6 +452,5 @@
.devtools-tooltip-image-broken {
box-sizing: border-box;
height: 100%;
text-align: center;
line-height: 30px;
padding: 7px;
}

Просмотреть файл

@ -6883,6 +6883,34 @@ nsContentUtils::WidgetForDocument(const nsIDocument* aDoc)
return nullptr;
}
nsIWidget*
nsContentUtils::WidgetForContent(const nsIContent* aContent)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
frame = nsLayoutUtils::GetDisplayRootFrame(frame);
nsView* view = frame->GetView();
if (view) {
return view->GetWidget();
}
}
return nullptr;
}
already_AddRefed<LayerManager>
nsContentUtils::LayerManagerForContent(const nsIContent *aContent)
{
nsIWidget* widget = nsContentUtils::WidgetForContent(aContent);
if (widget) {
RefPtr<LayerManager> manager = widget->GetLayerManager();
return manager.forget();
}
return nullptr;
}
static already_AddRefed<LayerManager>
LayerManagerForDocumentInternal(const nsIDocument *aDoc, bool aRequirePersistent)
{

Просмотреть файл

@ -2037,15 +2037,29 @@ public:
* Returns the widget for this document if there is one. Looks at all ancestor
* documents to try to find a widget, so for example this can still find a
* widget for documents in display:none frames that have no presentation.
*
* You should probably use WidgetForContent() instead of this, unless you have
* a good reason to do otherwise.
*/
static nsIWidget* WidgetForDocument(const nsIDocument* aDoc);
/**
* Returns the appropriate widget for this element, if there is one. Unlike
* WidgetForDocument(), this returns the correct widget for content in popups.
*
* You should probably use this instead of WidgetForDocument().
*/
static nsIWidget* WidgetForContent(const nsIContent* aContent);
/**
* Returns a layer manager to use for the given document. Basically we
* look up the document hierarchy for the first document which has
* a presentation with an associated widget, and use that widget's
* layer manager.
*
* You should probably use LayerManagerForContent() instead of this, unless
* you have a good reason to do otherwise.
*
* @param aDoc the document for which to return a layer manager.
* @param aAllowRetaining an outparam that states whether the returned
* layer manager should be used for retained layers
@ -2053,6 +2067,16 @@ public:
static already_AddRefed<mozilla::layers::LayerManager>
LayerManagerForDocument(const nsIDocument *aDoc);
/**
* Returns a layer manager to use for the given content. Unlike
* LayerManagerForDocument(), this returns the correct layer manager for
* content in popups.
*
* You should probably use this instead of LayerManagerForDocument().
*/
static already_AddRefed<mozilla::layers::LayerManager>
LayerManagerForContent(const nsIContent *aContent);
/**
* Returns a layer manager to use for the given document. Basically we
* look up the document hierarchy for the first document which has

Просмотреть файл

@ -57,6 +57,7 @@
#include "nsLayoutUtils.h"
#include "nsMappedAttributes.h"
#include "nsView.h"
#include "nsBaseWidget.h"
#include "GroupedSHistory.h"
#include "PartialSHistory.h"
@ -1259,9 +1260,18 @@ nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
return false;
}
RefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForDocument(mOwnerContent->GetComposedDoc());
if (!layerManager) {
// We never want to host remote frameloaders in simple popups, like menus.
nsIWidget* widget = nsContentUtils::WidgetForContent(mOwnerContent);
if (!widget || static_cast<nsBaseWidget*>(widget)->IsSmallPopup()) {
return false;
}
RenderFrameParent* rfp = GetCurrentRenderFrame();
if (!rfp) {
return false;
}
if (!rfp->AttachLayerManager()) {
// This is just not going to work.
return false;
}

Просмотреть файл

@ -151,7 +151,7 @@ skip-if(!winWidget) pref(webgl.disable-angle,true) == webgl-color-test.html?nat
# Bug 1255062
== clip-multiple-move-1.html clip-multiple-move-1-ref.html
== clip-multiple-move-2.html clip-multiple-move-2-ref.html
fuzzy-if(skiaContent,1,150) == clip-multiple-move-2.html clip-multiple-move-2-ref.html
# Bug 815648
== stroketext-shadow.html stroketext-shadow-ref.html

Просмотреть файл

@ -2293,7 +2293,7 @@ TabParent::RecvGetDPI(float* aValue)
{
TryCacheDPIAndScale();
MOZ_ASSERT(mDPI > 0,
MOZ_ASSERT(mDPI > 0 || mFrameElement,
"Must not ask for DPI before OwnerElement is received!");
*aValue = mDPI;
return IPC_OK();
@ -2304,7 +2304,7 @@ TabParent::RecvGetDefaultScale(double* aValue)
{
TryCacheDPIAndScale();
MOZ_ASSERT(mDefaultScale.scale > 0,
MOZ_ASSERT(mDefaultScale.scale > 0 || mFrameElement,
"Must not ask for scale before OwnerElement is received!");
*aValue = mDefaultScale.scale;
return IPC_OK();
@ -2315,7 +2315,7 @@ TabParent::RecvGetWidgetRounding(int32_t* aValue)
{
TryCacheDPIAndScale();
MOZ_ASSERT(mRounding > 0,
MOZ_ASSERT(mRounding > 0 || mFrameElement,
"Must not ask for rounding before OwnerElement is received!");
*aValue = mRounding;
return IPC_OK();
@ -2581,7 +2581,7 @@ TabParent::GetWidget() const
if (!mFrameElement) {
return nullptr;
}
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc());
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(mFrameElement);
return widget.forget();
}

Просмотреть файл

@ -1972,6 +1972,13 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
channel->SetContentType(NS_ConvertUTF16toUTF8(mOverrideMimeType));
}
// Fallback to 'application/octet-stream'
nsAutoCString type;
channel->GetContentType(type);
if (type.Equals(UNKNOWN_CONTENT_TYPE)) {
channel->SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
}
DetectCharset();
// Set up arraybuffer
@ -2696,12 +2703,13 @@ XMLHttpRequestMainThread::InitiateFetch(nsIInputStream* aUploadStream,
// Since we expect XML data, set the type hint accordingly
// if the channel doesn't know any content type.
// This means that we always try to parse local files as XML
// ignoring return value, as this is not critical
// ignoring return value, as this is not critical. Use text/xml as fallback
// MIME type.
nsAutoCString contentType;
if (NS_FAILED(mChannel->GetContentType(contentType)) ||
contentType.IsEmpty() ||
contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
mChannel->SetContentType(NS_LITERAL_CSTRING("application/xml"));
mChannel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
}
// Set up the preflight if needed

Просмотреть файл

@ -60,7 +60,7 @@ random-if(Android) needs-focus fails-if(stylo) != spellcheck-textarea-property-d
needs-focus == caret_on_focus.html caret_on_focus-ref.html
needs-focus fails-if(stylo) != caret_on_textarea_lastline.html caret_on_textarea_lastline-ref.html
needs-focus == input-text-onfocus-reframe.html input-text-onfocus-reframe-ref.html
needs-focus == input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe-ref.html
fuzzy-if(skiaContent,3,1) needs-focus == input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe-ref.html
needs-focus == caret_after_reframe.html caret_after_reframe-ref.html
== nobogusnode-1.html nobogusnode-ref.html
== nobogusnode-2.html nobogusnode-ref.html

Просмотреть файл

@ -84,10 +84,15 @@ LogToConsole(const nsAString& aMsg)
namespace {
// The number of permissions from the kPreloadPermissions list which are present
// in the permission manager. Used to determine if the permission manager should
// be checked for one of these preload permissions in nsContentBlocker.
static int32_t sPreloadPermissionCount = 0;
// These permissions are special permissions which must be transmitted to the
// content process before documents with their principals have loaded within
// that process. For example, the permissions which are used for content
// blocking are sent using this mechanism.
// that process. This is because these permissions are used for content
// blocking in nsContentBlocker.
//
// Permissions which are in this list are considered to have a "" permission
// key, even if their principal would not normally have that key.
@ -118,7 +123,6 @@ static const char* kPreloadPermissions[] = {
"fetch",
"image",
"manifest"
// ------------------------------------------
};
// NOTE: nullptr can be passed as aType - if it is this function will return
@ -1781,6 +1785,12 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
aExpireType, aExpireTime,
aModificationTime));
// Record a count of the number of preload permissions present in the
// content process.
if (IsPreloadPermission(mTypeArray[typeIndex].get())) {
sPreloadPermissionCount++;
}
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
UpdateDB(op, mStmtInsert, id, origin, aType, aPermission, aExpireType, aExpireTime, aModificationTime);
}
@ -1803,6 +1813,12 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
id = oldPermissionEntry.mID;
entry->GetPermissions().RemoveElementAt(index);
// Record a count of the number of preload permissions present in the
// content process.
if (IsPreloadPermission(mTypeArray[typeIndex].get())) {
sPreloadPermissionCount--;
}
if (aDBOperation == eWriteToDB)
// We care only about the id here so we pass dummy values for all other
// parameters.
@ -3248,3 +3264,10 @@ nsPermissionManager::WhenPermissionsAvailable(nsIPrincipal* aPrincipal,
});
return NS_OK;
}
NS_IMETHODIMP
nsPermissionManager::GetHasPreloadPermissions(bool* aResult)
{
*aResult = sPreloadPermissionCount > 0;
return NS_OK;
}

Просмотреть файл

@ -267,6 +267,7 @@ nsContentBlocker::TestPermission(nsIURI *aCurrentURI,
bool *aFromPrefs)
{
*aFromPrefs = false;
nsresult rv;
if (!*kTypeString[aContentType - 1]) {
// Disallow internal content policy types, they should not be used here.
@ -282,11 +283,16 @@ nsContentBlocker::TestPermission(nsIURI *aCurrentURI,
// default prefs.
// Don't forget the aContentType ranges from 1..8, while the
// array is indexed 0..7
uint32_t permission;
nsresult rv = mPermissionManager->TestPermission(aCurrentURI,
kTypeString[aContentType - 1],
&permission);
NS_ENSURE_SUCCESS(rv, rv);
// All permissions tested by this method are preload permissions, so don't
// bother actually checking with the permission manager unless we have a
// preload permission.
uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
if (mPermissionManager->GetHasPreloadPermissions()) {
rv = mPermissionManager->TestPermission(aCurrentURI,
kTypeString[aContentType - 1],
&permission);
NS_ENSURE_SUCCESS(rv, rv);
}
// If there is nothing on the list, use the default.
if (!permission) {

Просмотреть файл

@ -7,7 +7,6 @@
#include "SourceSurfaceSkia.h"
#include "ScaledFontBase.h"
#include "ScaledFontCairo.h"
#include "skia/include/core/SkBitmapDevice.h"
#include "FilterNodeSoftware.h"
#include "HelpersSkia.h"
@ -19,7 +18,7 @@
#include "skia/include/core/SkColorFilter.h"
#include "skia/include/effects/SkBlurImageFilter.h"
#include "skia/include/effects/SkLayerRasterizer.h"
#include "skia/src/core/SkSpecialImage.h"
#include "skia/src/core/SkDevice.h"
#include "Blur.h"
#include "Logging.h"
#include "Tools.h"
@ -30,10 +29,9 @@
#ifdef USE_SKIA_GPU
#include "GLDefs.h"
#include "skia/include/gpu/SkGr.h"
#include "skia/include/gpu/GrContext.h"
#include "skia/include/gpu/GrDrawContext.h"
#include "skia/include/gpu/gl/GrGLInterface.h"
#include "skia/src/gpu/GrRenderTargetContext.h"
#include "skia/src/image/SkImage_Gpu.h"
#endif
@ -270,6 +268,7 @@ DrawTargetSkia::DrawTargetSkia()
, mColorSpace(nullptr)
, mCanvasData(nullptr)
, mCGSize(0, 0)
, mNeedLayer(false)
#endif
{
}
@ -302,7 +301,7 @@ DrawTargetSkia::Snapshot()
if (mSurface->peekPixels(&pixmap)) {
image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
} else {
image = mSurface->makeImageSnapshot(SkBudgeted::kNo);
image = mSurface->makeImageSnapshot();
}
if (!snapshot->InitFromImage(image, mFormat, this)) {
return nullptr;
@ -318,23 +317,13 @@ DrawTargetSkia::LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat,
IntPoint* aOrigin)
{
// Ensure the layer is at the origin if required.
SkIPoint origin = mCanvas->getTopDevice()->getOrigin();
if (!aOrigin && !origin.isZero()) {
return false;
}
/* Test if the canvas' device has accessible pixels first, as actually
* accessing the pixels may trigger side-effects, even if it fails.
*/
if (!mCanvas->peekPixels(nullptr)) {
return false;
}
SkImageInfo info;
size_t rowBytes;
void* pixels = mCanvas->accessTopLayerPixels(&info, &rowBytes);
if (!pixels) {
SkIPoint origin;
void* pixels = mCanvas->accessTopLayerPixels(&info, &rowBytes, &origin);
if (!pixels ||
// Ensure the layer is at the origin if required.
(!aOrigin && !origin.isZero())) {
return false;
}
@ -459,7 +448,11 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
&stops->mPositions.front(),
stops->mCount,
mode, 0, &mat);
aPaint.setShader(shader);
if (shader) {
aPaint.setShader(shader);
} else {
aPaint.setColor(SK_ColorTRANSPARENT);
}
}
break;
}
@ -487,7 +480,11 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
&stops->mPositions.front(),
stops->mCount,
mode, 0, &mat);
aPaint.setShader(shader);
if (shader) {
aPaint.setShader(shader);
} else {
aPaint.setColor(SK_ColorTRANSPARENT);
}
}
break;
}
@ -528,7 +525,7 @@ GetClipBounds(SkCanvas *aCanvas)
// getClipBounds because getClipBounds inflates the the bounds
// by a pixel in each direction to compensate for antialiasing.
SkIRect deviceBounds;
if (!aCanvas->getClipDeviceBounds(&deviceBounds)) {
if (!aCanvas->getDeviceClipBounds(&deviceBounds)) {
return Rect();
}
SkMatrix inverseCTM;
@ -631,7 +628,7 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
bool forceGroup = SkImageIsMask(image) &&
aOptions.mCompositionOp != CompositionOp::OP_OVER;
AutoPaintSetup paint(mCanvas.get(), aOptions, &aDest, forceGroup);
AutoPaintSetup paint(mCanvas, aOptions, &aDest, forceGroup);
if (aSurfOptions.mSamplingFilter == SamplingFilter::POINT) {
paint.mPaint.setFilterQuality(kNone_SkFilterQuality);
}
@ -774,7 +771,7 @@ DrawTargetSkia::FillRect(const Rect &aRect,
MarkChanged();
SkRect rect = RectToSkRect(aRect);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern, &aRect, Point(0, 0), &aRect);
AutoPaintSetup paint(mCanvas, aOptions, aPattern, &aRect, Point(0, 0), &aRect);
mCanvas->drawRect(rect, paint.mPaint);
}
@ -794,7 +791,7 @@ DrawTargetSkia::Stroke(const Path *aPath,
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
@ -883,7 +880,7 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
if (aStrokeOptions.mDashLength > 0 && !rect.IsEmpty()) {
IntRect deviceClip(IntPoint(0, 0), mSize);
SkIRect clipBounds;
if (mCanvas->getClipDeviceBounds(&clipBounds)) {
if (mCanvas->getDeviceClipBounds(&clipBounds)) {
deviceClip = SkIRectToIntRect(clipBounds);
}
rect = ShrinkClippedStrokedRect(rect, deviceClip, mTransform, aStrokeOptions);
@ -893,7 +890,7 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
}
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
@ -909,7 +906,7 @@ DrawTargetSkia::StrokeLine(const Point &aStart,
const DrawOptions &aOptions)
{
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
@ -931,7 +928,7 @@ DrawTargetSkia::Fill(const Path *aPath,
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!skiaPath->GetPath().isFinite()) {
return;
@ -964,116 +961,6 @@ DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialias
}
#ifdef MOZ_WIDGET_COCOA
class CGClipApply : public SkCanvas::ClipVisitor {
public:
explicit CGClipApply(CGContextRef aCGContext)
: mCG(aCGContext) {}
void clipRect(const SkRect& aRect, SkCanvas::ClipOp op, bool antialias) override {
CGRect rect = CGRectMake(aRect.x(), aRect.y(), aRect.width(), aRect.height());
CGContextClipToRect(mCG, rect);
}
void clipRRect(const SkRRect& rrect, SkCanvas::ClipOp op, bool antialias) override {
SkPath path;
path.addRRect(rrect);
clipPath(path, op, antialias);
}
void clipPath(const SkPath& aPath, SkCanvas::ClipOp, bool antialias) override {
SkPath::Iter iter(aPath, true);
SkPoint source[4];
SkPath::Verb verb;
if (!aPath.isFinite()) {
return;
}
if (aPath.isEmpty()) {
// Weirdly, CoreGraphics clips empty paths as all shown
// but empty rects as all clipped. We detect this situation and
// workaround it appropriately
CGContextClipToRect(mCG, CGRectZero);
return;
}
CGMutablePathRef cgPath = CGPathCreateMutable();
MOZ_ASSERT(cgPath);
while ((verb = iter.next(source)) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kMove_Verb:
{
SkPoint dest = source[0];
CGPathMoveToPoint(cgPath, nullptr, dest.fX, dest.fY);
break;
}
case SkPath::kLine_Verb:
{
// The first point should be the end point of whatever
// verb we got to get here.
SkPoint second = source[1];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddLineToPoint(cgPath, nullptr, second.fX, second.fY);
break;
}
case SkPath::kQuad_Verb:
{
SkPoint second = source[1];
SkPoint third = source[2];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddQuadCurveToPoint(cgPath, nullptr,
second.fX, second.fY,
third.fX, third.fY);
break;
}
case SkPath::kCubic_Verb:
{
SkPoint second = source[1];
SkPoint third = source[2];
SkPoint fourth = source[2];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddCurveToPoint(cgPath, nullptr,
second.fX, second.fY,
third.fX, third.fY,
fourth.fX, fourth.fY);
break;
}
case SkPath::kClose_Verb:
{
if (!CGPathIsEmpty(cgPath)) {
CGPathCloseSubpath(cgPath);
}
break;
}
default:
{
SkDEBUGFAIL("unknown verb");
break;
}
} // end switch
} // end while
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGContextBeginPath(mCG);
CGContextAddPath(mCG, cgPath);
FillRule fillRule = GetFillRule(aPath.getFillType());
if (fillRule == FillRule::FILL_EVEN_ODD) {
CGContextEOClip(mCG);
} else {
CGContextClip(mCG);
}
CGPathRelease(cgPath);
}
private:
CGContextRef mCG;
};
static inline CGAffineTransform
GfxMatrixToCGAffineTransform(const Matrix &m)
{
@ -1142,7 +1029,7 @@ GfxMatrixToCGAffineTransform(const Matrix &m)
static bool
SetupCGContext(DrawTargetSkia* aDT,
CGContextRef aCGContext,
sk_sp<SkCanvas> aCanvas,
SkCanvas* aCanvas,
const IntPoint& aOrigin,
const IntSize& aSize)
{
@ -1157,10 +1044,15 @@ SetupCGContext(DrawTargetSkia* aDT,
// Want to apply clips BEFORE the transform since the transform
// will apply to the clips we apply.
// CGClipApply applies clips in device space, so it would be a mistake
// to transform these clips.
CGClipApply clipApply(aCGContext);
aCanvas->replayClips(&clipApply);
SkIRect clipBounds;
if (!aCanvas->getDeviceClipBounds(&clipBounds)) {
clipBounds = SkIRect::MakeXYWH(aOrigin.x, aOrigin.y,
aSize.width, aSize.height);
}
CGContextClipToRect(aCGContext,
CGRectMake(clipBounds.x(), clipBounds.y(),
clipBounds.width(), clipBounds.height()));
CGContextConcatCTM(aCGContext, GfxMatrixToCGAffineTransform(aDT->GetTransform()));
return true;
@ -1196,24 +1088,34 @@ SetupCGGlyphs(CGContextRef aCGContext,
// next to each other.
// The context returned from this method will have the origin
// in the top left and will hvae applied all the neccessary clips
// in the top left and will have applied all the neccessary clips
// and transforms to the CGContext. See the comment above
// SetupCGContext.
CGContextRef
DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
{
// Since we can't replay Skia clips, we have to use a layer if we have a complex clip.
// After saving a layer, the SkCanvas queries for needing a layer change so save if we
// pushed a layer.
mNeedLayer = !mCanvas->isClipEmpty() && !mCanvas->isClipRect();
if (mNeedLayer) {
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
SkCanvas::SaveLayerRec rec(nullptr, &paint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
mCanvas->saveLayer(rec);
}
uint8_t* data = nullptr;
int32_t stride;
SurfaceFormat format;
IntSize size;
IntPoint origin;
uint8_t* aSurfaceData = nullptr;
if (!LockBits(&aSurfaceData, &size, &stride, &format, &origin)) {
if (!LockBits(&data, &size, &stride, &format, &origin)) {
NS_WARNING("Could not lock skia bits to wrap CG around");
return nullptr;
}
if ((aSurfaceData == mCanvasData) && mCG && (mCGSize == size)) {
if (!mNeedLayer && (data == mCanvasData) && mCG && (mCGSize == size)) {
// If our canvas data still points to the same data,
// we can reuse the CG Context
CGContextSaveGState(mCG);
@ -1232,7 +1134,7 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
CGContextRelease(mCG);
}
mCanvasData = aSurfaceData;
mCanvasData = data;
mCGSize = size;
uint32_t bitmapInfo = (format == SurfaceFormat::A8) ?
@ -1249,6 +1151,9 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
NULL, /* Callback when released */
NULL);
if (!mCG) {
if (mNeedLayer) {
mCanvas->restore();
}
ReleaseBits(mCanvasData);
NS_WARNING("Could not create bitmap around skia data\n");
return nullptr;
@ -1269,6 +1174,17 @@ DrawTargetSkia::ReturnCGContext(CGContextRef aCGContext)
MOZ_ASSERT(aCGContext == mCG);
ReleaseBits(mCanvasData);
CGContextRestoreGState(aCGContext);
if (mNeedLayer) {
// A layer was used for clipping and is about to be popped by the restore.
// Make sure the CG context referencing it is released first so the popped
// layer doesn't accidentally get used.
if (mCG) {
CGContextRelease(mCG);
mCG = nullptr;
}
mCanvas->restore();
}
}
CGContextRef
@ -1432,7 +1348,7 @@ DrawTargetSkia::DrawGlyphs(ScaledFont* aFont,
return;
}
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (aStrokeOptions &&
!StrokeOptionsToPaint(paint.mPaint, *aStrokeOptions)) {
return;
@ -1552,7 +1468,7 @@ DrawTargetSkia::Mask(const Pattern &aSource,
const DrawOptions &aOptions)
{
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
AutoPaintSetup paint(mCanvas, aOptions, aSource);
SkPaint maskPaint;
SetPaintPattern(maskPaint, aMask);
@ -1572,7 +1488,7 @@ DrawTargetSkia::MaskSurface(const Pattern &aSource,
const DrawOptions &aOptions)
{
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource, nullptr, -aOffset);
AutoPaintSetup paint(mCanvas, aOptions, aSource, nullptr, -aOffset);
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask);
if (!alphaMask) {
@ -1618,8 +1534,8 @@ DrawTarget::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4x4& a
if (!dstSurf) {
return false;
}
sk_sp<SkCanvas> dstCanvas(
SkCanvas::NewRasterDirect(
std::unique_ptr<SkCanvas> dstCanvas(
SkCanvas::MakeRasterDirect(
SkImageInfo::Make(xformBounds.width, xformBounds.height,
GfxFormatToSkiaColorType(dstSurf->GetFormat()),
kPremul_SkAlphaType),
@ -1716,7 +1632,7 @@ DrawTargetSkia::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFor
#endif
#ifdef DEBUG
if (!IsBackedByPixels(mCanvas.get())) {
if (!IsBackedByPixels(mCanvas)) {
// If our canvas is backed by vector storage such as PDF then we want to
// create a new DrawTarget with similar storage to avoid losing fidelity
// (fidelity will be lost if the returned DT is Snapshot()'ed and drawn
@ -1753,7 +1669,7 @@ DrawTargetSkia::OptimizeGPUSourceSurface(SourceSurface *aSurface) const
}
// Upload the SkImage to a GrTexture otherwise.
sk_sp<SkImage> texture = image->makeTextureImage(mGrContext.get());
sk_sp<SkImage> texture = image->makeTextureImage(mGrContext.get(), nullptr);
if (texture) {
// Create a new SourceSurfaceSkia whose SkImage contains the GrTexture.
RefPtr<SourceSurfaceSkia> surface = new SourceSurfaceSkia();
@ -1870,7 +1786,7 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
mCanvas->save();
mCanvas->setMatrix(SkMatrix::MakeTrans(SkIntToScalar(aDestination.x), SkIntToScalar(aDestination.y)));
mCanvas->clipRect(SkRect::MakeIWH(aSourceRect.width, aSourceRect.height), kReplace_SkClipOp);
mCanvas->clipRect(SkRect::MakeIWH(aSourceRect.width, aSourceRect.height), SkClipOp::kReplace_deprecated);
SkPaint paint;
if (!image->isOpaque()) {
@ -1904,7 +1820,7 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
mSize = aSize;
mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas());
mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat));
if (info.isOpaque()) {
@ -1916,13 +1832,13 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
bool
DrawTargetSkia::Init(SkCanvas* aCanvas)
{
mCanvas = sk_ref_sp(aCanvas);
mCanvas = aCanvas;
SkImageInfo imageInfo = mCanvas->imageInfo();
// If the canvas is backed by pixels we clear it to be on the safe side. If
// it's not (for example, for PDF output) we don't.
if (IsBackedByPixels(mCanvas.get())) {
if (IsBackedByPixels(mCanvas)) {
SkColor clearColor = imageInfo.isOpaque() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
mCanvas->clear(clearColor);
}
@ -1969,7 +1885,7 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
}
// Create a GPU rendertarget/texture using the supplied GrContext.
// NewRenderTarget also implicitly clears the underlying texture on creation.
// MakeRenderTarget also implicitly clears the underlying texture on creation.
mSurface =
SkSurface::MakeRenderTarget(aGrContext,
SkBudgeted(aCached),
@ -1981,7 +1897,7 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
mGrContext = sk_ref_sp(aGrContext);
mSize = aSize;
mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas());
mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat));
return true;
}
@ -2001,7 +1917,7 @@ DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride
mSize = aSize;
mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas());
mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat));
return true;
}
@ -2041,7 +1957,7 @@ DrawTargetSkia::ClearRect(const Rect &aRect)
{
MarkChanged();
mCanvas->save();
mCanvas->clipRect(RectToSkRect(aRect), kIntersect_SkClipOp, true);
mCanvas->clipRect(RectToSkRect(aRect), SkClipOp::kIntersect, true);
SkColor clearColor = (mFormat == SurfaceFormat::B8G8R8X8) ? SK_ColorBLACK : SK_ColorTRANSPARENT;
mCanvas->clear(clearColor);
mCanvas->restore();
@ -2056,7 +1972,7 @@ DrawTargetSkia::PushClip(const Path *aPath)
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
mCanvas->save();
mCanvas->clipPath(skiaPath->GetPath(), kIntersect_SkClipOp, true);
mCanvas->clipPath(skiaPath->GetPath(), SkClipOp::kIntersect, true);
}
void
@ -2072,7 +1988,7 @@ DrawTargetSkia::PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount)
// this region by the current transform, unlike the other SkCanvas
// clip methods, so it is just passed through in device-space.
mCanvas->save();
mCanvas->clipRegion(region, kIntersect_SkClipOp);
mCanvas->clipRegion(region, SkClipOp::kIntersect);
}
void
@ -2081,7 +1997,7 @@ DrawTargetSkia::PushClipRect(const Rect& aRect)
SkRect rect = RectToSkRect(aRect);
mCanvas->save();
mCanvas->clipRect(rect, kIntersect_SkClipOp, true);
mCanvas->clipRect(rect, SkClipOp::kIntersect, true);
}
void
@ -2090,40 +2006,6 @@ DrawTargetSkia::PopClip()
mCanvas->restore();
}
// Image filter that just passes the source through to the result unmodified.
class CopyLayerImageFilter : public SkImageFilter
{
public:
CopyLayerImageFilter()
: SkImageFilter(nullptr, 0, nullptr)
{}
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const override {
offset->set(0, 0);
return sk_ref_sp(source);
}
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(CopyLayerImageFilter)
};
sk_sp<SkFlattenable>
CopyLayerImageFilter::CreateProc(SkReadBuffer& buffer)
{
SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
return sk_make_sp<CopyLayerImageFilter>();
}
#ifndef SK_IGNORE_TO_STRING
void
CopyLayerImageFilter::toString(SkString* str) const
{
str->append("CopyLayerImageFilter: ()");
}
#endif
void
DrawTargetSkia::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
const Matrix& aMaskTransform, const IntRect& aBounds,
@ -2150,13 +2032,11 @@ DrawTargetSkia::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
}
}
sk_sp<SkImageFilter> backdrop(aCopyBackground ? new CopyLayerImageFilter : nullptr);
SkCanvas::SaveLayerRec saveRec(aBounds.IsEmpty() ? nullptr : &bounds,
&paint,
backdrop.get(),
SkCanvas::kPreserveLCDText_SaveLayerFlag |
(aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0));
(aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0) |
(aCopyBackground ? SkCanvas::kInitWithPrevious_SaveLayerFlag : 0));
mCanvas->saveLayer(saveRec);
@ -2190,10 +2070,10 @@ DrawTargetSkia::PopLayer()
if (layerDevice->peekPixels(&layerPixmap)) {
layerImage = SkImage::MakeFromRaster(layerPixmap, nullptr, nullptr);
#ifdef USE_SKIA_GPU
} else if (GrDrawContext* drawCtx = mCanvas->internal_private_accessTopLayerDrawContext()) {
} else if (GrRenderTargetContext* drawCtx = mCanvas->internal_private_accessTopLayerRenderTargetContext()) {
drawCtx->prepareForExternalIO();
if (GrTexture* tex = drawCtx->accessRenderTarget()->asTexture()) {
layerImage = sk_make_sp<SkImage_Gpu>(layerBounds.width(), layerBounds.height(),
if (sk_sp<GrTextureProxy> tex = drawCtx->asTextureProxyRef()) {
layerImage = sk_make_sp<SkImage_Gpu>(mGrContext.get(),
kNeedNewImageUniqueID,
layerDevice->imageInfo().alphaType(),
tex, nullptr, SkBudgeted::kNo);

Просмотреть файл

@ -205,7 +205,7 @@ private:
IntSize mSize;
sk_sp<SkSurface> mSurface;
sk_sp<SkCanvas> mCanvas;
SkCanvas* mCanvas;
SourceSurfaceSkia* mSnapshot;
#ifdef MOZ_WIDGET_COCOA
@ -223,6 +223,7 @@ private:
CGColorSpaceRef mColorSpace;
uint8_t* mCanvasData;
IntSize mCGSize;
bool mNeedLayer;
#endif
};

Просмотреть файл

@ -594,6 +594,7 @@ GLContext::InitWithPrefixImpl(const char* prefix, bool trygl)
{ (PRFuncPtr*) &mSymbols.fLoadIdentity, { "LoadIdentity", nullptr } },
{ (PRFuncPtr*) &mSymbols.fLoadMatrixf, { "LoadMatrixf", nullptr } },
{ (PRFuncPtr*) &mSymbols.fMatrixMode, { "MatrixMode", nullptr } },
{ (PRFuncPtr*) &mSymbols.fPolygonMode, { "PolygonMode", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexGeni, { "TexGeni", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexGenf, { "TexGenf", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexGenfv, { "TexGenfv", nullptr } },

Просмотреть файл

@ -1459,6 +1459,12 @@ public:
AFTER_GL_CALL;
}
void fPolygonMode(GLenum face, GLenum mode) {
BEFORE_GL_CALL;
mSymbols.fPolygonMode(face, mode);
AFTER_GL_CALL;
}
void fPolygonOffset(GLfloat factor, GLfloat bias) {
BEFORE_GL_CALL;
mSymbols.fPolygonOffset(factor, bias);

Просмотреть файл

@ -203,6 +203,8 @@ struct GLContextSymbols
PFNGLPIXELSTOREIPROC fPixelStorei;
typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
PFNGLPOINTPARAMETERFPROC fPointParameterf;
typedef void (GLAPIENTRY * PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
PFNGLPOLYGONMODEPROC fPolygonMode;
typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat bias);
PFNGLPOLYGONOFFSETPROC fPolygonOffset;
typedef void (GLAPIENTRY * PFNGLREADBUFFERPROC) (GLenum);

Просмотреть файл

@ -221,6 +221,7 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
i->fFunctions.fLineWidth = WrapGL(context, &GLContext::fLineWidth);
i->fFunctions.fLinkProgram = WrapGL(context, &GLContext::fLinkProgram);
i->fFunctions.fPixelStorei = WrapGL(context, &GLContext::fPixelStorei);
i->fFunctions.fPolygonMode = WrapGL(context, &GLContext::fPolygonMode);
i->fFunctions.fReadPixels = WrapGL(context, &GLContext::fReadPixels);
i->fFunctions.fRenderbufferStorage = WrapGL(context, &GLContext::fRenderbufferStorage);
i->fFunctions.fScissor = WrapGL(context, &GLContext::fScissor);

Просмотреть файл

@ -11,7 +11,7 @@ fuzzy-if(Android,3,7) skip-if(!Android) pref(apz.allow_zooming,true) fails-if(st
# compositor, the border-radius ends of the scrollthumb are going to be a little
# off, hence the fuzzy-if clauses.
fuzzy-if(Android,54,18) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-zoom-1.html async-scrollbar-zoom-1-ref.html
fuzzy-if(Android,45,21) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-zoom-2.html async-scrollbar-zoom-2-ref.html
fuzzy-if(Android,45,22) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-zoom-2.html async-scrollbar-zoom-2-ref.html
# Meta-viewport tag support
skip-if(!Android) pref(apz.allow_zooming,true) == initial-scale-1.html initial-scale-1-ref.html

Просмотреть файл

@ -29,9 +29,9 @@ PaintCounter::PaintCounter()
mSurface = Factory::CreateDataSourceSurface(mRect.Size(), mFormat);
mStride = mSurface->Stride();
mCanvas.reset(
SkCanvas::NewRasterDirect(MakeSkiaImageInfo(mRect.Size(), mFormat),
mSurface->GetData(), mStride));
mCanvas =
SkCanvas::MakeRasterDirect(MakeSkiaImageInfo(mRect.Size(), mFormat),
mSurface->GetData(), mStride);
mCanvas->clear(SK_ColorWHITE);
}

Просмотреть файл

@ -33,7 +33,7 @@ private:
virtual ~PaintCounter();
SurfaceFormat mFormat;
sk_sp<SkCanvas> mCanvas;
std::unique_ptr<SkCanvas> mCanvas;
IntSize mSize;
int mStride;

Просмотреть файл

@ -2,9 +2,9 @@ This is an import of Skia. See skia/include/core/SkMilestone.h for the milestone
To update to a new version of Skia:
- Clone Skia from upstream using the instructions here: https://sites.google.com/site/skiadocs/user-documentation/downloading
- Clone Skia from upstream using the instructions here: https://skia.org/user/download
- Copy the entire source tree from a Skia clone to mozilla-central/gfx/skia/skia
- cd gfx/skia && ./gyp_mozbuild
- cd gfx/skia && ./generate_mozbuild.py
Once that's done, use git status to view the files that have changed. Keep an eye on GrUserConfig.h
and SkUserConfig.h as those probably don't want to be overwritten by upstream versions.

Просмотреть файл

@ -1,92 +0,0 @@
# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import collections
import os
import gyp
import gyp.common
import gyp.msvs_emulation
import json
import sys
generator_supports_multiple_toolsets = True
generator_wants_static_library_dependencies_adjusted = False
generator_default_variables = {
}
for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
'LIB_DIR', 'SHARED_LIB_DIR']:
# Some gyp steps fail if these are empty(!).
generator_default_variables[dirname] = 'dir'
for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
'CONFIGURATION_NAME']:
generator_default_variables[unused] = ''
def CalculateVariables(default_variables, params):
generator_flags = params.get('generator_flags', {})
for key, val in generator_flags.items():
default_variables.setdefault(key, val)
default_variables.setdefault('OS', gyp.common.GetFlavor(params))
flavor = gyp.common.GetFlavor(params)
if flavor =='win':
# Copy additional generator configuration data from VS, which is shared
# by the Windows Ninja generator.
import gyp.generator.msvs as msvs_generator
generator_additional_non_configuration_keys = getattr(msvs_generator,
'generator_additional_non_configuration_keys', [])
generator_additional_path_sections = getattr(msvs_generator,
'generator_additional_path_sections', [])
gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
def CalculateGeneratorInputInfo(params):
"""Calculate the generator specific info that gets fed to input (called by
gyp)."""
generator_flags = params.get('generator_flags', {})
if generator_flags.get('adjust_static_libraries', False):
global generator_wants_static_library_dependencies_adjusted
generator_wants_static_library_dependencies_adjusted = True
def GetOS(params):
for d in params['defines']:
pass
def GenerateOutput(target_list, target_dicts, data, params):
# Map of target -> list of targets it depends on.
edges = {}
# Queue of targets to visit.
targets_to_visit = target_list[:]
sources = [];
while len(targets_to_visit) > 0:
target = targets_to_visit.pop()
if target in edges:
continue
edges[target] = []
target_sources = target_dicts[target].get('sources')
if target_sources:
for source in target_sources:
if source.endswith('.cpp'):
sources.append(source)
for dep in target_dicts[target].get('dependencies', []):
edges[target].append(dep)
targets_to_visit.append(dep)
skia_os = data['gyp/core.gyp']['variables']['skia_os%']
f = open('sources.json', 'w')
json.dump(sources, f)
f.close()

Просмотреть файл

@ -1,8 +1,7 @@
#!/usr/bin/env python
import os
import locale
import subprocess
from collections import defaultdict
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
@ -44,7 +43,6 @@ LOCAL_INCLUDES += [
'skia/include/core',
'skia/include/effects',
'skia/include/gpu',
'skia/include/images',
'skia/include/pathops',
'skia/include/ports',
'skia/include/private',
@ -55,27 +53,17 @@ LOCAL_INCLUDES += [
'skia/src/gpu',
'skia/src/gpu/effects',
'skia/src/gpu/gl',
'skia/src/gpu/glsl',
'skia/src/image',
'skia/src/lazy',
'skia/src/opts',
'skia/src/sfnt',
'skia/src/sksl',
'skia/src/utils',
'skia/src/utils/mac',
'skia/src/utils/win',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
DEFINES['SK_FONTHOST_CAIRO_STANDALONE'] = 0
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
'android',
'cocoa',
'gtk2',
'gtk3',
'uikit',
}:
DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DEFINES['UNICODE'] = True
DEFINES['_UNICODE'] = True
@ -86,19 +74,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
# We should autogenerate these SSE related flags.
if CONFIG['_MSC_VER']:
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=42']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=51']
if CONFIG['INTEL_ARCHITECTURE'] and (CONFIG['GNU_CC'] or CONFIG['CLANG_CL']):
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
@ -106,8 +82,20 @@ if CONFIG['INTEL_ARCHITECTURE'] and (CONFIG['GNU_CC'] or CONFIG['CLANG_CL']):
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-msse4.2']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['BUILD_ARM_NEON']:
DEFINES['SK_ARM_HAS_OPTIONAL_NEON'] = 1
SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += ['-mavx2']
elif CONFIG['_MSC_VER']:
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=42']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=51']
SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=52']
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
CXXFLAGS += CONFIG['NEON_FLAGS']
DEFINES['SKIA_IMPLEMENTATION'] = 1
@ -158,12 +146,22 @@ import json
platforms = ['linux', 'mac', 'android', 'win']
def parse_sources(output):
return set(v.replace('//', 'skia/') for v in output.split() if v.endswith('.cpp') or v.endswith('.S'))
def generate_opt_sources():
opt_sources = {'opts': {''}}
for root, dirs, files in os.walk('skia/src/opts'):
for name in files:
if name.endswith('.cpp'):
opt_sources['opts'].add(os.path.join(root, name))
cpus = [('intel', 'x86', [':sse2', ':ssse3', ':sse41', ':sse42', ':avx', ':hsw']),
('arm', 'arm', [':armv7']),
('none', 'none', [':none'])]
opt_sources = {}
for key, cpu, deps in cpus:
subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_cpu="{1}"\''.format(key, cpu), shell=True)
opt_sources[key] = set()
for dep in deps:
output = subprocess.check_output('cd skia && bin/gn desc out/{0} {1} sources'.format(key, dep), shell=True)
if output:
opt_sources[key].update(parse_sources(output))
return opt_sources
@ -171,33 +169,25 @@ def generate_platform_sources():
sources = {}
for plat in platforms:
if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s -D host_os=linux gyp/skia_lib.gyp" % plat) != 0:
print 'Failed to generate sources for ' + plat
continue
output = subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_os="{0}"\' > /dev/null && bin/gn desc out/{0} :skia sources'.format(plat), shell=True)
if output:
sources[plat] = parse_sources(output)
f = open('skia/sources.json');
sources[plat] = set(v.replace('../', 'skia/') for v in json.load(f));
f.close()
deps = {':effects' : 'common', ':gpu' : 'gpu', ':pdf' : 'pdf'}
for dep, key in deps.items():
output = subprocess.check_output('cd skia && bin/gn desc out/linux {} sources'.format(dep), shell=True)
if output:
sources[key] = parse_sources(output)
return dict(sources.items() + generate_opt_sources().items())
def generate_separated_sources(platform_sources):
blacklist = [
'experimental',
'SkXML',
'GrGLCreateNativeInterface',
'GrGLCreateNullInterface',
'GrGLAssembleInterface',
'GrGLTestInterface',
'fontconfig',
'FontConfig',
'SkThreadUtils_pthread_',
'SkFontMgr_android',
'SkFontMgr_custom',
'SkFontHost_FreeType.cpp',
'Movie',
'ImageEncoder',
'skia/src/c/',
'skia/src/effects/Gr',
@ -205,7 +195,6 @@ def generate_separated_sources(platform_sources):
'skia/src/fonts/',
'skia/src/images/',
'skia/src/ports/SkImageGenerator',
'skia/src/sksl/',
'skia/src/gpu/vk/',
'SkBitmapRegion',
'SkLight',
@ -216,11 +205,7 @@ def generate_separated_sources(platform_sources):
'codec',
'SkWGL',
'SkMemory_malloc',
'SkOpts_',
'opts_check_x86',
'third_party',
# unused in skia/src/utils
'SkBoundaryPatch',
'SkCamera',
'SkCanvasStack',
'SkCanvasStateUtils',
@ -229,19 +214,17 @@ def generate_separated_sources(platform_sources):
'SkDumpCanvas',
'SkFrontBufferedStream',
'SkInterpolator',
'SkLayer',
'SkMeshUtils',
'SkMD5',
'SkMultiPictureDocument',
'SkNinePatch',
'SkNullCanvas',
'SkNWayCanvas',
'SkOverdrawCanvas',
'SkPaintFilterCanvas',
'SkParseColor',
'SkPatchGrid',
'SkRTConf',
'SkTextBox',
'SkWhitelistTypefaces',
'SkXPS',
'SkCreateCGImageRef',
]
def isblacklisted(value):
@ -268,30 +251,20 @@ def generate_separated_sources(platform_sources):
# 'skia/src/ports/SkDebug_android.cpp',
'skia/src/ports/SkFontHost_cairo.cpp',
# 'skia/src/ports/SkFontHost_FreeType.cpp',
# 'skia/src/ports/SkFontHost_FreeType_common.cpp',
'skia/src/ports/SkFontHost_FreeType_common.cpp',
# 'skia/src/ports/SkTime_Unix.cpp',
# 'skia/src/utils/SkThreadUtils_pthread.cpp',
},
'linux': {
'skia/src/ports/SkFontHost_cairo.cpp',
'skia/src/ports/SkFontHost_FreeType_common.cpp',
},
'intel': {
# There is currently no x86-specific opt for SkTextureCompression
'skia/src/opts/opts_check_x86.cpp',
'skia/src/opts/SkOpts_ssse3.cpp',
'skia/src/opts/SkOpts_sse41.cpp',
'skia/src/opts/SkOpts_sse42.cpp',
'skia/src/opts/SkOpts_avx.cpp',
'skia/src/opts/SkOpts_hsw.cpp',
},
'arm': {
'skia/src/core/SkUtilsArm.cpp',
},
'neon': {
'skia/src/opts/SkOpts_neon.cpp',
},
'intel': set(),
'arm': set(),
'none': set(),
'pdf': set(),
'pdf': {
'skia/src/core/SkMD5.cpp',
},
'gpu': set()
})
@ -305,30 +278,12 @@ def generate_separated_sources(platform_sources):
key = plat
if '_SSE' in value or '_SSSE' in value:
key = 'intel'
elif '_neon' in value:
key = 'neon'
elif '_arm' in value:
key = 'arm'
elif '_none' in value:
key = 'none'
elif 'gpu' in value or 'Gpu' in value:
key = 'gpu'
elif all(value in platform_sources.get(p, {})
for p in platforms if p != plat):
if all(value in platform_sources.get(p, {})
for p in platforms if p != plat):
key = 'common'
separated[key].add(value)
if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=linux -D host_os=linux -R pdf gyp/pdf.gyp") != 0:
print 'Failed to generate sources for Skia PDF'
else:
f = open('skia/sources.json');
separated['pdf'].add('skia/src/core/SkMD5.cpp');
separated['pdf'].update(filter(lambda x: 'pdf' in x, set(v.replace('../', 'skia/') for v in json.load(f))));
f.close()
return separated
def uniq(seq):
@ -383,16 +338,18 @@ unified_blacklist = [
'SkBlitter_RGB16.cpp',
'SkBlitter_Sprite.cpp',
'SkScan_Antihair.cpp',
'SkScan_AntiPath.cpp',
'SkParse.cpp',
'SkPDFFont.cpp',
'SkPictureData.cpp',
'GrDrawContext',
'GrResourceCache',
'GrResourceProvider',
'GrAA',
'GrGL',
'GrBatchAtlas.cpp',
'GrMSAAPathRenderer.cpp',
'GrNonAAFillRect',
'GrPathUtils',
'GrShadowRRectOp',
'SkColorSpace',
'SkImage_Gpu.cpp',
'SkPathOpsDebug.cpp',
@ -401,6 +358,10 @@ unified_blacklist = [
'SkMiniRecorder.cpp',
'SkXfermode',
'SkMatrix44.cpp',
'SkRTree.cpp',
'SkVertices.cpp',
'SkJumper',
'lex.layout.cpp',
] + opt_whitelist
def write_sources(f, values, indent):
@ -458,13 +419,13 @@ def write_mozbuild(sources):
f.write("if CONFIG['MOZ_ENABLE_SKIA_GPU']:\n")
write_sources(f, sources['gpu'], 4)
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):\n")
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':\n")
write_sources(f, sources['android'], 4)
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:\n")
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):\n")
write_sources(f, sources['mac'], 4)
f.write("if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:\n")
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):\n")
write_sources(f, sources['linux'], 4)
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n")
@ -479,15 +440,6 @@ def write_mozbuild(sources):
f.write("elif CONFIG['CPU_ARCH'] in ('arm', 'aarch64') and CONFIG['GNU_CC']:\n")
write_sources(f, sources['arm'], 4)
write_cflags(f, sources['arm'], opt_whitelist, 'skia_opt_flags', 4)
f.write(" if CONFIG['CPU_ARCH'] == 'aarch64':\n")
write_sources(f, sources['neon'], 8)
f.write(" elif CONFIG['BUILD_ARM_NEON']:\n")
write_list(f, 'SOURCES', sources['neon'], 8)
write_cflags(f, sources['neon'], 'neon', "CONFIG['NEON_FLAGS']", 8)
f.write(" if CONFIG['CPU_ARCH'] == 'aarch64' or CONFIG['BUILD_ARM_NEON']:\n")
write_cflags(f, sources['neon'], opt_whitelist, 'skia_opt_flags', 8)
f.write("else:\n")
write_sources(f, sources['none'], 4)

Просмотреть файл

@ -1,13 +0,0 @@
#!/bin/bash
# Install our generator
cp dump_mozbuild.py skia/third_party/externals/gyp/pylib/gyp/generator
# pushd skia
# for OS in win linux mac; do
# GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=$OS -D arm_neon=0 gyp/effects.gyp
# done
# popd
./generate_mozbuild.py

Просмотреть файл

@ -25,7 +25,10 @@ if CONFIG['MOZ_OPTIMIZE']:
UNIFIED_SOURCES += [
'skia/src/core/SkAAClip.cpp',
'skia/src/core/SkAlphaRuns.cpp',
'skia/src/core/SkAnalyticEdge.cpp',
'skia/src/core/SkAnnotation.cpp',
'skia/src/core/SkArenaAlloc.cpp',
'skia/src/core/SkATrace.cpp',
'skia/src/core/SkAutoPixmapStorage.cpp',
'skia/src/core/SkBBHFactory.cpp',
'skia/src/core/SkBigPicture.cpp',
@ -40,16 +43,17 @@ UNIFIED_SOURCES += [
'skia/src/core/SkBuffer.cpp',
'skia/src/core/SkCachedData.cpp',
'skia/src/core/SkCanvas.cpp',
'skia/src/core/SkChunkAlloc.cpp',
'skia/src/core/SkClipStack.cpp',
'skia/src/core/SkClipStackDevice.cpp',
'skia/src/core/SkColor.cpp',
'skia/src/core/SkColorFilter.cpp',
'skia/src/core/SkColorFilterShader.cpp',
'skia/src/core/SkColorLookUpTable.cpp',
'skia/src/core/SkColorMatrixFilterRowMajor255.cpp',
'skia/src/core/SkColorShader.cpp',
'skia/src/core/SkColorTable.cpp',
'skia/src/core/SkComposeShader.cpp',
'skia/src/core/SkConfig8888.cpp',
'skia/src/core/SkConvertPixels.cpp',
'skia/src/core/SkConvolver.cpp',
'skia/src/core/SkCpu.cpp',
'skia/src/core/SkCubicClipper.cpp',
@ -69,7 +73,7 @@ UNIFIED_SOURCES += [
'skia/src/core/SkEdge.cpp',
'skia/src/core/SkEdgeBuilder.cpp',
'skia/src/core/SkEdgeClipper.cpp',
'skia/src/core/SkError.cpp',
'skia/src/core/SkExecutor.cpp',
'skia/src/core/SkFilterProc.cpp',
'skia/src/core/SkFlattenable.cpp',
'skia/src/core/SkFlattenableSerialization.cpp',
@ -79,13 +83,13 @@ UNIFIED_SOURCES += [
'skia/src/core/SkFontMgr.cpp',
'skia/src/core/SkFontStream.cpp',
'skia/src/core/SkFontStyle.cpp',
'skia/src/core/SkForceCPlusPlusLinking.cpp',
'skia/src/core/SkGeometry.cpp',
'skia/src/core/SkGlobalInitialization_core.cpp',
'skia/src/core/SkGlyphCache.cpp',
'skia/src/core/SkGpuBlurUtils.cpp',
'skia/src/core/SkGraphics.cpp',
'skia/src/core/SkHalf.cpp',
'skia/src/core/SkICC.cpp',
'skia/src/core/SkImageCacherator.cpp',
'skia/src/core/SkImageFilter.cpp',
'skia/src/core/SkImageFilterCache.cpp',
@ -144,12 +148,11 @@ UNIFIED_SOURCES += [
'skia/src/core/SkRegion_path.cpp',
'skia/src/core/SkResourceCache.cpp',
'skia/src/core/SkRRect.cpp',
'skia/src/core/SkRTree.cpp',
'skia/src/core/SkRWBuffer.cpp',
'skia/src/core/SkScalar.cpp',
'skia/src/core/SkScalerContext.cpp',
'skia/src/core/SkScan.cpp',
'skia/src/core/SkScan_AntiPath.cpp',
'skia/src/core/SkScan_AAAPath.cpp',
'skia/src/core/SkScan_Hairline.cpp',
'skia/src/core/SkScan_Path.cpp',
'skia/src/core/SkSemaphore.cpp',
@ -169,6 +172,7 @@ UNIFIED_SOURCES += [
'skia/src/core/SkSwizzle.cpp',
'skia/src/core/SkTaskGroup.cpp',
'skia/src/core/SkTextBlob.cpp',
'skia/src/core/SkThreadedBMPDevice.cpp',
'skia/src/core/SkThreadID.cpp',
'skia/src/core/SkTime.cpp',
'skia/src/core/SkTLS.cpp',
@ -192,6 +196,9 @@ UNIFIED_SOURCES += [
'skia/src/effects/gradients/SkRadialGradient.cpp',
'skia/src/effects/gradients/SkSweepGradient.cpp',
'skia/src/effects/gradients/SkTwoPointConicalGradient.cpp',
'skia/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp',
'skia/src/effects/shadows/SkAmbientShadowMaskFilter.cpp',
'skia/src/effects/shadows/SkSpotShadowMaskFilter.cpp',
'skia/src/effects/SkDashPathEffect.cpp',
'skia/src/effects/SkImageSource.cpp',
'skia/src/effects/SkLayerRasterizer.cpp',
@ -202,7 +209,6 @@ UNIFIED_SOURCES += [
'skia/src/image/SkSurface.cpp',
'skia/src/image/SkSurface_Raster.cpp',
'skia/src/lazy/SkDiscardableMemoryPool.cpp',
'skia/src/lazy/SkDiscardablePixelRef.cpp',
'skia/src/pathops/SkAddIntersections.cpp',
'skia/src/pathops/SkDConicLineIntersection.cpp',
'skia/src/pathops/SkDCubicLineIntersection.cpp',
@ -244,18 +250,23 @@ UNIFIED_SOURCES += [
'skia/src/ports/SkOSFile_stdio.cpp',
'skia/src/sfnt/SkOTTable_name.cpp',
'skia/src/sfnt/SkOTUtils.cpp',
'skia/src/utils/mac/SkStream_mac.cpp',
'skia/src/utils/SkBase64.cpp',
'skia/src/utils/SkBitmapSourceDeserializer.cpp',
'skia/src/utils/SkDashPath.cpp',
'skia/src/utils/SkEventTracer.cpp',
'skia/src/utils/SkInsetConvexPolygon.cpp',
'skia/src/utils/SkMatrix22.cpp',
'skia/src/utils/SkOSFile.cpp',
'skia/src/utils/SkOSPath.cpp',
'skia/src/utils/SkPatchUtils.cpp',
'skia/src/utils/SkRGBAToYUV.cpp',
'skia/src/utils/SkTextureCompressor.cpp',
'skia/src/utils/SkTextureCompressor_ASTC.cpp',
'skia/src/utils/SkTextureCompressor_LATC.cpp',
'skia/src/utils/SkTextureCompressor_R11EAC.cpp',
'skia/src/utils/SkThreadUtils_win.cpp',
'skia/src/utils/win/SkAutoCoInitialize.cpp',
'skia/src/utils/win/SkDWrite.cpp',
'skia/src/utils/win/SkDWriteFontFileStream.cpp',
'skia/src/utils/win/SkDWriteGeometrySink.cpp',
'skia/src/utils/win/SkHRESULT.cpp',
'skia/src/utils/win/SkIStream.cpp',
]
SOURCES += [
'skia/src/core/SkBitmapProcState.cpp',
@ -270,23 +281,33 @@ SOURCES += [
'skia/src/core/SkBlitter_RGB16.cpp',
'skia/src/core/SkBlitter_Sprite.cpp',
'skia/src/core/SkColorSpace.cpp',
'skia/src/core/SkColorSpace_A2B.cpp',
'skia/src/core/SkColorSpace_ICC.cpp',
'skia/src/core/SkColorSpace_XYZ.cpp',
'skia/src/core/SkColorSpaceXform.cpp',
'skia/src/core/SkColorSpaceXform_A2B.cpp',
'skia/src/core/SkColorSpaceXformCanvas.cpp',
'skia/src/core/SkColorSpaceXformer.cpp',
'skia/src/core/SkMatrix.cpp',
'skia/src/core/SkMatrix44.cpp',
'skia/src/core/SkMiniRecorder.cpp',
'skia/src/core/SkOpts.cpp',
'skia/src/core/SkPictureData.cpp',
'skia/src/core/SkRecorder.cpp',
'skia/src/core/SkRTree.cpp',
'skia/src/core/SkScan_Antihair.cpp',
'skia/src/core/SkScan_AntiPath.cpp',
'skia/src/core/SkSpriteBlitter4f.cpp',
'skia/src/core/SkSpriteBlitter_ARGB32.cpp',
'skia/src/core/SkSpriteBlitter_RGB16.cpp',
'skia/src/core/SkVertices.cpp',
'skia/src/core/SkXfermode.cpp',
'skia/src/core/SkXfermode4f.cpp',
'skia/src/core/SkXfermodeF16.cpp',
'skia/src/core/SkXfermodeInterpretation.cpp',
'skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
'skia/src/jumper/SkJumper.cpp',
'skia/src/jumper/SkJumper_stages.cpp',
'skia/src/pathops/SkPathOpsDebug.cpp',
'skia/src/utils/SkParse.cpp',
'skia/src/utils/SkParsePath.cpp',
@ -333,52 +354,34 @@ if CONFIG['MOZ_ENABLE_SKIA_PDF']:
]
if CONFIG['MOZ_ENABLE_SKIA_GPU']:
UNIFIED_SOURCES += [
'skia/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp',
'skia/src/gpu/batches/GrAnalyticRectBatch.cpp',
'skia/src/gpu/batches/GrAtlasTextBatch.cpp',
'skia/src/gpu/batches/GrBatch.cpp',
'skia/src/gpu/batches/GrCopySurfaceBatch.cpp',
'skia/src/gpu/batches/GrDashLinePathRenderer.cpp',
'skia/src/gpu/batches/GrDefaultPathRenderer.cpp',
'skia/src/gpu/batches/GrDrawAtlasBatch.cpp',
'skia/src/gpu/batches/GrDrawBatch.cpp',
'skia/src/gpu/batches/GrDrawPathBatch.cpp',
'skia/src/gpu/batches/GrDrawVerticesBatch.cpp',
'skia/src/gpu/batches/GrNinePatch.cpp',
'skia/src/gpu/batches/GrNonAAStrokeRectBatch.cpp',
'skia/src/gpu/batches/GrPLSPathRenderer.cpp',
'skia/src/gpu/batches/GrRectBatchFactory.cpp',
'skia/src/gpu/batches/GrRegionBatch.cpp',
'skia/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp',
'skia/src/gpu/batches/GrTessellatingPathRenderer.cpp',
'skia/src/gpu/batches/GrVertexBatch.cpp',
'skia/src/gpu/effects/GrBezierEffect.cpp',
'skia/src/gpu/effects/GrBicubicEffect.cpp',
'skia/src/gpu/effects/GrBitmapTextGeoProc.cpp',
'skia/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp',
'skia/src/gpu/effects/GrConfigConversionEffect.cpp',
'skia/src/gpu/effects/GrConstColorProcessor.cpp',
'skia/src/gpu/effects/GrConvexPolyEffect.cpp',
'skia/src/gpu/effects/GrConvolutionEffect.cpp',
'skia/src/gpu/effects/GrCoverageSetOpXP.cpp',
'skia/src/gpu/effects/GrCustomXfermode.cpp',
'skia/src/gpu/effects/GrDashingEffect.cpp',
'skia/src/gpu/effects/GrDisableColorXP.cpp',
'skia/src/gpu/effects/GrDistanceFieldGeoProc.cpp',
'skia/src/gpu/effects/GrDitherEffect.cpp',
'skia/src/gpu/effects/GrGammaEffect.cpp',
'skia/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp',
'skia/src/gpu/effects/GrMatrixConvolutionEffect.cpp',
'skia/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp',
'skia/src/gpu/effects/GrOvalEffect.cpp',
'skia/src/gpu/effects/GrPorterDuffXferProcessor.cpp',
'skia/src/gpu/effects/GrRRectEffect.cpp',
'skia/src/gpu/effects/GrShadowGeoProc.cpp',
'skia/src/gpu/effects/GrSimpleTextureEffect.cpp',
'skia/src/gpu/effects/GrSingleTextureEffect.cpp',
'skia/src/gpu/effects/GrSRGBEffect.cpp',
'skia/src/gpu/effects/GrTextureDomain.cpp',
'skia/src/gpu/effects/GrTextureStripAtlas.cpp',
'skia/src/gpu/effects/GrXfermodeFragmentProcessor.cpp',
'skia/src/gpu/effects/GrYUVEffect.cpp',
'skia/src/gpu/GrAuditTrail.cpp',
'skia/src/gpu/GrBatchFlushState.cpp',
'skia/src/gpu/GrBatchTest.cpp',
'skia/src/gpu/GrBitmapTextureMaker.cpp',
'skia/src/gpu/GrBlend.cpp',
'skia/src/gpu/GrBlurUtils.cpp',
'skia/src/gpu/GrBuffer.cpp',
@ -389,8 +392,10 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/GrContext.cpp',
'skia/src/gpu/GrCoordTransform.cpp',
'skia/src/gpu/GrDefaultGeoProcFactory.cpp',
'skia/src/gpu/GrDistanceFieldGenFromVector.cpp',
'skia/src/gpu/GrDrawingManager.cpp',
'skia/src/gpu/GrDrawTarget.cpp',
'skia/src/gpu/GrDrawOpAtlas.cpp',
'skia/src/gpu/GrDrawOpTest.cpp',
'skia/src/gpu/GrFixedClip.cpp',
'skia/src/gpu/GrFragmentProcessor.cpp',
'skia/src/gpu/GrGpu.cpp',
@ -398,10 +403,10 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/GrGpuFactory.cpp',
'skia/src/gpu/GrGpuResource.cpp',
'skia/src/gpu/GrGpuResourceRef.cpp',
'skia/src/gpu/GrImageIDTextureAdjuster.cpp',
'skia/src/gpu/GrInvariantOutput.cpp',
'skia/src/gpu/GrImageTextureMaker.cpp',
'skia/src/gpu/GrMemoryPool.cpp',
'skia/src/gpu/GrOvalRenderer.cpp',
'skia/src/gpu/GrOpFlushState.cpp',
'skia/src/gpu/GrOpList.cpp',
'skia/src/gpu/GrPaint.cpp',
'skia/src/gpu/GrPath.cpp',
'skia/src/gpu/GrPathProcessor.cpp',
@ -409,37 +414,43 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/GrPathRenderer.cpp',
'skia/src/gpu/GrPathRendererChain.cpp',
'skia/src/gpu/GrPathRendering.cpp',
'skia/src/gpu/GrPathRenderingDrawContext.cpp',
'skia/src/gpu/GrPathUtils.cpp',
'skia/src/gpu/GrPathRenderingRenderTargetContext.cpp',
'skia/src/gpu/GrPipeline.cpp',
'skia/src/gpu/GrPipelineBuilder.cpp',
'skia/src/gpu/GrPreFlushResourceProvider.cpp',
'skia/src/gpu/GrPrimitiveProcessor.cpp',
'skia/src/gpu/GrProcessor.cpp',
'skia/src/gpu/GrProcessorAnalysis.cpp',
'skia/src/gpu/GrProcessorSet.cpp',
'skia/src/gpu/GrProcessorUnitTest.cpp',
'skia/src/gpu/GrProcOptInfo.cpp',
'skia/src/gpu/GrProgramDesc.cpp',
'skia/src/gpu/GrProgramElement.cpp',
'skia/src/gpu/GrRectanizer_pow2.cpp',
'skia/src/gpu/GrRectanizer_skyline.cpp',
'skia/src/gpu/GrReducedClip.cpp',
'skia/src/gpu/GrRenderTarget.cpp',
'skia/src/gpu/GrRenderTargetContext.cpp',
'skia/src/gpu/GrRenderTargetOpList.cpp',
'skia/src/gpu/GrRenderTargetProxy.cpp',
'skia/src/gpu/GrResourceProvider.cpp',
'skia/src/gpu/GrShaderCaps.cpp',
'skia/src/gpu/GrShaderVar.cpp',
'skia/src/gpu/GrShape.cpp',
'skia/src/gpu/GrSoftwarePathRenderer.cpp',
'skia/src/gpu/GrStencilAttachment.cpp',
'skia/src/gpu/GrStencilSettings.cpp',
'skia/src/gpu/GrStyle.cpp',
'skia/src/gpu/GrSurface.cpp',
'skia/src/gpu/GrSurfaceContext.cpp',
'skia/src/gpu/GrSurfaceProxy.cpp',
'skia/src/gpu/GrSWMaskHelper.cpp',
'skia/src/gpu/GrTessellator.cpp',
'skia/src/gpu/GrTestUtils.cpp',
'skia/src/gpu/GrTexture.cpp',
'skia/src/gpu/GrTextureAccess.cpp',
'skia/src/gpu/GrTextureParamsAdjuster.cpp',
'skia/src/gpu/GrTextureProvider.cpp',
'skia/src/gpu/GrTextureAdjuster.cpp',
'skia/src/gpu/GrTextureContext.cpp',
'skia/src/gpu/GrTextureMaker.cpp',
'skia/src/gpu/GrTextureOpList.cpp',
'skia/src/gpu/GrTextureProducer.cpp',
'skia/src/gpu/GrTextureProxy.cpp',
'skia/src/gpu/GrTextureRenderTargetProxy.cpp',
'skia/src/gpu/GrTextureToYUVPlanes.cpp',
'skia/src/gpu/GrTraceMarker.cpp',
'skia/src/gpu/GrXferProcessor.cpp',
@ -447,30 +458,50 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/instanced/GLInstancedRendering.cpp',
'skia/src/gpu/instanced/InstancedRendering.cpp',
'skia/src/gpu/instanced/InstanceProcessor.cpp',
'skia/src/gpu/ops/GrAnalyticRectOp.cpp',
'skia/src/gpu/ops/GrAtlasTextOp.cpp',
'skia/src/gpu/ops/GrCopySurfaceOp.cpp',
'skia/src/gpu/ops/GrDashLinePathRenderer.cpp',
'skia/src/gpu/ops/GrDashOp.cpp',
'skia/src/gpu/ops/GrDefaultPathRenderer.cpp',
'skia/src/gpu/ops/GrDrawAtlasOp.cpp',
'skia/src/gpu/ops/GrDrawPathOp.cpp',
'skia/src/gpu/ops/GrDrawVerticesOp.cpp',
'skia/src/gpu/ops/GrLatticeOp.cpp',
'skia/src/gpu/ops/GrMeshDrawOp.cpp',
'skia/src/gpu/ops/GrNonAAStrokeRectOp.cpp',
'skia/src/gpu/ops/GrOp.cpp',
'skia/src/gpu/ops/GrOvalOpFactory.cpp',
'skia/src/gpu/ops/GrRectOpFactory.cpp',
'skia/src/gpu/ops/GrRegionOp.cpp',
'skia/src/gpu/ops/GrSemaphoreOp.cpp',
'skia/src/gpu/ops/GrSmallPathRenderer.cpp',
'skia/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp',
'skia/src/gpu/ops/GrTessellatingPathRenderer.cpp',
'skia/src/gpu/SkGpuDevice.cpp',
'skia/src/gpu/SkGpuDevice_drawTexture.cpp',
'skia/src/gpu/SkGr.cpp',
'skia/src/gpu/text/GrAtlasGlyphCache.cpp',
'skia/src/gpu/text/GrAtlasTextBlob.cpp',
'skia/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp',
'skia/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp',
'skia/src/gpu/text/GrAtlasTextContext.cpp',
'skia/src/gpu/text/GrBatchFontCache.cpp',
'skia/src/gpu/text/GrDistanceFieldAdjustTable.cpp',
'skia/src/gpu/text/GrStencilAndCoverTextContext.cpp',
'skia/src/gpu/text/GrTextBlobCache.cpp',
'skia/src/gpu/text/GrTextUtils.cpp',
'skia/src/image/SkSurface_Gpu.cpp',
'skia/src/sksl/ir/SkSLSymbolTable.cpp',
'skia/src/sksl/ir/SkSLType.cpp',
'skia/src/sksl/SkSLCFGGenerator.cpp',
'skia/src/sksl/SkSLCompiler.cpp',
'skia/src/sksl/SkSLGLSLCodeGenerator.cpp',
'skia/src/sksl/SkSLIRGenerator.cpp',
'skia/src/sksl/SkSLParser.cpp',
'skia/src/sksl/SkSLSPIRVCodeGenerator.cpp',
'skia/src/sksl/SkSLString.cpp',
'skia/src/sksl/SkSLUtil.cpp',
]
SOURCES += [
'skia/src/gpu/batches/GrAAConvexPathRenderer.cpp',
'skia/src/gpu/batches/GrAAConvexTessellator.cpp',
'skia/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp',
'skia/src/gpu/batches/GrAAFillRectBatch.cpp',
'skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp',
'skia/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp',
'skia/src/gpu/batches/GrAAStrokeRectBatch.cpp',
'skia/src/gpu/batches/GrMSAAPathRenderer.cpp',
'skia/src/gpu/batches/GrNonAAFillRectBatch.cpp',
'skia/src/gpu/batches/GrNonAAFillRectPerspectiveBatch.cpp',
'skia/src/gpu/gl/builders/GrGLProgramBuilder.cpp',
'skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp',
'skia/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp',
@ -479,6 +510,7 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/gl/GrGLContext.cpp',
'skia/src/gpu/gl/GrGLDefaultInterface_native.cpp',
'skia/src/gpu/gl/GrGLExtensions.cpp',
'skia/src/gpu/gl/GrGLExternalTextureData.cpp',
'skia/src/gpu/gl/GrGLGLSL.cpp',
'skia/src/gpu/gl/GrGLGpu.cpp',
'skia/src/gpu/gl/GrGLGpuProgramCache.cpp',
@ -498,7 +530,6 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/gl/GrGLVertexArray.cpp',
'skia/src/gpu/glsl/GrGLSL.cpp',
'skia/src/gpu/glsl/GrGLSLBlend.cpp',
'skia/src/gpu/glsl/GrGLSLCaps.cpp',
'skia/src/gpu/glsl/GrGLSLFragmentProcessor.cpp',
'skia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp',
'skia/src/gpu/glsl/GrGLSLGeometryProcessor.cpp',
@ -511,12 +542,23 @@ if CONFIG['MOZ_ENABLE_SKIA_GPU']:
'skia/src/gpu/glsl/GrGLSLVarying.cpp',
'skia/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp',
'skia/src/gpu/glsl/GrGLSLXferProcessor.cpp',
'skia/src/gpu/GrBatchAtlas.cpp',
'skia/src/gpu/GrDrawContext.cpp',
'skia/src/gpu/GrPathUtils.cpp',
'skia/src/gpu/GrResourceCache.cpp',
'skia/src/gpu/GrResourceProvider.cpp',
'skia/src/gpu/ops/GrAAConvexPathRenderer.cpp',
'skia/src/gpu/ops/GrAAConvexTessellator.cpp',
'skia/src/gpu/ops/GrAAFillRectOp.cpp',
'skia/src/gpu/ops/GrAAHairLinePathRenderer.cpp',
'skia/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp',
'skia/src/gpu/ops/GrAAStrokeRectOp.cpp',
'skia/src/gpu/ops/GrMSAAPathRenderer.cpp',
'skia/src/gpu/ops/GrNonAAFillRectOp.cpp',
'skia/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp',
'skia/src/gpu/ops/GrShadowRRectOp.cpp',
'skia/src/image/SkImage_Gpu.cpp',
'skia/src/sksl/lex.layout.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
UNIFIED_SOURCES += [
'skia/src/ports/SkDebug_android.cpp',
'skia/src/ports/SkOSFile_posix.cpp',
@ -525,23 +567,23 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
'skia/src/utils/SkThreadUtils_pthread.cpp',
]
SOURCES += [
'skia/src/jumper/SkJumper_generated.S',
'skia/src/ports/SkFontHost_cairo.cpp',
'skia/src/ports/SkFontHost_FreeType_common.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
UNIFIED_SOURCES += [
'skia/src/ports/SkDebug_stdio.cpp',
'skia/src/ports/SkOSFile_posix.cpp',
'skia/src/ports/SkOSLibrary_posix.cpp',
'skia/src/ports/SkTLS_pthread.cpp',
'skia/src/utils/mac/SkCreateCGImageRef.cpp',
'skia/src/utils/mac/SkStream_mac.cpp',
'skia/src/utils/SkThreadUtils_pthread.cpp',
]
SOURCES += [
'skia/src/jumper/SkJumper_generated.S',
'skia/src/ports/SkFontHost_mac.cpp',
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
UNIFIED_SOURCES += [
'skia/src/ports/SkDebug_stdio.cpp',
'skia/src/ports/SkOSFile_posix.cpp',
@ -550,35 +592,28 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
'skia/src/utils/SkThreadUtils_pthread.cpp',
]
SOURCES += [
'skia/src/jumper/SkJumper_generated.S',
'skia/src/ports/SkFontHost_cairo.cpp',
'skia/src/ports/SkFontHost_FreeType_common.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [
'skia/src/jumper/SkJumper_generated_win.S',
'skia/src/ports/SkDebug_win.cpp',
'skia/src/ports/SkFontHost_win.cpp',
'skia/src/ports/SkFontMgr_win_dw.cpp',
'skia/src/ports/SkFontMgr_win_dw_factory.cpp',
'skia/src/ports/SkOSFile_win.cpp',
'skia/src/ports/SkOSLibrary_win.cpp',
'skia/src/ports/SkRemotableFontMgr_win_dw.cpp',
'skia/src/ports/SkScalerContext_win_dw.cpp',
'skia/src/ports/SkTLS_win.cpp',
'skia/src/ports/SkTypeface_win_dw.cpp',
'skia/src/utils/SkThreadUtils_win.cpp',
'skia/src/utils/win/SkAutoCoInitialize.cpp',
'skia/src/utils/win/SkDWrite.cpp',
'skia/src/utils/win/SkDWriteFontFileStream.cpp',
'skia/src/utils/win/SkDWriteGeometrySink.cpp',
'skia/src/utils/win/SkHRESULT.cpp',
'skia/src/utils/win/SkIStream.cpp',
]
if CONFIG['INTEL_ARCHITECTURE']:
UNIFIED_SOURCES += [
'skia/src/opts/opts_check_x86.cpp',
]
SOURCES += [
'skia/src/opts/SkBitmapFilter_opts_SSE2.cpp',
'skia/src/opts/SkBitmapProcState_opts_SSE2.cpp',
'skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp',
'skia/src/opts/SkBlitRow_opts_SSE2.cpp',
@ -588,7 +623,6 @@ if CONFIG['INTEL_ARCHITECTURE']:
'skia/src/opts/SkOpts_sse42.cpp',
'skia/src/opts/SkOpts_ssse3.cpp',
]
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += skia_opt_flags
@ -598,44 +632,22 @@ if CONFIG['INTEL_ARCHITECTURE']:
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += skia_opt_flags
elif CONFIG['CPU_ARCH'] in ('arm', 'aarch64') and CONFIG['GNU_CC']:
UNIFIED_SOURCES += [
'skia/src/core/SkUtilsArm.cpp',
]
SOURCES += [
'skia/src/opts/SkBitmapProcState_opts_arm.cpp',
'skia/src/opts/SkBitmapProcState_arm_neon.cpp',
'skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp',
'skia/src/opts/SkBitmapProcState_opts_none.cpp',
'skia/src/opts/SkBlitMask_opts_arm.cpp',
'skia/src/opts/SkBlitMask_opts_arm_neon.cpp',
'skia/src/opts/SkBlitRow_opts_arm.cpp',
'skia/src/opts/SkBlitRow_opts_arm_neon.cpp',
]
SOURCES['skia/src/opts/SkBitmapProcState_opts_arm.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_arm_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_opts_none.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitMask_opts_arm.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitMask_opts_arm_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitRow_opts_arm.cpp'].flags += skia_opt_flags
if CONFIG['CPU_ARCH'] == 'aarch64':
SOURCES += [
'skia/src/opts/SkBitmapProcState_arm_neon.cpp',
'skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp',
'skia/src/opts/SkBlitMask_opts_arm_neon.cpp',
'skia/src/opts/SkBlitRow_opts_arm_neon.cpp',
'skia/src/opts/SkOpts_neon.cpp',
]
elif CONFIG['BUILD_ARM_NEON']:
SOURCES += [
'skia/src/opts/SkBitmapProcState_arm_neon.cpp',
'skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp',
'skia/src/opts/SkBlitMask_opts_arm_neon.cpp',
'skia/src/opts/SkBlitRow_opts_arm_neon.cpp',
'skia/src/opts/SkOpts_neon.cpp',
]
SOURCES['skia/src/opts/SkBitmapProcState_arm_neon.cpp'].flags += CONFIG['NEON_FLAGS']
SOURCES['skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp'].flags += CONFIG['NEON_FLAGS']
SOURCES['skia/src/opts/SkBlitMask_opts_arm_neon.cpp'].flags += CONFIG['NEON_FLAGS']
SOURCES['skia/src/opts/SkBlitRow_opts_arm_neon.cpp'].flags += CONFIG['NEON_FLAGS']
SOURCES['skia/src/opts/SkOpts_neon.cpp'].flags += CONFIG['NEON_FLAGS']
if CONFIG['CPU_ARCH'] == 'aarch64' or CONFIG['BUILD_ARM_NEON']:
SOURCES['skia/src/opts/SkBitmapProcState_arm_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBitmapProcState_matrixProcs_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitMask_opts_arm_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitRow_opts_arm_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkOpts_neon.cpp'].flags += skia_opt_flags
SOURCES['skia/src/opts/SkBlitRow_opts_arm_neon.cpp'].flags += skia_opt_flags
else:
SOURCES += [
'skia/src/opts/SkBitmapProcState_opts_none.cpp',
@ -654,7 +666,6 @@ LOCAL_INCLUDES += [
'skia/include/core',
'skia/include/effects',
'skia/include/gpu',
'skia/include/images',
'skia/include/pathops',
'skia/include/ports',
'skia/include/private',
@ -665,27 +676,17 @@ LOCAL_INCLUDES += [
'skia/src/gpu',
'skia/src/gpu/effects',
'skia/src/gpu/gl',
'skia/src/gpu/glsl',
'skia/src/image',
'skia/src/lazy',
'skia/src/opts',
'skia/src/sfnt',
'skia/src/sksl',
'skia/src/utils',
'skia/src/utils/mac',
'skia/src/utils/win',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
DEFINES['SK_FONTHOST_CAIRO_STANDALONE'] = 0
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
'android',
'cocoa',
'gtk2',
'gtk3',
'uikit',
}:
DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DEFINES['UNICODE'] = True
DEFINES['_UNICODE'] = True
@ -696,19 +697,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
# We should autogenerate these SSE related flags.
if CONFIG['_MSC_VER']:
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=42']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=51']
if CONFIG['INTEL_ARCHITECTURE'] and (CONFIG['GNU_CC'] or CONFIG['CLANG_CL']):
SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
@ -716,8 +705,20 @@ if CONFIG['INTEL_ARCHITECTURE'] and (CONFIG['GNU_CC'] or CONFIG['CLANG_CL']):
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-msse4.2']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx']
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['BUILD_ARM_NEON']:
DEFINES['SK_ARM_HAS_OPTIONAL_NEON'] = 1
SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += ['-mavx2']
elif CONFIG['_MSC_VER']:
# MSVC doesn't need special compiler flags, but Skia needs to be told that these files should
# be built with the required SSE level or it will simply compile in stubs and cause runtime crashes
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20']
SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31']
SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41']
SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=42']
SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=51']
SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=52']
elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
CXXFLAGS += CONFIG['NEON_FLAGS']
DEFINES['SKIA_IMPLEMENTATION'] = 1

Просмотреть файл

@ -10,7 +10,7 @@
#include "SkBitmap.h"
#include "SkBRDAllocator.h"
#include "SkEncodedFormat.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
/*
@ -55,18 +55,21 @@ public:
* if this color type is unsupported.
* @param requireUnpremul If the image is not opaque, we will use this to determine the
* alpha type to use.
* @param prefColorSpace If non-null and supported, this is the color space that we will
* decode into. Otherwise, we will choose a default.
*
*/
virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
const SkIRect& desiredSubset, int sampleSize,
SkColorType colorType, bool requireUnpremul) = 0;
SkColorType colorType, bool requireUnpremul,
sk_sp<SkColorSpace> prefColorSpace = nullptr) = 0;
/*
* @param Requested destination color type
* @return true if we support the requested color type and false otherwise
*/
virtual bool conversionSupported(SkColorType colorType) = 0;
virtual SkEncodedFormat getEncodedFormat() = 0;
virtual SkEncodedImageFormat getEncodedFormat() = 0;
int width() const { return fWidth; }
int height() const { return fHeight; }

Просмотреть файл

@ -1,501 +0,0 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAnimator_DEFINED
#define SkAnimator_DEFINED
#include "SkScalar.h"
#include "SkKey.h"
#include "SkEventSink.h"
class SkAnimateMaker;
class SkCanvas;
class SkDisplayable;
class SkEvent;
class SkExtras;
struct SkMemberInfo;
class SkPaint;
struct SkRect;
class SkStream;
class SkTypedArray;
class SkXMLParserError;
class SkDOM;
struct SkDOMNode;
/** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
This enum is incomplete and will be fleshed out in a future release */
enum SkElementType {
kElementDummyType
};
/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
This enum is incomplete and will be fleshed out in a future release */
enum SkFieldType {
kFieldDummyType
};
/** \class SkAnimator
The SkAnimator class decodes an XML stream into a display list. The
display list can be drawn statically as a picture, or can drawn
different elements at different times to form a moving animation.
SkAnimator does not read the system time on its own; it relies on the
caller to pass the current time. The caller can pause, speed up, or
reverse the animation by varying the time passed in.
The XML describing the display list must conform to the schema
described by SkAnimateSchema.xsd.
The XML must contain an <event> element to draw. Usually, it contains
an <event kind="onload" /> block to add some drawing elements to the
display list when the document is first decoded.
Here's an "Hello World" XML sample:
<screenplay>
<event kind="onload" >
<text text="Hello World" y="20" />
</event>
</screenplay>
To read and draw this sample:
// choose one of these two
SkAnimator animator; // declare an animator instance on the stack
// SkAnimator* animator = new SkAnimator() // or one could instantiate the class
// choose one of these three
animator.decodeMemory(buffer, size); // to read from RAM
animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
animator.decodeURI(filename); // to read from a web location, or from a local text file
// to draw to the current window:
SkCanvas canvas(getBitmap()); // create a canvas
animator.draw(canvas, &paint, 0); // draw the scene
*/
class SkAnimator : public SkEventSink {
public:
SkAnimator();
virtual ~SkAnimator();
/** Add a drawable extension to the graphics engine. Experimental.
@param extras A derived class that implements methods that identify and instantiate the class
*/
void addExtras(SkExtras* extras);
/** Read in XML from a stream, and append it to the current
animator. Returns false if an error was encountered.
Error diagnostics are stored in fErrorCode and fLineNumber.
@param stream The stream to append.
@return true if the XML was parsed successfully.
*/
bool appendStream(SkStream* stream);
/** Read in XML from memory. Returns true if the file can be
read without error. Returns false if an error was encountered.
Error diagnostics are stored in fErrorCode and fLineNumber.
@param buffer The XML text as UTF-8 characters.
@param size The XML text length in bytes.
@return true if the XML was parsed successfully.
*/
bool decodeMemory(const void* buffer, size_t size);
/** Read in XML from a stream. Returns true if the file can be
read without error. Returns false if an error was encountered.
Error diagnostics are stored in fErrorCode and fLineNumber.
@param stream The stream containg the XML text as UTF-8 characters.
@return true if the XML was parsed successfully.
*/
virtual bool decodeStream(SkStream* stream);
/** Parse the DOM tree starting at the specified node. Returns true if it can be
parsed without error. Returns false if an error was encountered.
Error diagnostics are stored in fErrorCode and fLineNumber.
@return true if the DOM was parsed successfully.
*/
virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
/** Read in XML from a URI. Returns true if the file can be
read without error. Returns false if an error was encountered.
Error diagnostics are stored in fErrorCode and fLineNumber.
@param uri The complete url path to be read (either ftp, http or https).
@return true if the XML was parsed successfully.
*/
bool decodeURI(const char uri[]);
/** Pass a char event, usually a keyboard symbol, to the animator.
This triggers events of the form <event kind="keyChar" key="... />
@param ch The character to match against <event> element "key"
attributes.
@return true if the event was dispatched successfully.
*/
bool doCharEvent(SkUnichar ch);
/** Experimental:
Pass a mouse click event along with the mouse coordinates to
the animator. This triggers events of the form <event kind="mouseDown" ... />
and other mouse events.
@param state The mouse state, described by SkView::Click::State : values are
down == 0, moved == 1, up == 2
@param x The x-position of the mouse
@param y The y-position of the mouse
@return true if the event was dispatched successfully.
*/
bool doClickEvent(int state, SkScalar x, SkScalar y);
/** Pass a meta-key event, such as an arrow , to the animator.
This triggers events of the form <event kind="keyPress" code="... />
@param code The key to match against <event> element "code"
attributes.
@return true if the event was dispatched successfully.
*/
bool doKeyEvent(SkKey code);
bool doKeyUpEvent(SkKey code);
/** Send an event to the animator. The animator's clock is set
relative to the current time.
@return true if the event was dispatched successfully.
*/
bool doUserEvent(const SkEvent& evt);
/** The possible results from the draw function.
*/
enum DifferenceType {
kNotDifferent,
kDifferent,
kPartiallyDifferent
};
/** Draws one frame of the animation. The first call to draw always
draws the initial frame of the animation. Subsequent calls draw
the offset into the animation by
subtracting the initial time from the current time.
@param canvas The canvas to draw into.
@param paint The paint to draw with.
@param time The offset into the current animation.
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
redraw area.
*/
DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
/** Draws one frame of the animation, using a new Paint each time.
The first call to draw always
draws the initial frame of the animation. Subsequent calls draw
the offset into the animation by
subtracting the initial time from the current time.
@param canvas The canvas to draw into.
@param time The offset into the current animation.
@return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
redraw area.
*/
DifferenceType draw(SkCanvas* canvas, SkMSec time);
/** Experimental:
Helper to choose whether to return a SkView::Click handler.
@param x ignored
@param y ignored
@return true if a mouseDown event handler is enabled.
*/
bool findClickEvent(SkScalar x, SkScalar y);
/** Get the nested animator associated with this element, if any.
Use this to access a movie's event sink, to send events to movies.
@param element the value returned by getElement
@return the internal animator.
*/
const SkAnimator* getAnimator(const SkDisplayable* element) const;
/** Returns the scalar value of the specified element's attribute[index]
@param element the value returned by getElement
@param field the value returned by getField
@param index the array entry
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
*/
int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
/** Returns the scalar value of the specified element's attribute[index]
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param index the array entry
@return the integer value to retrieve, or SK_NaN32 if unsuccessful
*/
int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
/** Returns the scalar value of the specified element's attribute[index]
@param element the value returned by getElement
@param field the value returned by getField
@param index the array entry
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
*/
SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
/** Returns the scalar value of the specified element's attribute[index]
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param index the array entry
@return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
*/
SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
/** Returns the string value of the specified element's attribute[index]
@param element is a value returned by getElement
@param field is a value returned by getField
@param index the array entry
@return the string value to retrieve, or null if unsuccessful
*/
const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
/** Returns the string value of the specified element's attribute[index]
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param index the array entry
@return the string value to retrieve, or null if unsuccessful
*/
const char* getArrayString(const char* elementID, const char* fieldName, int index);
/** Returns the XML element corresponding to the given ID.
@param elementID is the value of the id attribute in the XML of this element
@return the element matching the ID, or null if the element can't be found
*/
const SkDisplayable* getElement(const char* elementID);
/** Returns the element type corresponding to the XML element.
The element type matches the element name; for instance, <line> returns kElement_LineType
@param element is a value returned by getElement
@return element type, or 0 if the element can't be found
*/
SkElementType getElementType(const SkDisplayable* element);
/** Returns the element type corresponding to the given ID.
@param elementID is the value of the id attribute in the XML of this element
@return element type, or 0 if the element can't be found
*/
SkElementType getElementType(const char* elementID);
/** Returns the XML field of the named attribute in the XML element.
@param element is a value returned by getElement
@param fieldName is the attribute to return
@return the attribute matching the fieldName, or null if the element can't be found
*/
const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
/** Returns the XML field of the named attribute in the XML element matching the elementID.
@param elementID is the value of the id attribute in the XML of this element
@param fieldName is the attribute to return
@return the attribute matching the fieldName, or null if the element can't be found
*/
const SkMemberInfo* getField(const char* elementID, const char* fieldName);
/** Returns the value type coresponding to the element's attribute.
The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
@param field is a value returned by getField
@return the attribute type, or 0 if the element can't be found
*/
SkFieldType getFieldType(const SkMemberInfo* field);
/** Returns the value type coresponding to the element's attribute.
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@return the attribute type, or 0 if the element can't be found
*/
SkFieldType getFieldType(const char* elementID, const char* fieldName);
/** Returns the recommended animation interval. Returns zero if no
interval is specified.
*/
SkMSec getInterval();
/** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
kIsPartiallyDifferent to do a mimimal inval(). */
void getInvalBounds(SkRect* inval);
/** Returns the details of any error encountered while parsing the XML.
*/
const SkXMLParserError* getParserError();
/** Returns the details of any error encountered while parsing the XML as string.
*/
const char* getParserErrorString();
/** Returns the scalar value of the specified element's attribute
@param element is a value returned by getElement
@param field is a value returned by getField
@return the integer value to retrieve, or SK_NaN32 if not found
*/
int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
/** Returns the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@return the integer value to retrieve, or SK_NaN32 if not found
*/
int32_t getInt(const char* elementID, const char* fieldName);
/** Returns the scalar value of the specified element's attribute
@param element is a value returned by getElement
@param field is a value returned by getField
@return the scalar value to retrieve, or SK_ScalarNaN if not found
*/
SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
/** Returns the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@return the scalar value to retrieve, or SK_ScalarNaN if not found
*/
SkScalar getScalar(const char* elementID, const char* fieldName);
/** Returns the string value of the specified element's attribute
@param element is a value returned by getElement
@param field is a value returned by getField
@return the string value to retrieve, or null if not found
*/
const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
/** Returns the string value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@return the string value to retrieve, or null if not found
*/
const char* getString(const char* elementID, const char* fieldName);
/** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
const char* getURIBase();
/** Resets the animator to a newly created state with no animation data. */
void initialize();
/** Experimental. Resets any active animations so that the next time passed is treated as
time zero. */
void reset();
/** Sets the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param array is the c-style array of integers
@param count is the length of the array
@return true if the value was set successfully
*/
bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
/** Sets the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param array is the c-style array of strings
@param count is the length of the array
@return true if the value was set successfully
*/
bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
/** Sets the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param data the integer value to set
@return true if the value was set successfully
*/
bool setInt(const char* elementID, const char* fieldName, int32_t data);
/** Sets the scalar value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param data the scalar value to set
@return true if the value was set successfully
*/
bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
/** Sets the string value of the specified element's attribute
@param elementID is the value of the id attribute in the XML of this element
@param fieldName specifies the name of the attribute
@param data the string value to set
@return true if the value was set successfully
*/
bool setString(const char* elementID, const char* fieldName, const char* data);
/** Sets the file default directory of the URL base path
@param path the directory path
*/
void setURIBase(const char* path);
typedef void* Handler;
// This guy needs to be exported to java, so don't make it virtual
void setHostHandler(Handler handler) {
this->onSetHostHandler(handler);
}
/** \class Timeline
Returns current time to animator. To return a custom timeline, create a child
class and override the getMSecs method.
*/
class Timeline {
public:
virtual ~Timeline() {}
/** Returns the current time in milliseconds */
virtual SkMSec getMSecs() const = 0;
};
/** Sets a user class to return the current time to the animator.
Optional; if not called, the system clock will be used by calling
SkEvent::GetMSecsSinceStartup instead.
@param callBack the time function
*/
void setTimeline(const Timeline& );
static void Init(bool runUnitTests);
static void Term();
/** The event sink events generated by the animation are posted to.
Screenplay also posts an inval event to this event sink after processing an
event to force a redraw.
@param target the event sink id
*/
void setHostEventSinkID(SkEventSinkID hostID);
SkEventSinkID getHostEventSinkID() const;
// helper
void setHostEventSink(SkEventSink* sink) {
this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
}
virtual void setJavaOwner(Handler owner);
#ifdef SK_DEBUG
virtual void eventDone(const SkEvent& evt);
virtual bool isTrackingEvents();
static bool NoLeaks();
#endif
protected:
virtual void onSetHostHandler(Handler handler);
virtual void onEventPost(SkEvent*, SkEventSinkID);
virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
private:
// helper functions for setters
bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
virtual bool onEvent(const SkEvent&);
SkAnimateMaker* fMaker;
friend class SkAnimateMaker;
friend class SkAnimatorScript;
friend class SkAnimatorScript2;
friend class SkApply;
friend class SkDisplayMovie;
friend class SkDisplayType;
friend class SkPost;
friend class SkXMLAnimatorWriter;
};
#endif

Просмотреть файл

@ -1,39 +0,0 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAnimatorView_DEFINED
#define SkAnimatorView_DEFINED
#include "SkView.h"
#include "SkAnimator.h"
class SkAnimatorView : public SkView {
public:
SkAnimatorView();
virtual ~SkAnimatorView();
SkAnimator* getAnimator() const { return fAnimator; }
bool decodeFile(const char path[]);
bool decodeMemory(const void* buffer, size_t size);
bool decodeStream(SkStream* stream);
protected:
// overrides
virtual bool onEvent(const SkEvent&);
virtual void onDraw(SkCanvas*);
virtual void onInflate(const SkDOM&, const SkDOM::Node*);
private:
SkAnimator* fAnimator;
typedef SkView INHERITED;
};
#endif

Просмотреть файл

@ -19,7 +19,7 @@ SK_C_PLUS_PLUS_BEGIN_GUARD
Returns a new empty sk_data_t. This call must be balanced with a call to
sk_data_unref().
*/
SK_API sk_data_t* sk_data_new_empty();
SK_API sk_data_t* sk_data_new_empty(void);
/**
Returns a new sk_data_t by copying the specified source data.
This call must be balanced with a call to sk_data_unref().

Просмотреть файл

@ -28,7 +28,7 @@ SK_C_PLUS_PLUS_BEGIN_GUARD
maskfilter : NULL
xfermode_mode : SRCOVER_SK_XFERMODE_MODE
*/
SK_API sk_paint_t* sk_paint_new();
SK_API sk_paint_t* sk_paint_new(void);
/**
Release the memory storing the sk_paint_t and unref() all
associated objects.

Просмотреть файл

@ -21,7 +21,7 @@ typedef enum {
} sk_path_direction_t;
/** Create a new, empty path. */
SK_API sk_path_t* sk_path_new();
SK_API sk_path_t* sk_path_new(void);
/** Release the memory used by a sk_path_t. */
SK_API void sk_path_delete(sk_path_t*);

Просмотреть файл

@ -19,7 +19,7 @@ SK_C_PLUS_PLUS_BEGIN_GUARD
Create a new sk_picture_recorder_t. Its resources should be
released with a call to sk_picture_recorder_delete().
*/
sk_picture_recorder_t* sk_picture_recorder_new();
sk_picture_recorder_t* sk_picture_recorder_new(void);
/**
Release the memory and other resources used by this
sk_picture_recorder_t.

Просмотреть файл

@ -81,7 +81,7 @@ typedef enum {
/**
Return the default sk_colortype_t; this is operating-system dependent.
*/
SK_API sk_colortype_t sk_colortype_get_default_8888();
SK_API sk_colortype_t sk_colortype_get_default_8888(void);
typedef struct {
int32_t width;
@ -113,6 +113,59 @@ typedef struct {
float bottom;
} sk_rect_t;
/**
The sk_matrix_t struct holds a 3x3 perspective matrix for
transforming coordinates:
(X,Y) = T[M]((x,y))
X = (M[0] * x + M[1] * y + M[2]) / (M[6] * x + M[7] * y + M[8]);
Y = (M[3] * x + M[4] * y + M[5]) / (M[6] * x + M[7] * y + M[8]);
Therefore, the identity matrix is
sk_matrix_t identity = {{1, 0, 0,
0, 1, 0,
0, 0, 1}};
A matrix that scales by sx and sy is:
sk_matrix_t scale = {{sx, 0, 0,
0, sy, 0,
0, 0, 1}};
A matrix that translates by tx and ty is:
sk_matrix_t translate = {{1, 0, tx,
0, 1, ty,
0, 0, 1}};
A matrix that rotates around the origin by A radians:
sk_matrix_t rotate = {{cos(A), -sin(A), 0,
sin(A), cos(A), 0,
0, 0, 1}};
Two matrixes can be concatinated by:
void concat_matrices(sk_matrix_t* dst,
const sk_matrix_t* matrixU,
const sk_matrix_t* matrixV) {
const float* u = matrixU->mat;
const float* v = matrixV->mat;
sk_matrix_t result = {{
u[0] * v[0] + u[1] * v[3] + u[2] * v[6],
u[0] * v[1] + u[1] * v[4] + u[2] * v[7],
u[0] * v[2] + u[1] * v[5] + u[2] * v[8],
u[3] * v[0] + u[4] * v[3] + u[5] * v[6],
u[3] * v[1] + u[4] * v[4] + u[5] * v[7],
u[3] * v[2] + u[4] * v[5] + u[5] * v[8],
u[6] * v[0] + u[7] * v[3] + u[8] * v[6],
u[6] * v[1] + u[7] * v[4] + u[8] * v[7],
u[6] * v[2] + u[7] * v[5] + u[8] * v[8]
}};
*dst = result;
}
*/
typedef struct {
float mat[9];
} sk_matrix_t;

Просмотреть файл

@ -9,7 +9,7 @@
#define SkAndroidCodec_DEFINED
#include "SkCodec.h"
#include "SkEncodedFormat.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
#include "SkTypes.h"
@ -51,14 +51,18 @@ public:
/**
* Format of the encoded data.
*/
SkEncodedFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); }
SkEncodedImageFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); }
/**
* @param requestedColorType Color type requested by the client
*
* If it is possible to decode to requestedColorType, this returns
* requestedColorType. Otherwise, this returns whichever color type
* is suggested by the codec as the best match for the encoded data.
* |requestedColorType| may be overriden. We will default to kF16
* for high precision images and kIndex8 for GIF and WBMP.
*
* In the general case, if it is possible to decode to
* |requestedColorType|, this returns |requestedColorType|.
* Otherwise, this returns a color type that is an appropriate
* match for the the encoded data.
*/
SkColorType computeOutputColorType(SkColorType requestedColorType);
@ -71,6 +75,19 @@ public:
*/
SkAlphaType computeOutputAlphaType(bool requestedUnpremul);
/**
* @param outputColorType Color type that the client will decode to.
* @param prefColorSpace Preferred color space to decode to.
* This may not return |prefColorSpace| for a couple reasons.
* (1) Android Principles: 565 must be sRGB, F16 must be
* linear sRGB, transfer function must be parametric.
* (2) Codec Limitations: F16 requires a linear color space.
*
* Returns the appropriate color space to decode to.
*/
sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType,
sk_sp<SkColorSpace> prefColorSpace = nullptr);
/**
* Returns the dimensions of the scaled output image, for an input
* sampleSize.
@ -154,7 +171,7 @@ public:
*
* Must be within the bounds returned by getInfo().
*
* If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left
* If the EncodedFormat is SkEncodedImageFormat::kWEBP, the top and left
* values must be even.
*
* The default is NULL, meaning a decode of the entire image.
@ -260,6 +277,6 @@ private:
// embedded SkCodec.
const SkImageInfo& fInfo;
SkAutoTDelete<SkCodec> fCodec;
std::unique_ptr<SkCodec> fCodec;
};
#endif // SkAndroidCodec_DEFINED

Просмотреть файл

@ -10,7 +10,7 @@
#include "../private/SkTemplates.h"
#include "SkColor.h"
#include "SkEncodedFormat.h"
#include "SkEncodedImageFormat.h"
#include "SkEncodedInfo.h"
#include "SkImageInfo.h"
#include "SkSize.h"
@ -18,7 +18,10 @@
#include "SkTypes.h"
#include "SkYUVSizeInfo.h"
#include <vector>
class SkColorSpace;
class SkColorSpaceXform;
class SkData;
class SkPngChunkReader;
class SkSampler;
@ -32,7 +35,7 @@ class ColorCodecBench;
/**
* Abstraction layer directly on top of an image codec.
*/
class SkCodec : SkNoncopyable {
class SK_API SkCodec : SkNoncopyable {
public:
/**
* Minimum number of bytes that must be buffered in SkStream input.
@ -173,7 +176,7 @@ public:
/**
* Format of the encoded data.
*/
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
/**
* Used to describe the result of a call to getPixels().
@ -243,14 +246,17 @@ public:
struct Options {
Options()
: fZeroInitialized(kNo_ZeroInitialized)
, fSubset(NULL)
, fSubset(nullptr)
, fFrameIndex(0)
, fHasPriorFrame(false)
, fPremulBehavior(SkTransferFunctionBehavior::kRespect)
{}
ZeroInitialized fZeroInitialized;
ZeroInitialized fZeroInitialized;
/**
* If not NULL, represents a subset of the original image to decode.
* Must be within the bounds returned by getInfo().
* If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
* If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which
* currently supports subsets), the top and left values must be even.
*
* In getPixels and incremental decode, we will attempt to decode the
@ -264,7 +270,41 @@ public:
* subset left and subset width to decode partial scanlines on calls
* to getScanlines().
*/
SkIRect* fSubset;
const SkIRect* fSubset;
/**
* The frame to decode.
*
* Only meaningful for multi-frame images.
*/
size_t fFrameIndex;
/**
* If true, the dst already contains the prior frame.
*
* Only meaningful for multi-frame images.
*
* If fFrameIndex needs to be blended with a prior frame (as reported by
* getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to
* either true or false:
*
* true means that the prior frame is already in the dst, and this
* codec only needs to decode fFrameIndex and blend it with the dst.
* Options.fZeroInitialized is ignored in this case.
*
* false means that the dst does not contain the prior frame, so this
* codec needs to first decode the prior frame (which in turn may need
* to decode its prior frame).
*/
bool fHasPriorFrame;
/**
* Indicates whether we should do a linear premultiply or a legacy premultiply.
*
* In the case where the dst SkColorSpace is nullptr, this flag is ignored and
* we will always do a legacy premultiply.
*/
SkTransferFunctionBehavior fPremulBehavior;
};
/**
@ -522,19 +562,6 @@ public:
* Upside down bmps are an example.
*/
kBottomUp_SkScanlineOrder,
/*
* This indicates that the scanline decoder reliably outputs rows, but
* they will not be in logical order. If the scanline format is
* kOutOfOrder, the nextScanline() API should be used to determine the
* actual y-coordinate of the next output row.
*
* For this scanline ordering, it is advisable to get and skip
* scanlines one at a time.
*
* Interlaced gifs are an example.
*/
kOutOfOrder_SkScanlineOrder,
};
/**
@ -550,7 +577,7 @@ public:
* decoder.
*
* This will equal fCurrScanline, except in the case of strangely
* encoded image types (bottom-up bmps, interlaced gifs).
* encoded image types (bottom-up bmps).
*
* Results are undefined when not in scanline decoding mode.
*/
@ -566,6 +593,87 @@ public:
*/
int outputScanline(int inputScanline) const;
/**
* Return the number of frames in the image.
*
* May require reading through the stream.
*/
size_t getFrameCount() {
return this->onGetFrameCount();
}
// The required frame for an independent frame is marked as
// kNone.
static constexpr size_t kNone = static_cast<size_t>(-1);
/**
* Information about individual frames in a multi-framed image.
*/
struct FrameInfo {
/**
* The frame that this frame needs to be blended with, or
* kNone.
*/
size_t fRequiredFrame;
/**
* Number of milliseconds to show this frame.
*/
size_t fDuration;
/**
* Whether the end marker for this frame is contained in the stream.
*
* Note: this does not guarantee that an attempt to decode will be complete.
* There could be an error in the stream.
*/
bool fFullyReceived;
/**
* This is conservative; it will still return non-opaque if e.g. a
* color index-based frame has a color with alpha but does not use it.
*/
SkAlphaType fAlphaType;
};
/**
* Return info about a single frame.
*
* Only supported by multi-frame images. Does not read through the stream,
* so it should be called after getFrameCount() to parse any frames that
* have not already been parsed.
*/
bool getFrameInfo(size_t index, FrameInfo* info) const {
return this->onGetFrameInfo(index, info);
}
/**
* Return info about all the frames in the image.
*
* May require reading through the stream to determine info about the
* frames (including the count).
*
* As such, future decoding calls may require a rewind.
*
* For single-frame images, this will return an empty vector.
*/
std::vector<FrameInfo> getFrameInfo();
static constexpr int kRepetitionCountInfinite = -1;
/**
* Return the number of times to repeat, if this image is animated.
*
* May require reading the stream to find the repetition count.
*
* As such, future decoding calls may require a rewind.
*
* For single-frame images, this will return 0.
*/
int getRepetitionCount() {
return this->onGetRepetitionCount();
}
protected:
/**
* Takes ownership of SkStream*
@ -574,7 +682,7 @@ protected:
int height,
const SkEncodedInfo&,
SkStream*,
sk_sp<SkColorSpace> = nullptr,
sk_sp<SkColorSpace>,
Origin = kTopLeft_Origin);
/**
@ -600,7 +708,7 @@ protected:
return false;
}
virtual SkEncodedFormat onGetEncodedFormat() const = 0;
virtual SkEncodedImageFormat onGetEncodedFormat() const = 0;
/**
* @param rowsDecoded When the encoded image stream is incomplete, this function
@ -706,25 +814,42 @@ protected:
virtual int onOutputScanline(int inputScanline) const;
/**
* Used for testing with qcms.
* FIXME: Remove this when we are done comparing with qcms.
*/
virtual sk_sp<SkData> getICCData() const { return nullptr; }
private:
const SkEncodedInfo fEncodedInfo;
const SkImageInfo fSrcInfo;
SkAutoTDelete<SkStream> fStream;
bool fNeedsRewind;
const Origin fOrigin;
bool initializeColorXform(const SkImageInfo& dstInfo,
SkTransferFunctionBehavior premulBehavior);
SkColorSpaceXform* colorXform() const { return fColorXform.get(); }
SkImageInfo fDstInfo;
SkCodec::Options fOptions;
virtual size_t onGetFrameCount() {
return 1;
}
virtual bool onGetFrameInfo(size_t, FrameInfo*) const {
return false;
}
virtual int onGetRepetitionCount() {
return 0;
}
void setUnsupportedICC(bool SkDEBUGCODE(value)) { SkDEBUGCODE(fUnsupportedICC = value); }
private:
const SkEncodedInfo fEncodedInfo;
const SkImageInfo fSrcInfo;
std::unique_ptr<SkStream> fStream;
bool fNeedsRewind;
const Origin fOrigin;
SkImageInfo fDstInfo;
SkCodec::Options fOptions;
std::unique_ptr<SkColorSpaceXform> fColorXform;
// Only meaningful during scanline decodes.
int fCurrScanline;
int fCurrScanline;
bool fStartedIncrementalDecode;
bool fStartedIncrementalDecode;
#ifdef SK_DEBUG
bool fUnsupportedICC = false;
#endif
/**
* Return whether these dimensions are supported as a scale.
@ -782,17 +907,14 @@ private:
* May create a sampler, if one is not currently being used. Otherwise, does
* not affect ownership.
*
* Only valid during scanline decoding.
* Only valid during scanline decoding or incremental decoding.
*/
virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
// For testing with qcms
// FIXME: Remove these when we are done comparing with qcms.
friend class DM::ColorCodecSrc;
friend class ColorCodecBench;
friend class DM::CodecSrc; // for fillIncompleteImage
friend class SkSampledCodec;
friend class SkIcoCodec;
friend struct Sniffer; // for fUnsupportedICC
friend class AutoCleanPng; // for setUnsupportedICC()
};
#endif // SkCodec_DEFINED

Просмотреть файл

@ -1,28 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEncodedFormat_DEFINED
#define SkEncodedFormat_DEFINED
/**
* Enum describing format of encoded data.
*/
enum SkEncodedFormat {
kUnknown_SkEncodedFormat,
kBMP_SkEncodedFormat,
kGIF_SkEncodedFormat,
kICO_SkEncodedFormat,
kJPEG_SkEncodedFormat,
kPNG_SkEncodedFormat,
kWBMP_SkEncodedFormat,
kWEBP_SkEncodedFormat,
kPKM_SkEncodedFormat,
kKTX_SkEncodedFormat,
kASTC_SkEncodedFormat,
kDNG_SkEncodedFormat,
};
#endif // SkEncodedFormat_DEFINED

Просмотреть файл

@ -93,10 +93,6 @@
*/
//#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024)
/* Define this to provide font subsetter in PDF generation.
*/
//#define SK_SFNTLY_SUBSETTER "sample/chromium/font_subsetter.h"
/* Define this to set the upper limit for text to support LCD. Values that
are very large increase the cost in the font cache and draw slower, without
improving readability. If this is undefined, Skia will use its default
@ -161,8 +157,6 @@
#define SK_DISABLE_SLOW_DEBUG_VALIDATION 1
#define MOZ_SKIA 1
#ifndef MOZ_IMPLICIT
# ifdef MOZ_CLANG_PLUGIN
# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
@ -171,4 +165,6 @@
# endif
#endif
#define MOZ_SKIA
#endif

Просмотреть файл

@ -20,8 +20,6 @@ struct SkIRect;
struct SkRect;
class SkPaint;
class SkPixelRef;
class SkPixelRefFactory;
class SkRegion;
class SkString;
/** \class SkBitmap
@ -33,6 +31,8 @@ class SkString;
A const SkBitmap exposes getAddr(), which lets a caller write its pixels;
the constness is considered to apply to the bitmap's configuration, not
its contents.
SkBitmap is not thread safe. Each thread must use its own (shallow) copy.
*/
class SK_API SkBitmap {
public:
@ -85,6 +85,7 @@ public:
SkColorType colorType() const { return fInfo.colorType(); }
SkAlphaType alphaType() const { return fInfo.alphaType(); }
SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); }
/**
* Return the number of bytes per pixel based on the colortype. If the colortype is
@ -117,7 +118,7 @@ public:
* dimensions of the bitmap are > 0 (see empty()).
* Hey! Before you use this, see if you really want to know drawsNothing() instead.
*/
bool isNull() const { return NULL == fPixelRef; }
bool isNull() const { return nullptr == fPixelRef; }
/** Return true iff drawing this bitmap has no effect.
*/
@ -215,7 +216,10 @@ public:
* this (isOpaque). Only call this if you need to compute this value from
* "unknown" pixels.
*/
static bool ComputeIsOpaque(const SkBitmap&);
static bool ComputeIsOpaque(const SkBitmap& bm) {
SkAutoPixmapUnlock result;
return bm.requestLock(&result) && result.pixmap().computeIsOpaque();
}
/**
* Return the bitmap's bounds [0, 0, width, height] as an SkRect
@ -233,16 +237,20 @@ public:
bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
enum AllocFlags {
kZeroPixels_AllocFlag = 1 << 0,
};
/**
* Allocate the bitmap's pixels to match the requested image info. If the Factory
* is non-null, call it to allcoate the pixelref. If the ImageInfo requires
* a colortable, then ColorTable must be non-null, and will be ref'd.
* a colortable, then ColorTable must be non-null.
*
* On failure, the bitmap will be set to empty and return false.
*/
bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
void allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) {
if (!this->tryAllocPixels(info, factory, ctable)) {
bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, sk_sp<SkColorTable> ctable,
uint32_t flags = 0);
void allocPixels(const SkImageInfo& info, sk_sp<SkColorTable> ctable, uint32_t flags = 0) {
if (!this->tryAllocPixels(info, std::move(ctable), flags)) {
sk_throw();
}
}
@ -283,6 +291,11 @@ public:
this->allocPixels(info);
}
// TEMPORARY -- remove after updating Android BitmapTests.cpp:35
void allocPixels(const SkImageInfo& info, std::nullptr_t, SkColorTable* ctable) {
this->allocPixels(info, sk_ref_sp(ctable));
}
/**
* Install a pixelref that wraps the specified pixels and rowBytes, and
* optional ReleaseProc and context. When the pixels are no longer
@ -332,27 +345,6 @@ public:
*/
void setPixels(void* p, SkColorTable* ctable = NULL);
/** Copies the bitmap's pixels to the location pointed at by dst and returns
true if possible, returns false otherwise.
In the case when the dstRowBytes matches the bitmap's rowBytes, the copy
may be made faster by copying over the dst's per-row padding (for all
rows but the last). By setting preserveDstPad to true the caller can
disable this optimization and ensure that pixels in the padding are not
overwritten.
Always returns false for RLE formats.
@param dst Location of destination buffer.
@param dstSize Size of destination buffer. Must be large enough to hold
pixels using indicated stride.
@param dstRowBytes Width of each line in the buffer. If 0, uses
bitmap's internal stride.
@param preserveDstPad Must we preserve padding in the dst
*/
bool copyPixelsTo(void* const dst, size_t dstSize, size_t dstRowBytes = 0,
bool preserveDstPad = false) const;
/** Use the standard HeapAllocator to create the pixelref that manages the
pixel memory. It will be sized based on the current ImageInfo.
If this is called multiple times, a new pixelref object will be created
@ -404,7 +396,7 @@ public:
* Return the current pixelref object or NULL if there is none. This does
* not affect the refcount of the pixelref.
*/
SkPixelRef* pixelRef() const { return fPixelRef; }
SkPixelRef* pixelRef() const { return fPixelRef.get(); }
/**
* A bitmap can reference a subset of a pixelref's pixels. That means the
@ -420,21 +412,12 @@ public:
SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
/**
* Assign a pixelref and origin to the bitmap. Pixelrefs are reference,
* so the existing one (if any) will be unref'd and the new one will be
* ref'd. (x,y) specify the offset within the pixelref's pixels for the
* top/left corner of the bitmap. For a bitmap that encompases the entire
* pixels of the pixelref, these will be (0,0).
* Assign a pixelref and origin to the bitmap. (dx,dy) specify the offset
* within the pixelref's pixels for the top/left corner of the bitmap. For
* a bitmap that encompases the entire pixels of the pixelref, these will
* be (0,0).
*/
SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
return this->setPixelRef(pr, origin.fX, origin.fY);
}
SkPixelRef* setPixelRef(SkPixelRef* pr) {
return this->setPixelRef(pr, 0, 0);
}
void setPixelRef(sk_sp<SkPixelRef>, int dx, int dy);
/** Call this to ensure that the bitmap points to the current pixel address
in the pixelref. Balance it with a call to unlockPixels(). These calls
@ -448,15 +431,6 @@ public:
*/
void unlockPixels() const;
/**
* Some bitmaps can return a copy of their pixels for lockPixels(), but
* that copy, if modified, will not be pushed back. These bitmaps should
* not be used as targets for a raster device/canvas (since all pixels
* modifications will be lost when unlockPixels() is called.)
*/
// DEPRECATED
bool lockPixelsAreWritable() const;
bool requestLock(SkAutoPixmapUnlock* result) const;
/** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
@ -525,13 +499,19 @@ public:
}
/**
* Return the SkColor of the specified pixel. In most cases this will
* require un-premultiplying the color. Alpha only colortypes (e.g. kAlpha_8_SkColorType)
* return black with the appropriate alpha set. The value is undefined
* for kUnknown_SkColorType or if x or y are out of bounds, or if the bitmap
* does not have any pixels (or has not be locked with lockPixels()).
* Converts the pixel at the specified coordinate to an unpremultiplied
* SkColor. Note: this ignores any SkColorSpace information, and may return
* lower precision data than is actually in the pixel. Alpha only
* colortypes (e.g. kAlpha_8_SkColorType) return black with the appropriate
* alpha set. The value is undefined for kUnknown_SkColorType or if x or y
* are out of bounds, or if the bitmap does not have any pixels (or has not
* be locked with lockPixels())..
*/
SkColor getColor(int x, int y) const;
SkColor getColor(int x, int y) const {
SkPixmap pixmap;
SkAssertResult(this->peekPixels(&pixmap));
return pixmap.getColor(x, y);
}
/** Returns the address of the specified pixel. This performs a runtime
check to know the size of the pixels, and will return the same answer
@ -586,6 +566,7 @@ public:
*/
bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
#ifdef SK_BUILD_FOR_ANDROID
/** Makes a deep copy of this bitmap, respecting the requested colorType,
* and allocating the dst pixels on the cpu.
* Returns false if either there is an error (i.e. the src does not have
@ -598,11 +579,26 @@ public:
* will be used.
* @return true if the copy was made.
*/
bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const;
bool copyTo(SkBitmap* dst, SkColorType ct, Allocator*) const;
bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const {
bool copyTo(SkBitmap* dst, Allocator* allocator) const {
return this->copyTo(dst, this->colorType(), allocator);
}
#endif
/** Makes a deep copy of this bitmap, respecting the requested colorType.
* Returns false if either there is an error (i.e. the src does not have
* pixels) or the request cannot be satisfied (e.g. the src has per-pixel
* alpha, and the requested colortype does not support alpha).
* @param dst The bitmap to be sized and allocated
* @param ct The desired colorType for dst
* @return true if the copy was made.
*/
bool copyTo(SkBitmap* dst, SkColorType ct) const;
bool copyTo(SkBitmap* dst) const {
return this->copyTo(dst, this->colorType());
}
/**
* Copy the bitmap's pixels into the specified buffer (pixels + rowBytes),
@ -625,6 +621,23 @@ public:
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const;
bool readPixels(const SkPixmap& dst, int srcX, int srcY) const;
bool readPixels(const SkPixmap& dst) const {
return this->readPixels(dst, 0, 0);
}
/**
* Copy the src pixmap's pixels into this bitmap, offset by dstX, dstY.
*
* This is logically the same as creating a bitmap around src, and calling readPixels on it
* with this bitmap as the dst.
*/
bool writePixels(const SkPixmap& src, int dstX, int dstY) {
return this->writePixels(src, dstX, dstY, SkTransferFunctionBehavior::kRespect);
}
bool writePixels(const SkPixmap& src) {
return this->writePixels(src, 0, 0);
}
/**
* Returns true if this bitmap's pixels can be converted into the requested
@ -715,37 +728,16 @@ public:
bool allocPixelRef(SkBitmap*, SkColorTable*) override;
};
class RLEPixels {
public:
RLEPixels(int width, int height);
virtual ~RLEPixels();
uint8_t* packedAtY(int y) const {
SkASSERT((unsigned)y < (unsigned)fHeight);
return fYPtrs[y];
}
// called by subclasses during creation
void setPackedAtY(int y, uint8_t* addr) {
SkASSERT((unsigned)y < (unsigned)fHeight);
fYPtrs[y] = addr;
}
private:
uint8_t** fYPtrs;
int fHeight;
};
SK_TO_STRING_NONVIRT()
private:
mutable SkPixelRef* fPixelRef;
mutable int fPixelLockCount;
mutable sk_sp<SkPixelRef> fPixelRef;
mutable int fPixelLockCount;
// These are just caches from the locked pixelref
mutable void* fPixels;
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
mutable void* fPixels;
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
SkIPoint fPixelRefOrigin;
SkIPoint fPixelRefOrigin;
enum Flags {
kImageIsVolatile_Flag = 0x02,
@ -758,9 +750,13 @@ private:
#endif
};
SkImageInfo fInfo;
uint32_t fRowBytes;
uint8_t fFlags;
SkImageInfo fInfo;
uint32_t fRowBytes;
uint8_t fFlags;
bool writePixels(const SkPixmap& src, int x, int y, SkTransferFunctionBehavior behavior);
bool internalCopyTo(SkBitmap* dst, SkColorType ct, Allocator*) const;
/* Unreference any pixelrefs or colortables
*/
@ -770,6 +766,7 @@ private:
static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
friend class SkImage_Raster;
friend class SkReadBuffer; // unflatten, rawpixels
friend class SkBinaryWriteBuffer; // rawpixels
friend struct SkBitmapProcState;

Просмотреть файл

@ -8,6 +8,8 @@
#ifndef SkBlendMode_DEFINED
#define SkBlendMode_DEFINED
#include "SkTypes.h"
enum class SkBlendMode {
kClear, //!< [0, 0]
kSrc, //!< [Sa, Sc]
@ -48,4 +50,9 @@ enum class SkBlendMode {
kLastMode = kLuminosity
};
/**
* Return the (c-string) name of the blendmode.
*/
SK_API const char* SkBlendMode_Name(SkBlendMode);
#endif

Просмотреть файл

@ -8,42 +8,41 @@
#ifndef SkCanvas_DEFINED
#define SkCanvas_DEFINED
#include "SkTypes.h"
#include "SkBlendMode.h"
#include "SkBitmap.h"
#include "SkClipOp.h"
#include "SkDeque.h"
#include "SkImage.h"
#include "SkPaint.h"
#include "SkRefCnt.h"
#include "SkRegion.h"
#include "SkRasterHandleAllocator.h"
#include "SkSurfaceProps.h"
#include "SkXfermode.h"
#include "SkLights.h"
#include "../private/SkShadowParams.h"
class GrContext;
class GrDrawContext;
class GrRenderTargetContext;
class SkBaseDevice;
class SkBitmap;
#ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
class SkCanvasClipVisitor;
#endif
class SkClipStack;
class SkData;
class SkDraw;
class SkDrawable;
class SkDrawFilter;
class SkImage;
class SkImageFilter;
class SkMetaData;
class SkPath;
class SkPicture;
class SkPixmap;
class SkRasterClip;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkSurface;
class SkSurface_Base;
class SkTextBlob;
//#define SK_SUPPORT_LEGACY_CLIP_REGIONOPS
class SkVertices;
/** \class SkCanvas
@ -60,31 +59,12 @@ class SkTextBlob;
color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
etc.
*/
class SK_API SkCanvas : public SkRefCnt {
class SK_API SkCanvas : SkNoncopyable {
enum PrivateSaveLayerFlags {
kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
};
public:
#ifdef SK_SUPPORT_LEGACY_CLIP_REGIONOPS
typedef SkRegion::Op ClipOp;
static const ClipOp kDifference_Op = SkRegion::kDifference_Op;
static const ClipOp kIntersect_Op = SkRegion::kIntersect_Op;
static const ClipOp kUnion_Op = SkRegion::kUnion_Op;
static const ClipOp kXOR_Op = SkRegion::kXOR_Op;
static const ClipOp kReverseDifference_Op = SkRegion::kReverseDifference_Op;
static const ClipOp kReplace_Op = SkRegion::kReplace_Op;
#else
typedef SkClipOp ClipOp;
static const ClipOp kDifference_Op = kDifference_SkClipOp;
static const ClipOp kIntersect_Op = kIntersect_SkClipOp;
static const ClipOp kUnion_Op = kUnion_SkClipOp;
static const ClipOp kXOR_Op = kXOR_SkClipOp;
static const ClipOp kReverseDifference_Op = kReverseDifference_SkClipOp;
static const ClipOp kReplace_Op = kReplace_SkClipOp;
#endif
/**
* Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
* specified pixels. To access the pixels after drawing to them, the caller should call
@ -100,10 +80,11 @@ public:
* Note: it is valid to request a supported ImageInfo, but with zero
* dimensions.
*/
static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo&, void*, size_t);
static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
size_t rowBytes) {
return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
}
/**
@ -131,6 +112,19 @@ public:
*/
explicit SkCanvas(const SkBitmap& bitmap);
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
enum class ColorBehavior {
kLegacy,
};
/**
* Android framework only constructor.
* Allows the creation of a legacy SkCanvas even though the |bitmap|
* and its pixel ref may have an SkColorSpace.
*/
SkCanvas(const SkBitmap& bitmap, ColorBehavior);
#endif
/** Construct a canvas with the specified bitmap to draw into.
@param bitmap Specifies a bitmap for the canvas to draw into. Its
structure are copied to the canvas.
@ -171,45 +165,6 @@ public:
*/
virtual SkISize getBaseLayerSize() const;
/**
* DEPRECATED: call getBaseLayerSize
*/
SkISize getDeviceSize() const { return this->getBaseLayerSize(); }
/**
* DEPRECATED.
* Return the canvas' device object, which may be null. The device holds
* the bitmap of the pixels that the canvas draws into. The reference count
* of the returned device is not changed by this call.
*/
#ifndef SK_SUPPORT_LEGACY_GETDEVICE
protected: // Can we make this private?
#endif
SkBaseDevice* getDevice() const;
public:
SkBaseDevice* getDevice_just_for_deprecated_compatibility_testing() const {
return this->getDevice();
}
/**
* saveLayer() can create another device (which is later drawn onto
* the previous device). getTopDevice() returns the top-most device current
* installed. Note that this can change on other calls like save/restore,
* so do not access this device after subsequent canvas calls.
* The reference count of the device is not changed.
*
* @param updateMatrixClip If this is true, then before the device is
* returned, we ensure that its has been notified about the current
* matrix and clip. Note: this happens automatically when the device
* is drawn to, but is optional here, as there is a small perf hit
* sometimes.
*/
#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE
private:
#endif
SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
public:
/**
* Create a new surface matching the specified info, one that attempts to
* be maximally compatible when used with this canvas. If there is no matching Surface type,
@ -220,9 +175,6 @@ public:
* surface, then the new surface is created with default properties.
*/
sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps* = nullptr);
#ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
SkSurface* newSurface(const SkImageInfo& info, const SkSurfaceProps* props = NULL);
#endif
/**
* Return the GPU context of the device that is associated with the canvas.
@ -245,6 +197,8 @@ public:
*/
void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
/**
* If the canvas has readable pixels in its base layer (and is not recording to a picture
* or other non-raster target) and has direct access to its pixels (i.e. they are in
@ -258,10 +212,6 @@ public:
*/
bool peekPixels(SkPixmap*);
#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS
const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
#endif
/**
* Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
* converting them into the requested format (SkImageInfo). The base-layer pixels are read
@ -379,6 +329,9 @@ public:
kIsOpaque_SaveLayerFlag = 1 << 0,
kPreserveLCDText_SaveLayerFlag = 1 << 1,
/** initialize the new layer with the contents of the previous layer */
kInitWithPrevious_SaveLayerFlag = 1 << 2,
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
#endif
@ -500,26 +453,37 @@ public:
* @param op The region op to apply to the current clip
* @param doAntiAlias true if the clip should be antialiased
*/
void clipRect(const SkRect& rect, ClipOp, bool doAntiAlias);
void clipRect(const SkRect& rect, ClipOp op) {
void clipRect(const SkRect& rect, SkClipOp, bool doAntiAlias);
void clipRect(const SkRect& rect, SkClipOp op) {
this->clipRect(rect, op, false);
}
void clipRect(const SkRect& rect, bool doAntiAlias = false) {
this->clipRect(rect, kIntersect_Op, doAntiAlias);
this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
}
/**
* Sets the max clip rectangle, which can be set by clipRect, clipRRect and
* clipPath and intersect the current clip with the specified rect.
* The max clip affects only future ops (it is not retroactive).
* We DON'T record the clip restriction in pictures.
* This is private API to be used only by Android framework.
* @param rect The maximum allowed clip in device coordinates.
* Empty rect means max clip is not enforced.
*/
void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
/**
* Modify the current clip with the specified SkRRect.
* @param rrect The rrect to combine with the current clip
* @param op The region op to apply to the current clip
* @param doAntiAlias true if the clip should be antialiased
*/
void clipRRect(const SkRRect& rrect, ClipOp op, bool doAntiAlias);
void clipRRect(const SkRRect& rrect, ClipOp op) {
void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
void clipRRect(const SkRRect& rrect, SkClipOp op) {
this->clipRRect(rrect, op, false);
}
void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
this->clipRRect(rrect, kIntersect_Op, doAntiAlias);
this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
}
/**
@ -528,12 +492,12 @@ public:
* @param op The region op to apply to the current clip
* @param doAntiAlias true if the clip should be antialiased
*/
void clipPath(const SkPath& path, ClipOp op, bool doAntiAlias);
void clipPath(const SkPath& path, ClipOp op) {
void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
void clipPath(const SkPath& path, SkClipOp op) {
this->clipPath(path, op, false);
}
void clipPath(const SkPath& path, bool doAntiAlias = false) {
this->clipPath(path, kIntersect_Op, doAntiAlias);
this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
}
/** EXPERIMENTAL -- only used for testing
@ -550,7 +514,7 @@ public:
@param deviceRgn The region to apply to the current clip
@param op The region op to apply to the current clip
*/
void clipRegion(const SkRegion& deviceRgn, ClipOp op = kIntersect_Op);
void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
/** Return true if the specified rectangle, after being transformed by the
current matrix, would lie completely outside of the current clip. Call
@ -574,34 +538,33 @@ public:
*/
bool quickReject(const SkPath& path) const;
/** Return the bounds of the current clip (in local coordinates) in the
bounds parameter, and return true if it is non-empty. This can be useful
in a way similar to quickReject, in that it tells you that drawing
outside of these bounds will be clipped out.
*/
virtual bool getClipBounds(SkRect* bounds) const;
/**
* Return the bounds of the current clip in local coordinates. If the clip is empty,
* return { 0, 0, 0, 0 }.
*/
SkRect getLocalClipBounds() const { return this->onGetLocalClipBounds(); }
/** Return the bounds of the current clip, in device coordinates; returns
true if non-empty. Maybe faster than getting the clip explicitly and
then taking its bounds.
*/
virtual bool getClipDeviceBounds(SkIRect* bounds) const;
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
specified ARGB color, using the specified mode.
@param a the alpha component (0..255) of the color to fill the canvas
@param r the red component (0..255) of the color to fill the canvas
@param g the green component (0..255) of the color to fill the canvas
@param b the blue component (0..255) of the color to fill the canvas
@param mode the mode to apply the color in (defaults to SrcOver)
*/
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode = SkBlendMode::kSrcOver);
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkXfermode::Mode mode) {
this->drawARGB(a, r, g, b, (SkBlendMode)mode);
/**
* Returns true if the clip bounds are non-empty.
*/
bool getLocalClipBounds(SkRect* bounds) const {
*bounds = this->onGetLocalClipBounds();
return !bounds->isEmpty();
}
/**
* Return the bounds of the current clip in device coordinates. If the clip is empty,
* return { 0, 0, 0, 0 }.
*/
SkIRect getDeviceClipBounds() const { return this->onGetDeviceClipBounds(); }
/**
* Returns true if the clip bounds are non-empty.
*/
bool getDeviceClipBounds(SkIRect* bounds) const {
*bounds = this->onGetDeviceClipBounds();
return !bounds->isEmpty();
}
#endif
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
specified color and mode.
@ -609,11 +572,6 @@ public:
@param mode the mode to apply the color in (defaults to SrcOver)
*/
void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
void drawColor(SkColor color, SkXfermode::Mode mode) {
this->drawColor(color, (SkBlendMode)mode);
}
#endif
/**
* Helper method for drawing a color in SRC mode, completely replacing all the pixels
@ -676,18 +634,10 @@ public:
*/
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
/** Helper method for drawing a single point. See drawPoints() for a more
details.
*/
/** Helper method for drawing a single point. See drawPoints() for more details.
*/
void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
/** Draws a single pixel in the specified color.
@param x The X coordinate of which pixel to draw
@param y The Y coordiante of which pixel to draw
@param color The color to draw
*/
void drawPoint(SkScalar x, SkScalar y, SkColor color);
/** Draw a line segment with the specified start and stop x,y coordinates,
using the specified paint. NOTE: since a line is always "framed", the
paint's Style is ignored.
@ -697,8 +647,7 @@ public:
@param y1 The y-coordinate of the end point of the line
@param paint The paint used to draw the line
*/
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
const SkPaint& paint);
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
/** Draw the specified rectangle using the specified paint. The rectangle
will be filled or stroked based on the Style in the paint.
@ -718,17 +667,6 @@ public:
this->drawRect(r, paint);
}
/** Draw the specified rectangle using the specified paint. The rectangle
will be filled or framed based on the Style in the paint.
@param left The left side of the rectangle to be drawn
@param top The top side of the rectangle to be drawn
@param right The right side of the rectangle to be drawn
@param bottom The bottom side of the rectangle to be drawn
@param paint The paint used to draw the rect
*/
void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
SkScalar bottom, const SkPaint& paint);
/** Draw the outline of the specified region using the specified paint.
@param region The region to be drawn
@param paint The paint used to draw the region
@ -765,8 +703,7 @@ public:
@param radius The radius of the cirle to be drawn
@param paint The paint used to draw the circle
*/
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
const SkPaint& paint);
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
/** Draw the specified arc, which will be scaled to fit inside the
specified oval. Sweep angles are not treated as modulo 360 and thus can
@ -792,8 +729,7 @@ public:
@param ry The y-radius of the oval used to round the corners
@param paint The paint used to draw the roundRect
*/
void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
const SkPaint& paint);
void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
/** Draw the specified path using the specified paint. The path will be
filled or framed based on the Style in the paint.
@ -1176,48 +1112,16 @@ public:
}
#endif
enum VertexMode {
kTriangles_VertexMode,
kTriangleStrip_VertexMode,
kTriangleFan_VertexMode
};
/** Draw vertices from an immutable SkVertices object.
/** Draw the array of vertices, interpreted as triangles (based on mode).
If both textures and vertex-colors are NULL, it strokes hairlines with
the paint's color. This behavior is a useful debugging mode to visualize
the mesh.
@param vmode How to interpret the array of vertices
@param vertexCount The number of points in the vertices array (and
corresponding texs and colors arrays if non-null)
@param vertices Array of vertices for the mesh
@param texs May be null. If not null, specifies the coordinate
in _texture_ space (not uv space) for each vertex.
@param colors May be null. If not null, specifies a color for each
vertex, to be interpolated across the triangle.
@param xmode Used if both texs and colors are present. In this
case the colors are combined with the texture using mode,
before being drawn using the paint. If mode is null, then
kModulate_Mode is used.
@param indices If not null, array of indices to reference into the
vertex (texs, colors) array.
@param indexCount number of entries in the indices array (if not null)
@param vertices The mesh to draw.
@param mode Used if both texs and colors are present and paint has a
shader. In this case the colors are combined with the texture
using mode, before being drawn using the paint.
@param paint Specifies the shader/texture if present.
*/
void drawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint);
void drawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], const sk_sp<SkXfermode>& xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
this->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode.get(),
indices, indexCount, paint);
}
*/
void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
/**
Draw a cubic coons patch
@ -1228,15 +1132,15 @@ public:
their order is clockwise starting at the top left corner.
@param texCoords specifies the texture coordinates that will be bilerp across the patch,
their order is the same as the colors.
@param xmode specifies how are the colors and the textures combined if both of them are
@param mode specifies how are the colors and the textures combined if both of them are
present.
@param paint Specifies the shader/texture if present.
*/
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
void drawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4],
const sk_sp<SkXfermode>& xmode, const SkPaint& paint) {
this->drawPatch(cubics, colors, texCoords, xmode.get(), paint);
const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], const SkPaint& paint) {
this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
}
/**
@ -1247,32 +1151,30 @@ public:
* xform maps [0, 0, tex.width, tex.height] -> quad
*
* The color array is optional. When specified, each color modulates the pixels in its
* corresponding quad (via the specified SkXfermode::Mode).
* corresponding quad (via the specified SkBlendMode).
*
* The cullRect is optional. When specified, it must be a conservative bounds of all of the
* resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
* intersect the current clip.
*
* The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
* and xfermode are used to affect each of the quads.
* and blendmode are used to affect each of the quads.
*/
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
const SkColor colors[], int count, SkXfermode::Mode, const SkRect* cullRect,
const SkColor colors[], int count, SkBlendMode, const SkRect* cullRect,
const SkPaint* paint);
void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
const SkPaint* paint) {
this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
}
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
const SkRect* cullRect, const SkPaint* paint) {
this->drawAtlas(atlas, xform, tex, NULL, count, SkXfermode::kDst_Mode, cullRect, paint);
}
void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
const SkColor colors[], int count, SkXfermode::Mode mode, const SkRect* cull,
const SkPaint* paint) {
this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cull, paint);
this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
}
void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
int count, const SkRect* cullRect, const SkPaint* paint) {
this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkXfermode::kDst_Mode,
this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
cullRect, paint);
}
@ -1351,15 +1253,7 @@ public:
*/
const SkMatrix& getTotalMatrix() const;
/** Return the clip stack. The clip stack stores all the individual
* clips organized by the save/restore frame in which they were
* added.
* @return the current clip stack ("list" of individual clip elements)
*/
const SkClipStack* getClipStack() const {
return fClipStack;
}
#ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
typedef SkCanvasClipVisitor ClipVisitor;
/**
* Replays the clip operations, back to front, that have been applied to
@ -1367,11 +1261,12 @@ public:
* clip. All clips have already been transformed into device space.
*/
void replayClips(ClipVisitor*) const;
#endif
///////////////////////////////////////////////////////////////////////////
// don't call
GrDrawContext* internal_private_accessTopLayerDrawContext();
GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
// don't call
static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
@ -1393,6 +1288,12 @@ public:
*/
void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
/**
* Returns the global clip as a region. If the clip contains AA, then only the bounds
* of the clip may be returned.
*/
void temporary_internal_getRgnClip(SkRegion*);
protected:
#ifdef SK_EXPERIMENTAL_SHADOWING
/** Returns the current (cumulative) draw depth of the canvas.
@ -1437,6 +1338,10 @@ protected:
virtual void didTranslateZ(SkScalar) {}
#endif
virtual SkRect onGetLocalClipBounds() const;
virtual SkIRect onGetDeviceClipBounds() const;
virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value);
virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
@ -1460,7 +1365,7 @@ protected:
const SkPaint& paint);
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
virtual void onDrawDrawable(SkDrawable*, const SkMatrix*);
@ -1472,12 +1377,9 @@ protected:
const SkPaint&);
virtual void onDrawRRect(const SkRRect&, const SkPaint&);
virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&);
virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
const SkPoint texs[], const SkColor colors[], SkXfermode*,
const uint16_t indices[], int indexCount, const SkPaint&);
virtual void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&);
virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*);
int count, SkBlendMode, const SkRect* cull, const SkPaint*);
virtual void onDrawPath(const SkPath&, const SkPaint&);
virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
@ -1500,10 +1402,10 @@ protected:
kSoft_ClipEdgeStyle
};
virtual void onClipRect(const SkRect& rect, ClipOp, ClipEdgeStyle);
virtual void onClipRRect(const SkRRect& rrect, ClipOp, ClipEdgeStyle);
virtual void onClipPath(const SkPath& path, ClipOp, ClipEdgeStyle);
virtual void onClipRegion(const SkRegion& deviceRgn, ClipOp);
virtual void onClipRect(const SkRect& rect, SkClipOp, ClipEdgeStyle);
virtual void onClipRRect(const SkRRect& rrect, SkClipOp, ClipEdgeStyle);
virtual void onClipPath(const SkPath& path, SkClipOp, ClipEdgeStyle);
virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp);
virtual void onDiscard();
@ -1515,12 +1417,6 @@ protected:
const SkPaint*,
const SkShadowParams& params);
#endif
// Returns the canvas to be used by DrawIter. Default implementation
// returns this. Subclasses that encapsulate an indirect canvas may
// need to overload this method. The impl must keep track of this, as it
// is not released or deleted by the caller.
virtual SkCanvas* canvasForDrawIter();
// Clip rectangle bounds. Called internally by saveLayer.
// returns false if the entire rectangle is entirely clipped out
@ -1551,7 +1447,7 @@ private:
SkBaseDevice* device() const;
const SkMatrix& matrix() const;
const SkRasterClip& clip() const;
void clip(SkRegion*) const;
const SkPaint& paint() const;
int x() const;
int y() const;
@ -1567,13 +1463,13 @@ private:
SkPaint fDefaultPaint;
bool fDone;
};
static bool BoundsAffectsClip(SaveLayerFlags);
static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
SkBaseDevice* dst, const SkMatrix& ctm,
const SkClipStack* clipStack);
SkBaseDevice* dst, const SkIPoint& dstOrigin,
const SkMatrix& ctm);
enum ShaderOverrideOpacity {
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
@ -1590,9 +1486,13 @@ private:
: kNotOpaque_ShaderOverrideOpacity);
}
public:
SkBaseDevice* getDevice() const;
SkBaseDevice* getTopDevice() const;
private:
class MCRec;
SkAutoTUnref<SkClipStack> fClipStack;
SkDeque fMCStack;
// points to top of stack
MCRec* fMCRec;
@ -1600,7 +1500,7 @@ private:
enum {
kMCRecSize = 128, // most recent measurement
kMCRecCount = 32, // common depth for save/restores
kDeviceCMSize = 176, // most recent measurement
kDeviceCMSize = 184, // most recent measurement
};
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
@ -1610,6 +1510,7 @@ private:
int fSaveCount; // value returned by getSaveCount()
SkMetaData* fMetaData;
std::unique_ptr<SkRasterHandleAllocator> fAllocator;
SkSurface_Base* fSurfaceBase;
SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
@ -1619,8 +1520,7 @@ private:
friend class SkSurface_Base;
friend class SkSurface_Gpu;
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
void updateDeviceCMCache();
SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
void doSave();
void checkForDeferredSave();
@ -1628,15 +1528,17 @@ private:
friend class SkDrawIter; // needs setupDrawForLayerDevice()
friend class AutoDrawLooper;
friend class SkLua; // needs top layer size and offset
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
friend class SkSurface_Raster; // needs getDevice()
friend class SkRecorder; // InitFlags
friend class SkLiteRecorder; // InitFlags
friend class SkNoSaveLayerCanvas; // InitFlags
friend class SkRecorder; // resetForNextPicture
friend class SkLiteRecorder; // resetForNextPicture
friend class SkNoDrawCanvas; // InitFlags
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
friend class SkDeferredCanvas; // For use of resetForNextPicture
friend class SkOverdrawCanvas;
friend class SkRasterHandleAllocator;
enum InitFlags {
kDefault_InitFlags = 0,
@ -1644,6 +1546,8 @@ private:
};
SkCanvas(const SkIRect& bounds, InitFlags);
SkCanvas(SkBaseDevice* device, InitFlags);
SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
SkRasterHandleAllocator::Handle);
void resetForNextPicture(const SkIRect& bounds);
@ -1673,14 +1577,6 @@ private:
// shared by save() and saveLayer()
void internalSave();
void internalRestore();
static void DrawRect(const SkDraw& draw, const SkPaint& paint,
const SkRect& r, SkScalar textSize);
static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
const char text[], size_t byteLength,
SkScalar x, SkScalar y);
// only for canvasutils
const SkRegion& internal_private_getTotalClip() const;
/*
* Returns true if drawing the specified rect (or all if it is null) with the specified
@ -1694,6 +1590,11 @@ private:
*/
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
/**
* Returns true if the clip (for any active layer) contains antialiasing.
* If the clip is empty, this will return false.
*/
bool androidFramework_isClipAA() const;
/**
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
@ -1704,7 +1605,6 @@ private:
bool fAllowSoftClip;
bool fAllowSimplifyClip;
const bool fConservativeRasterClip;
class AutoValidateClip : ::SkNoncopyable {
public:
@ -1763,12 +1663,14 @@ private:
};
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
#ifdef SK_SUPPORT_OBSOLETE_REPLAYCLIP
class SkCanvasClipVisitor {
public:
virtual ~SkCanvasClipVisitor();
virtual void clipRect(const SkRect&, SkCanvas::ClipOp, bool antialias) = 0;
virtual void clipRRect(const SkRRect&, SkCanvas::ClipOp, bool antialias) = 0;
virtual void clipPath(const SkPath&, SkCanvas::ClipOp, bool antialias) = 0;
virtual void clipRect(const SkRect&, SkClipOp, bool antialias) = 0;
virtual void clipRRect(const SkRRect&, SkClipOp, bool antialias) = 0;
virtual void clipPath(const SkPath&, SkClipOp, bool antialias) = 0;
};
#endif
#endif

Просмотреть файл

@ -1,89 +0,0 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkChunkAlloc_DEFINED
#define SkChunkAlloc_DEFINED
#include "SkTypes.h"
class SkChunkAlloc : SkNoncopyable {
public:
SkChunkAlloc(size_t minSize);
~SkChunkAlloc();
/**
* Free up all allocated blocks. This invalidates all returned
* pointers.
*/
void reset();
/**
* Reset to 0 used bytes preserving as much memory as possible.
* This invalidates all returned pointers.
*/
void rewind();
enum AllocFailType {
kReturnNil_AllocFailType,
kThrow_AllocFailType
};
/**
* Allocates a memory block of size bytes.
* On success: returns a pointer to beginning of memory block that is
* 8 byte aligned. The content of allocated block is not initialized.
* On failure: calls abort() if called with kThrow_AllocFailType,
* otherwise returns NULL pointer.
*/
void* alloc(size_t bytes, AllocFailType);
/**
* Shortcut for calling alloc with kThrow_AllocFailType.
*/
void* allocThrow(size_t bytes) {
return this->alloc(bytes, kThrow_AllocFailType);
}
/** Call this to unalloc the most-recently allocated ptr by alloc(). On
success, the number of bytes freed is returned, or 0 if the block could
not be unallocated. This is a hint to the underlying allocator that
the previous allocation may be reused, but the implementation is free
to ignore this call (and return 0).
*/
size_t unalloc(void* ptr);
size_t totalCapacity() const { return fTotalCapacity; }
size_t totalUsed() const { return fTotalUsed; }
SkDEBUGCODE(int blockCount() const { return fBlockCount; })
SkDEBUGCODE(size_t totalLost() const { return fTotalLost; })
/**
* Returns true if the specified address is within one of the chunks, and
* has at least 1-byte following the address (i.e. if addr points to the
* end of a chunk, then contains() will return false).
*/
bool contains(const void* addr) const;
private:
struct Block;
Block* fBlock;
size_t fMinSize;
size_t fChunkSize;
size_t fTotalCapacity;
size_t fTotalUsed; // will be <= fTotalCapacity
SkDEBUGCODE(int fBlockCount;)
SkDEBUGCODE(size_t fTotalLost;) // will be <= fTotalCapacity
Block* newBlock(size_t bytes, AllocFailType ftype);
Block* addBlockIfNecessary(size_t bytes, AllocFailType ftype);
SkDEBUGCODE(void validate();)
};
#endif

Просмотреть файл

@ -10,17 +10,20 @@
#include "SkTypes.h"
// these kept in SkRegion::Op order for now ...
enum SkClipOp {
kDifference_SkClipOp = 0,
kIntersect_SkClipOp = 1,
// SkClipOp enum values always match the corresponding values in SkRegion::Op
enum class SkClipOp {
kDifference = 0,
kIntersect = 1,
// Goal: remove these, since they can grow the current clip
kUnion_SkClipOp = 2,
kXOR_SkClipOp = 3,
kReverseDifference_SkClipOp = 4,
kReplace_SkClipOp = 5,
kUnion_deprecated = 2,
kXOR_deprecated = 3,
kReverseDifference_deprecated = 4,
kReplace_deprecated = 5,
kMax_EnumValue = kReplace_deprecated,
};
#endif

Просмотреть файл

@ -67,7 +67,7 @@ static inline SkColor SkColorSetARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
/** return the blue byte from a SkColor value */
#define SkColorGetB(color) (((color) >> 0) & 0xFF)
static inline SkColor SkColorSetA(SkColor c, U8CPU a) {
static constexpr inline SkColor SkColorSetA(SkColor c, U8CPU a) {
return (c & 0x00FFFFFF) | (a << 24);
}
@ -183,6 +183,7 @@ struct SkColor4f {
float* vec() { return &fR; }
static SkColor4f Pin(float r, float g, float b, float a);
/** Convert to SkColor4f, assuming SkColor is sRGB */
static SkColor4f FromColor(SkColor);
static SkColor4f FromColor3f(SkColor3f, float a);

Просмотреть файл

@ -8,14 +8,16 @@
#ifndef SkColorFilter_DEFINED
#define SkColorFilter_DEFINED
#include "SkBlendMode.h"
#include "SkColor.h"
#include "SkFlattenable.h"
#include "SkRefCnt.h"
#include "SkXfermode.h"
class GrContext;
class GrFragmentProcessor;
class SkArenaAlloc;
class SkBitmap;
class SkColorSpace;
class SkRasterPipeline;
/**
@ -33,7 +35,7 @@ public:
* returns true, and sets (if not NULL) the color and mode appropriately.
* If not, this returns false and ignores the parameters.
*/
virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const;
virtual bool asColorMode(SkColor* color, SkBlendMode* bmode) const;
/**
* If the filter can be represented by a 5x4 matrix, this
@ -71,7 +73,8 @@ public:
virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const;
bool appendStages(SkRasterPipeline*) const;
bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
bool shaderIsOpaque) const;
enum Flags {
/** If set the filter methods will not change the alpha channel of the colors.
@ -109,15 +112,12 @@ public:
If the Mode is DST, this function will return NULL (since that
mode will have no effect on the result).
@param c The source color used with the specified mode
@param mode The xfermode mode that is applied to each color in
@param mode The blend that is applied to each color in
the colorfilter's filterSpan[16,32] methods
@return colorfilter object that applies the src color and mode,
or NULL if the mode will have no effect.
*/
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkXfermode::Mode mode);
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode) {
return MakeModeFilter(c, (SkXfermode::Mode)mode);
}
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode);
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
* the outer filter to the result of the inner's.
@ -134,21 +134,6 @@ public:
*/
static sk_sp<SkColorFilter> MakeMatrixFilterRowMajor255(const SkScalar array[20]);
#ifdef SK_SUPPORT_LEGACY_COLORFILTER_PTR
static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode) {
return MakeModeFilter(c, mode).release();
}
static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner) {
return MakeComposeFilter(sk_ref_sp(outer), sk_ref_sp(inner)).release();
}
static SkColorFilter* CreateMatrixFilterRowMajor255(const SkScalar array[20]) {
return MakeMatrixFilterRowMajor255(array).release();
}
virtual SkColorFilter* newComposed(const SkColorFilter* inner) const {
return this->makeComposed(sk_ref_sp(const_cast<SkColorFilter*>(inner))).release();
}
#endif
#if SK_SUPPORT_GPU
/**
* A subclass may implement this factory function to work with the GPU backend. It returns
@ -159,7 +144,8 @@ public:
*
* A null return indicates that the color filter isn't implemented for the GPU backend.
*/
virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const;
virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
SkColorSpace* dstColorSpace) const;
#endif
bool affectsTransparentBlack() const {
@ -174,7 +160,8 @@ public:
protected:
SkColorFilter() {}
virtual bool onAppendStages(SkRasterPipeline*) const;
virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
bool shaderIsOpaque) const;
private:
/*

Просмотреть файл

@ -204,12 +204,8 @@ static inline unsigned Sk255To256(U8CPU value) {
* for [0,255] value and [0,256] alpha256.
*/
static inline U16CPU SkAlphaMulInv256(U16CPU value, U16CPU alpha256) {
#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
return SkAlpha255To256(255 - SkAlphaMul(value, alpha256));
#else
unsigned prod = 0xFFFF - value * alpha256;
return (prod + (prod >> 8)) >> 8;
#endif
}
// The caller may want negative values, so keep all params signed (int)
@ -584,22 +580,13 @@ static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
* Interpolates between colors src and dst using [0,256] scale.
*/
static inline SkPMColor SkPMLerp(SkPMColor src, SkPMColor dst, unsigned scale) {
#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
return SkAlphaMulQ(src, scale) + SkAlphaMulQ(dst, 256 - scale);
#else
return SkFastFourByteInterp256(src, dst, scale);
#endif
}
static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
SkASSERT((unsigned)aa <= 255);
unsigned src_scale = SkAlpha255To256(aa);
#ifdef SK_SUPPORT_LEGACY_BROKEN_LERP
unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
#else
unsigned dst_scale = SkAlphaMulInv256(SkGetPackedA32(src), src_scale);
const uint32_t mask = 0xFF00FF;
@ -611,7 +598,6 @@ static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
uint32_t dst_ag = ((dst >> 8) & mask) * dst_scale;
return (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask);
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -13,31 +13,62 @@
class SkData;
/**
* Describes a color gamut with primaries and a white point.
*/
struct SK_API SkColorSpacePrimaries {
float fRX, fRY;
float fGX, fGY;
float fBX, fBY;
float fWX, fWY;
/**
* Convert primaries and a white point to a toXYZD50 matrix, the preferred color gamut
* representation of SkColorSpace.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
};
/**
* Contains the coefficients for a common transfer function equation, specified as
* a transformation from a curved space to linear.
*
* LinearVal = C*InputVal + F , for 0.0f <= InputVal < D
* LinearVal = (A*InputVal + B)^G + E, for D <= InputVal <= 1.0f
*
* Function is undefined if InputVal is not in [ 0.0f, 1.0f ].
* Resulting LinearVals must be in [ 0.0f, 1.0f ].
* Function must be positive and increasing.
*/
struct SK_API SkColorSpaceTransferFn {
float fG;
float fA;
float fB;
float fC;
float fD;
float fE;
float fF;
/**
* Produces a new parametric transfer function equation that is the mathematical inverse of
* this one.
*/
SkColorSpaceTransferFn invert() const;
};
class SK_API SkColorSpace : public SkRefCnt {
public:
/**
* Common, named profiles that we can recognize.
* Create the sRGB color space.
*/
enum Named : uint8_t {
/**
* By far the most common color space.
* This is the default space for images, unmarked content, and monitors.
*/
kSRGB_Named,
static sk_sp<SkColorSpace> MakeSRGB();
/**
* Very common wide gamut color space.
* Often used by images and monitors.
*/
kAdobeRGB_Named,
/**
* Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for
* half-float surfaces, and high precision individual colors (gradient stops, etc...)
*/
kSRGBLinear_Named,
};
/**
* Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for
* half-float surfaces, and high precision individual colors (gradient stops, etc...)
*/
static sk_sp<SkColorSpace> MakeSRGBLinear();
enum RenderTargetGamma : uint8_t {
kLinear_RenderTargetGamma,
@ -49,28 +80,34 @@ public:
kSRGB_RenderTargetGamma,
};
/**
* Create an SkColorSpace from a transfer function and a color gamut transform to D50 XYZ.
*/
static sk_sp<SkColorSpace> NewRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50);
enum Gamut {
kSRGB_Gamut,
kAdobeRGB_Gamut,
kDCIP3_D65_Gamut,
kRec2020_Gamut,
};
/**
* Create a common, named SkColorSpace.
* Create an SkColorSpace from a transfer function and a color gamut.
*
* Transfer function can be specified as an enum or as the coefficients to an equation.
* Gamut can be specified as an enum or as the matrix transformation to XYZ D50.
*/
static sk_sp<SkColorSpace> NewNamed(Named);
static sk_sp<SkColorSpace> MakeRGB(RenderTargetGamma gamma, Gamut gamut);
static sk_sp<SkColorSpace> MakeRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50);
static sk_sp<SkColorSpace> MakeRGB(const SkColorSpaceTransferFn& coeffs, Gamut gamut);
static sk_sp<SkColorSpace> MakeRGB(const SkColorSpaceTransferFn& coeffs,
const SkMatrix44& toXYZD50);
/**
* Create an SkColorSpace from an ICC profile.
*/
static sk_sp<SkColorSpace> NewICC(const void*, size_t);
/**
* Create an SkColorSpace with the same gamut as this color space, but with linear gamma.
*/
sk_sp<SkColorSpace> makeLinearGamma();
static sk_sp<SkColorSpace> MakeICC(const void*, size_t);
/**
* Returns true if the color space gamma is near enough to be approximated as sRGB.
* This includes the canonical sRGB transfer function as well as a 2.2f exponential
* transfer function.
*/
bool gammaCloseToSRGB() const;
@ -79,6 +116,34 @@ public:
*/
bool gammaIsLinear() const;
/**
* If the transfer function can be represented as coefficients to the standard
* equation, returns true and sets |fn| to the proper values.
*
* If not, returns false.
*/
bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const;
/**
* Returns true and sets |toXYZD50| if the color gamut can be described as a matrix.
* Returns false otherwise.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
/**
* Returns true if the color space is sRGB.
* Returns false otherwise.
*
* This allows a little bit of tolerance, given that we might see small numerical error
* in some cases: converting ICC fixed point to float, converting white point to D50,
* rounding decisions on transfer function and matrix.
*
* This does not consider a 2.2f exponential transfer function to be sRGB. While these
* functions are similar (and it is sometimes useful to consider them together), this
* function checks for logical equality.
*/
bool isSRGB() const;
/**
* Returns nullptr on failure. Fails when we fallback to serializing ICC data and
* the data is too large to serialize.
@ -103,4 +168,17 @@ protected:
SkColorSpace() {}
};
enum class SkTransferFunctionBehavior {
/**
* Converts to a linear space before premultiplying, unpremultiplying, or blending.
*/
kRespect,
/**
* Premultiplies, unpremultiplies, and blends ignoring the transfer function. Pixels are
* treated as if they are linear, regardless of their transfer function encoding.
*/
kIgnore,
};
#endif

Просмотреть файл

@ -0,0 +1,67 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorSpaceXform_DEFINED
#define SkColorSpaceXform_DEFINED
#include "SkImageInfo.h"
class SkColorSpace;
class SK_API SkColorSpaceXform : SkNoncopyable {
public:
/**
* Create an object to handle color space conversions.
*
* @param srcSpace The encoded color space.
* @param dstSpace The destination color space.
*
*/
static std::unique_ptr<SkColorSpaceXform> New(SkColorSpace* srcSpace, SkColorSpace* dstSpace);
enum ColorFormat {
kRGBA_8888_ColorFormat,
kBGRA_8888_ColorFormat,
// Unsigned, big-endian, 16-bit integer
kRGB_U16_BE_ColorFormat, // Src only
kRGBA_U16_BE_ColorFormat, // Src only
kRGBA_F16_ColorFormat,
kRGBA_F32_ColorFormat,
kBGR_565_ColorFormat, // Dst only, kOpaque only
};
/**
* Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer.
*
* F16 and F32 are only supported when the color space is linear. This function will return
* false in unsupported cases.
*
* @param dst Stored in the format described by |dstColorFormat|
* @param src Stored in the format described by |srcColorFormat|
* @param len Number of pixels in the buffers
* @param dstColorFormat Describes color format of |dst|
* @param srcColorFormat Describes color format of |src|
* @param alphaType Describes alpha properties of the |dst| (and |src|)
* kUnpremul preserves input alpha values
* kPremul performs a premultiplication and also preserves alpha values
* kOpaque optimization hint, |dst| alphas set to 1
*
*/
bool apply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, int count,
SkAlphaType alphaType) const;
virtual ~SkColorSpaceXform() {}
protected:
SkColorSpaceXform() {}
};
#endif

Просмотреть файл

@ -0,0 +1,20 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorSpaceXformCanvas_DEFINED
#define SkColorSpaceXformCanvas_DEFINED
#include <SkCanvas.h>
#include <SkColorSpace.h>
#include <memory>
// Proxy SkCanvas calls to unowned target, transforming colors into targetCS as it goes.
// May return nullptr if |targetCS| is unsupported.
std::unique_ptr<SkCanvas> SK_API SkCreateColorSpaceXformCanvas(SkCanvas* target,
sk_sp<SkColorSpace> targetCS);
#endif //SkColorSpaceXformCanvas_DEFINED

Просмотреть файл

@ -24,10 +24,12 @@
*/
class SK_API SkColorTable : public SkRefCnt {
public:
static sk_sp<SkColorTable> Make(const SkPMColor colors[], int count);
/** Copy up to 256 colors into a new SkColorTable.
*/
SkColorTable(const SkPMColor colors[], int count);
virtual ~SkColorTable();
~SkColorTable() override;
/** Returns the number of colors in the table.
*/
@ -52,7 +54,7 @@ public:
void writeToBuffer(SkWriteBuffer&) const;
// may return null
static SkColorTable* Create(SkReadBuffer&);
static sk_sp<SkColorTable> Create(SkReadBuffer&);
private:
enum AllocatedWithMalloc {

Просмотреть файл

@ -0,0 +1,68 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkCrossContextImageData_DEFINED
#define SkCrossContextImageData_DEFINED
#include "SkImage.h"
#if SK_SUPPORT_GPU
#include "GrExternalTextureData.h"
#endif
class SK_API SkCrossContextImageData : SkNoncopyable {
public:
/**
* Decodes and uploads the encoded data to a texture using the supplied GrContext, then
* returns an instance of SkCrossContextImageData that can be used to transport that texture
* to a different GrContext, across thread boundaries. The GrContext used here, and the one
* used to reconstruct the texture-backed image later must be in the same GL share group,
* or otherwise be able to share resources. After calling this, you *must* construct exactly
* one SkImage from the returned value, using SkImage::MakeFromCrossContextImageData.
*
* The texture will be decoded and uploaded to be suitable for use with surfaces that have the
* supplied destination color space. The color space of the texture itself will be determined
* from the encoded data.
*/
static std::unique_ptr<SkCrossContextImageData> MakeFromEncoded(
GrContext*, sk_sp<SkData>, SkColorSpace* dstColorSpace);
private:
SkCrossContextImageData(sk_sp<SkImage> image) : fImage(std::move(image)) {
SkASSERT(!fImage->isTextureBacked());
}
#if SK_SUPPORT_GPU
SkCrossContextImageData(const GrBackendTextureDesc& desc,
std::unique_ptr<GrExternalTextureData> textureData,
SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace)
: fAlphaType(alphaType)
, fColorSpace(std::move(colorSpace))
, fDesc(desc)
, fTextureData(std::move(textureData)) {
// Point our texture desc at our copy of the backend information
fDesc.fTextureHandle = fTextureData->getBackendObject();
}
#endif
// For non-GPU backed images
sk_sp<SkImage> fImage;
#if SK_SUPPORT_GPU
// GPU-backed images store some generic information (needed to reconstruct the SkImage),
// and some backend-specific info (to reconstruct the texture).
SkAlphaType fAlphaType;
sk_sp<SkColorSpace> fColorSpace;
GrBackendTextureDesc fDesc;
std::unique_ptr<GrExternalTextureData> fTextureData;
#endif
friend class SkImage;
};
#endif

Просмотреть файл

@ -168,14 +168,8 @@ private:
explicit SkData(size_t size); // inplace new/delete
~SkData();
// Objects of this type are sometimes created in a custom fashion using sk_malloc_throw and
// therefore must be sk_freed. We overload new to also call sk_malloc_throw so that memory
// can be unconditionally released using sk_free in an overloaded delete. Overloading regular
// new means we must also overload placement new.
void* operator new(size_t size) { return sk_malloc_throw(size); }
void* operator new(size_t, void* p) { return p; }
void operator delete(void* p) { sk_free(p); }
// Ensure the unsized delete is called.
void operator delete(void* p) { ::operator delete(p); }
// Called the first time someone calls NewEmpty to initialize the singleton.
friend SkData* sk_new_empty_data();

Просмотреть файл

@ -9,7 +9,6 @@
#define SkDataTable_DEFINED
#include "../private/SkTDArray.h"
#include "SkChunkAlloc.h"
#include "SkData.h"
#include "SkString.h"
@ -117,58 +116,4 @@ private:
typedef SkRefCnt INHERITED;
};
/**
* Helper class that allows for incrementally building up the data needed to
* create a SkDataTable.
*/
class SK_API SkDataTableBuilder : SkNoncopyable {
public:
SkDataTableBuilder(size_t minChunkSize);
~SkDataTableBuilder();
int count() const { return fDir.count(); }
size_t minChunkSize() const { return fMinChunkSize; }
/**
* Forget any previously appended entries, setting count() back to 0.
*/
void reset(size_t minChunkSize);
void reset() {
this->reset(fMinChunkSize);
}
/**
* Copy size-bytes from data, and append it to the growing SkDataTable.
*/
void append(const void* data, size_t size);
/**
* Helper version of append() passes strlen() + 1 for the size,
* so the trailing-zero will be copied as well.
*/
void appendStr(const char str[]) {
this->append(str, strlen(str) + 1);
}
/**
* Helper version of append() passes string.size() + 1 for the size,
* so the trailing-zero will be copied as well.
*/
void appendString(const SkString& string) {
this->append(string.c_str(), string.size() + 1);
}
/**
* Return an SkDataTable from the accumulated entries that were added by
* calls to append(). This call also clears any accumluated entries from
* this builder, so its count() will be 0 after this call.
*/
sk_sp<SkDataTable> detachDataTable();
private:
SkTDArray<SkDataTable::Dir> fDir;
SkChunkAlloc* fHeap;
size_t fMinChunkSize;
};
#endif

Просмотреть файл

@ -19,6 +19,10 @@
class SkCanvas;
class SkWStream;
#ifdef SK_BUILD_FOR_WIN
struct IXpsOMObjectFactory;
#endif
/** SK_ScalarDefaultDPI is 72 DPI.
*/
#define SK_ScalarDefaultRasterDPI 72.0f
@ -46,7 +50,7 @@ public:
*/
struct PDFMetadata {
/**
* The documents title.
* The document's title.
*/
SkString fTitle;
/**
@ -141,19 +145,34 @@ public:
static sk_sp<SkDocument> MakePDF(const char outputFilePath[],
SkScalar dpi = SK_ScalarDefaultRasterDPI);
#ifdef SK_BUILD_FOR_WIN
/**
* Create a XPS-backed document, writing the results into the stream.
* Returns NULL if XPS is not supported.
*
* @param stream A XPS document will be written to this stream. The
* document may write to the stream at anytime during its
* lifetime, until either close() or abort() are called or
* the document is deleted.
* @param xpsFactory A pointer to a COM XPS factory. Must be non-null.
* The document will take a ref to the factory. See
* dm/DMSrcSink.cpp for an example.
* @param dpi The DPI (pixels-per-inch) at which features without
* native XPS support will be rasterized (e.g. draw image
* with perspective, draw text with perspective, ...) A
* larger DPI would create a XPS that reflects the
* original intent with better fidelity, but it can make
* for larger XPS files too, which would use more memory
* while rendering, and it would be slower to be processed
* or sent online or to printer.
*
* @returns nullptr if XPS is not supported.
*/
static sk_sp<SkDocument> MakeXPS(SkWStream* stream,
IXpsOMObjectFactory* xpsFactory,
SkScalar dpi = SK_ScalarDefaultRasterDPI);
/**
* Create a XPS-backed document, writing the results into a file.
* Returns NULL if XPS is not supported.
*/
static sk_sp<SkDocument> MakeXPS(const char path[],
SkScalar dpi = SK_ScalarDefaultRasterDPI);
#endif
// DEPRECATED; TODO(halcanary): remove this function after Chromium switches to new API.
static sk_sp<SkDocument> MakeXPS(SkWStream*) { return nullptr; }
/**
* Begin a new page for the document, returning the canvas that will draw

Просмотреть файл

@ -15,10 +15,12 @@
#include "SkPoint.h"
#include "SkColor.h"
class SkCanvas;
class SkPaint;
class SkArenaAlloc;
class SkCanvas;
class SkColorSpaceXformer;
class SkPaint;
struct SkRect;
class SkString;
class SkString;
/** \class SkDrawLooper
Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
@ -61,19 +63,8 @@ public:
/**
* Called right before something is being drawn. Returns a Context
* whose next() method should be called until it returns false.
* The caller has to ensure that the storage pointer provides enough
* memory for the Context. The required size can be queried by calling
* contextSize(). It is also the caller's responsibility to destroy the
* object after use.
*/
virtual Context* createContext(SkCanvas*, void* storage) const = 0;
/**
* Returns the number of bytes needed to store subclasses of Context (belonging to the
* corresponding SkDrawLooper subclass).
*/
virtual size_t contextSize() const = 0;
virtual Context* makeContext(SkCanvas*, SkArenaAlloc*) const = 0;
/**
* The fast bounds functions are used to enable the paint to be culled early
@ -110,9 +101,16 @@ public:
SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
protected:
sk_sp<SkDrawLooper> makeColorSpace(SkColorSpaceXformer* xformer) const {
return this->onMakeColorSpace(xformer);
}
virtual sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
SkDrawLooper() {}
private:
friend class SkColorSpaceXformer;
typedef SkFlattenable INHERITED;
};

Просмотреть файл

@ -9,6 +9,7 @@
#define SkDrawable_DEFINED
#include "SkFlattenable.h"
#include "SkScalar.h"
class SkCanvas;
class SkMatrix;

Просмотреть файл

@ -0,0 +1,33 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEncodedImageFormat_DEFINED
#define SkEncodedImageFormat_DEFINED
#include <stdint.h>
/**
* Enum describing format of encoded data.
*/
enum class SkEncodedImageFormat {
#ifdef GOOGLE3
kUnknown,
#endif
kBMP,
kGIF,
kICO,
kJPEG,
kPNG,
kWBMP,
kWEBP,
kPKM,
kKTX,
kASTC,
kDNG,
};
#endif // SkEncodedImageFormat_DEFINED

Просмотреть файл

@ -1,91 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkError_DEFINED
#define SkError_DEFINED
/** \file SkError.h
*/
enum SkError {
/** All is well
*/
kNoError_SkError=0,
/** User argument passed to Skia function was invalid: NULL when thats
* not allowed, out of numeric range, bad enum, or violating some
* other general precondition.
*/
kInvalidArgument_SkError,
/** User tried to perform some operation in a state when the operation
* was not legal, or the operands make no sense (e.g., asking for
* pixels from an SkPictureCanvas). Other examples might be
* inset()ing a rectangle to make it degenerate (negative width/height).
*/
kInvalidOperation_SkError,
/** Probably not needed right now, but in the future we could have opaque
* handles for SkPictures floating around, and it would be a good idea
* to anticipate this kind of issue.
*/
kInvalidHandle_SkError,
/** This is probably not possible because paint surely has defaults for
* everything, but perhaps a paint can get into a bad state somehow.
*/
kInvalidPaint_SkError,
/** Skia was unable to allocate memory to perform some task.
*/
kOutOfMemory_SkError,
/** Skia failed while trying to consume some external resource.
*/
kParseError_SkError,
/** Something went wrong internally; could be resource exhaustion but
* will often be a bug.
*/
kInternalError_SkError
};
/** Return the current per-thread error code. Error codes are "sticky"; they
* are not not reset by subsequent successful operations.
*/
SkError SkGetLastError();
/** Clear the current per-thread error code back to kNoError_SkError.
*/
void SkClearLastError();
/** Type for callback functions to be invoked whenever an error is registered.
* Callback functions take the error code being set, as well as a context
* argument that is provided when the callback is registered.
*/
typedef void (*SkErrorCallbackFunction)(SkError, void *);
/** Set the current per-thread error callback.
*
* @param cb The callback function to be invoked. Passing NULL
* for cb will revert to the default error callback which
* does nothing on release builds, but on debug builds will
* print an informative error message to the screen.
* @param context An arbitrary pointer that will be passed to
* the provided callback function.
*/
void SkSetErrorCallback(SkErrorCallbackFunction cb, void *context);
/** Get a human-readable description of the last (per-thread) error that
* occurred. The returned error message will include not only a human
* readable version of the error code, but also information about the
* conditions that led to the error itself.
*/
const char *SkGetLastErrorString();
#endif /* SkError_DEFINED */

Просмотреть файл

@ -0,0 +1,32 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkExecutor_DEFINED
#define SkExecutor_DEFINED
#include <functional>
#include <memory>
class SkExecutor {
public:
virtual ~SkExecutor();
// Create a thread pool SkExecutor with a fixed thread count, by default the number of cores.
static std::unique_ptr<SkExecutor> MakeThreadPool(int threads = 0);
// There is always a default SkExecutor available by calling SkExecutor::GetDefault().
static SkExecutor& GetDefault();
static void SetDefault(SkExecutor*); // Does not take ownership. Not thread safe.
// Add work to execute.
virtual void add(std::function<void(void)>) = 0;
// If it makes sense for this executor, use this thread to execute work for a little while.
virtual void borrow() {}
};
#endif//SkExecutor_DEFINED

Просмотреть файл

@ -11,9 +11,12 @@
#include "SkFlattenable.h"
class SkData;
class SkImageFilter;
SK_API SkData* SkValidatingSerializeFlattenable(SkFlattenable*);
SK_API SkFlattenable* SkValidatingDeserializeFlattenable(const void* data, size_t size,
SkFlattenable::Type type);
SK_API sk_sp<SkImageFilter> SkValidatingDeserializeImageFilter(const void* data, size_t size);
#endif

Просмотреть файл

@ -0,0 +1,79 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontAgruments_DEFINED
#define SkFontAgruments_DEFINED
#include "SkScalar.h"
#include "SkTypes.h"
/** Represents a set of actual arguments for a font. */
struct SkFontArguments {
struct VariationPosition {
struct Coordinate {
SkFourByteTag axis;
SkScalar value;
};
const Coordinate* coordinates;
int coordinateCount;
};
// deprecated, use VariationCoordinate instead
struct Axis {
SkFourByteTag fTag;
SkScalar fStyleValue;
};
SkFontArguments() : fCollectionIndex(0), fVariationDesignPosition{nullptr, 0} {}
/** Specify the index of the desired font.
*
* Font formats like ttc, dfont, cff, cid, pfr, t42, t1, and fon may actually be indexed
* collections of fonts.
*/
SkFontArguments& setCollectionIndex(int collectionIndex) {
fCollectionIndex = collectionIndex;
return *this;
}
// deprecated, use setVariationDesignPosition instead.
SkFontArguments& setAxes(const Axis* axes, int axisCount) {
fVariationDesignPosition.coordinates =
reinterpret_cast<const VariationPosition::Coordinate*>(axes);
fVariationDesignPosition.coordinateCount = axisCount;
return *this;
}
/** Specify a position in the variation design space.
*
* Any axis not specified will use the default value.
* Any specified axis not actually present in the font will be ignored.
*
* @param position not copied. The value must remain valid for life of SkFontArguments.
*/
SkFontArguments& setVariationDesignPosition(VariationPosition position) {
fVariationDesignPosition.coordinates = position.coordinates;
fVariationDesignPosition.coordinateCount = position.coordinateCount;
return *this;
}
int getCollectionIndex() const {
return fCollectionIndex;
}
// deprecated, use getVariationDesignPosition instead.
const Axis* getAxes(int* axisCount) const {
*axisCount = fVariationDesignPosition.coordinateCount;
return reinterpret_cast<const Axis*>(fVariationDesignPosition.coordinates);
}
VariationPosition getVariationDesignPosition() const {
return fVariationDesignPosition;
}
private:
int fCollectionIndex;
VariationPosition fVariationDesignPosition;
};
#endif

Просмотреть файл

@ -8,7 +8,7 @@
#ifndef SkGraphics_DEFINED
#define SkGraphics_DEFINED
#include "SkTypes.h"
#include "SkRefCnt.h"
class SkData;
class SkImageGenerator;
@ -157,7 +157,8 @@ public:
*/
static void SetTLSFontCacheLimit(size_t bytes);
typedef SkImageGenerator* (*ImageGeneratorFromEncodedFactory)(SkData*);
typedef std::unique_ptr<SkImageGenerator>
(*ImageGeneratorFromEncodedDataFactory)(sk_sp<SkData>);
/**
* To instantiate images from encoded data, first looks at this runtime function-ptr. If it
@ -166,8 +167,8 @@ public:
*
* Returns the previous factory (which could be NULL).
*/
static ImageGeneratorFromEncodedFactory
SetImageGeneratorFromEncodedFactory(ImageGeneratorFromEncodedFactory);
static ImageGeneratorFromEncodedDataFactory
SetImageGeneratorFromEncodedDataFactory(ImageGeneratorFromEncodedDataFactory);
};
class SkAutoGraphics {

Просмотреть файл

@ -0,0 +1,109 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkICC_DEFINED
#define SkICC_DEFINED
#include "SkData.h"
#include "SkRefCnt.h"
struct SkColorSpaceTransferFn;
class SkColorSpace;
class SkData;
class SkMatrix44;
class SK_API SkICC : public SkRefCnt {
public:
/**
* Parse an ICC profile.
*
* Returns nullptr if the data is not a valid ICC profile or if the profile
* input space is not RGB.
*/
static sk_sp<SkICC> Make(const void*, size_t);
/**
* If the gamut can be represented as transformation into XYZ D50, returns
* true and sets the proper values in |toXYZD50|.
*
* If not, returns false. This indicates that the ICC data is too complex
* to isolate a simple gamut transformation.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
/**
* If the transfer function can be represented as coefficients to the standard
* equation, returns true and sets |fn| to the proper values.
*
* If not, returns false. This indicates one of the following:
* (1) The R, G, and B transfer functions are not the same.
* (2) The transfer function is represented as a table that we have not managed
* to match to a standard curve.
* (3) The ICC data is too complex to isolate a single transfer function.
*/
bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const;
/**
* Please do not call this unless isNumericalTransferFn() has been called and it
* fails. SkColorSpaceTransferFn is the preferred representation.
*
* If it is not possible to represent the R, G, and B transfer functions numerically
* and it is still necessary to get the transfer function, this will return the
* transfer functions as three tables (R, G, and B).
*
* If possible, this will return tables of the same length as they were specified in
* the ICC profile. This means that the lengths of the three tables are not
* guaranteed to be the same. If the ICC representation was not a table, the length
* will be chosen arbitrarily.
*
* The lengths of the tables are all guaranteed to be at least 2. Entries in the
* tables are guaranteed to be in [0, 1].
*
* This API may be deleted in favor of a numerical approximation of the raw data.
*
* This function may fail, indicating that the ICC profile does not have transfer
* functions.
*/
struct Channel {
// Byte offset of the start of the table in |fStorage|
size_t fOffset;
int fCount;
};
struct Tables {
Channel fRed;
Channel fGreen;
Channel fBlue;
const float* red() {
return (const float*) (fStorage->bytes() + fRed.fOffset);
}
const float* green() {
return (const float*) (fStorage->bytes() + fGreen.fOffset);
}
const float* blue() {
return (const float*) (fStorage->bytes() + fBlue.fOffset);
}
sk_sp<SkData> fStorage;
};
bool rawTransferFnData(Tables* tables) const;
/**
* Write an ICC profile with transfer function |fn| and gamut |toXYZD50|.
*/
static sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50);
private:
SkICC(sk_sp<SkColorSpace> colorSpace);
sk_sp<SkColorSpace> fColorSpace;
friend class ICCTest;
};
#endif

Просмотреть файл

@ -18,6 +18,7 @@
class SkData;
class SkCanvas;
class SkColorTable;
class SkCrossContextImageData;
class SkImageGenerator;
class SkPaint;
class SkPicture;
@ -73,7 +74,8 @@ public:
*
* If a subset is specified, it must be contained within the generator's bounds.
*/
static sk_sp<SkImage> MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator>,
const SkIRect* subset = nullptr);
/**
* Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
@ -154,10 +156,18 @@ public:
const SkISize nv12Sizes[2], GrSurfaceOrigin,
sk_sp<SkColorSpace> = nullptr);
static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
const SkMatrix*, const SkPaint*);
enum class BitDepth {
kU8,
kF16,
};
static sk_sp<SkImage> MakeTextureFromPixmap(GrContext*, const SkPixmap&, SkBudgeted budgeted);
/**
* Create a new image from the specified picture.
* On creation of the SkImage, snap the SkPicture to a particular BitDepth and SkColorSpace.
*/
static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
const SkMatrix*, const SkPaint*, BitDepth,
sk_sp<SkColorSpace>);
///////////////////////////////////////////////////////////////////////////////////////////////
@ -167,6 +177,21 @@ public:
SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
uint32_t uniqueID() const { return fUniqueID; }
SkAlphaType alphaType() const;
/**
* Returns the color space of the SkImage.
*
* This is the color space that was supplied on creation of the SkImage or a color
* space that was parsed from encoded data. This color space is not guaranteed to be
* renderable. Can return nullptr if the SkImage was created without a color space.
*/
SkColorSpace* colorSpace() const;
sk_sp<SkColorSpace> refColorSpace() const;
/**
* Returns true fi the image will be drawn as a mask, with no intrinsic color of its own.
*/
bool isAlphaOnly() const;
bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
/**
@ -176,11 +201,6 @@ public:
bool readYUV8Planes(const SkISize[3], void* const planes[3], const size_t rowBytes[3],
SkYUVColorSpace) const;
#ifdef SK_SUPPORT_LEGACY_CREATESHADER_PTR
SkShader* newShader(SkShader::TileMode, SkShader::TileMode,
const SkMatrix* localMatrix = nullptr) const;
#endif
sk_sp<SkShader> makeShader(SkShader::TileMode, SkShader::TileMode,
const SkMatrix* localMatrix = nullptr) const;
@ -193,35 +213,6 @@ public:
*/
bool peekPixels(SkPixmap* pixmap) const;
#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS
/**
* If the image has direct access to its pixels (i.e. they are in local
* RAM) return the (const) address of those pixels, and if not null, return
* the ImageInfo and rowBytes. The returned address is only valid while
* the image object is in scope.
*
* On failure, returns NULL and the info and rowBytes parameters are
* ignored.
*
* DEPRECATED -- use the SkPixmap variant instead
*/
const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const;
#endif
/**
* Some images have to perform preliminary work in preparation for drawing. This can be
* decoding, uploading to a GPU, or other tasks. These happen automatically when an image
* is drawn, and often they are cached so that the cost is only paid the first time.
*
* Preroll() can be called before drawing to try to perform this prepatory work ahead of time.
* For images that have no such work, this returns instantly. Others may do some thing to
* prepare their cache and then return.
*
* If the image will drawn to a GPU-backed canvas or surface, pass the associated GrContext.
* If the image will be drawn to any other type of canvas or surface, pass null.
*/
void preroll(GrContext* = nullptr) const;
// DEPRECATED - currently used by Canvas2DLayerBridge in Chromium.
GrTexture* getTexture() const;
@ -234,8 +225,11 @@ public:
* Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the
* GrContext will issue to the backend API any deferred IO operations on the texture before
* returning.
* If 'origin' is supplied it will be filled in with the origin of the content drawn
* into the image.
*/
GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const;
GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin = nullptr) const;
/**
* Hints to image calls where the system might cache computed intermediates (e.g. the results
@ -290,7 +284,7 @@ public:
* Note: this will attempt to encode the image's pixels in the specified format,
* even if the image returns a data from refEncoded(). That data will be ignored.
*/
SkData* encode(SkImageEncoder::Type, int quality) const;
SkData* encode(SkEncodedImageFormat, int quality) const;
/**
* Encode the image and return the result as a caller-managed SkData. This will
@ -331,11 +325,20 @@ public:
sk_sp<SkImage> makeSubset(const SkIRect& subset) const;
/**
* Ensures that an image is backed by a texture (when GrContext is non-null). If no
* transformation is required, the returned image may be the same as this image. If the this
* image is from a different GrContext, this will fail.
* Ensures that an image is backed by a texture (when GrContext is non-null), suitable for use
* with surfaces that have the supplied destination color space. If no transformation is
* required, the returned image may be the same as this image. If this image is from a
* different GrContext, this will fail.
*/
sk_sp<SkImage> makeTextureImage(GrContext*) const;
sk_sp<SkImage> makeTextureImage(GrContext*, SkColorSpace* dstColorSpace) const;
/**
* Constructs a texture backed image from data that was previously uploaded on another thread
* and GrContext. The GrContext used to upload the data must be in the same GL share group as
* the one passed in here, or otherwise be able to share resources with the passed in context.
*/
static sk_sp<SkImage> MakeFromCrossContextImageData(GrContext*,
std::unique_ptr<SkCrossContextImageData>);
/**
* If the image is texture-backed this will make a raster copy of it (or nullptr if reading back
@ -392,13 +395,16 @@ public:
* When buffer is not null this fills in the deferred texture data for this image in the
* provided buffer (assuming this is an appropriate candidate image and the buffer is
* appropriately aligned). Upon success the size written is returned, otherwise 0.
*
* dstColorSpace is the color space of the surface where this texture will ultimately be used.
* If the method determines that mip-maps are needed, this helps determine the correct strategy
* for building them (gamma-correct or not).
*/
size_t getDeferredTextureImageData(const GrContextThreadSafeProxy&,
const DeferredTextureImageUsageParams[],
int paramCnt,
void* buffer,
SkSourceGammaTreatment treatment =
SkSourceGammaTreatment::kIgnore) const;
SkColorSpace* dstColorSpace = nullptr) const;
/**
* Returns a texture-backed image from data produced in SkImage::getDeferredTextureImageData.
@ -431,39 +437,21 @@ public:
*/
bool isLazyGenerated() const;
#ifdef SK_SUPPORT_LEGACY_IMAGEFACTORY
static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes,
SkColorTable* ctable = nullptr);
static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes,
RasterReleaseProc, ReleaseContext);
static SkImage* NewFromBitmap(const SkBitmap&);
static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = nullptr);
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
return NewFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr);
}
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) {
return NewFromTexture(ctx, de, at, nullptr, nullptr);
}
static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
TextureReleaseProc, ReleaseContext);
static SkImage* NewFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
SkAlphaType = kPremul_SkAlphaType);
static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
const GrBackendObject yuvTextureHandles[3],
const SkISize yuvSizes[3],
GrSurfaceOrigin);
static SkImage* NewFromPicture(const SkPicture*, const SkISize& dimensions,
const SkMatrix*, const SkPaint*);
static SkImage* NewTextureFromPixmap(GrContext*, const SkPixmap&, SkBudgeted budgeted);
static SkImage* NewFromDeferredTextureImageData(GrContext*, const void*, SkBudgeted);
SkImage* newSubset(const SkIRect& subset) const { return this->makeSubset(subset).release(); }
SkImage* newTextureImage(GrContext* ctx) const { return this->makeTextureImage(ctx).release(); }
#endif
/**
* If |target| is supported, returns an SkImage in the |target| color space.
* Otherwise, returns nullptr.
*
* This will leave the image as is if it already in the |target| color space.
* Otherwise, it will convert the pixels from the src color space to the |target|
* color space. If this->colorSpace() is nullptr, the src color space will be
* treated as sRGB.
*
* If |premulBehavior| is kIgnore, any premultiplication or unpremultiplication will
* be performed in the gamma encoded space. If it is kRespect, premultiplication is
* assumed to be linear.
*/
sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target,
SkTransferFunctionBehavior premulBehavior) const;
protected:
SkImage(int width, int height, uint32_t uniqueID);
@ -471,7 +459,7 @@ protected:
private:
static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
const GrMipLevel* texels, int mipLevelCount,
SkBudgeted, SkSourceGammaTreatment);
SkBudgeted, SkDestinationSurfaceColorMode);
const int fWidth;
const int fHeight;

Просмотреть файл

@ -8,112 +8,35 @@
#ifndef SkImageEncoder_DEFINED
#define SkImageEncoder_DEFINED
#include "SkImageInfo.h"
#include "SkTRegistry.h"
#include "SkBitmap.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
class SkBitmap;
class SkPixelSerializer;
class SkPixmap;
class SkData;
class SkWStream;
/**
* Encode SkPixmap in the given binary image format.
*
* @param dst results are written to this stream.
* @param src source pixels.
* @param format image format, not all formats are supported.
* @param quality range from 0-100, not all formats respect quality.
*
* @return false iff input is bad or format is unsupported.
*
* Will always return false if Skia is compiled without image
* encoders.
*
* For examples of encoding an image to a file or to a block of memory,
* see tools/sk_tool_utils.h.
*/
SK_API bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
SkEncodedImageFormat format, int quality);
/**
* The following helper function wraps SkEncodeImage().
*/
inline bool SkEncodeImage(SkWStream* dst, const SkBitmap& src, SkEncodedImageFormat f, int q) {
SkAutoLockPixels autoLockPixels(src);
SkPixmap pixmap;
return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q);
}
class SkImageEncoder {
public:
// TODO (scroggo): Merge with SkEncodedFormat.
enum Type {
kUnknown_Type,
kBMP_Type,
kGIF_Type,
kICO_Type,
kJPEG_Type,
kPNG_Type,
kWBMP_Type,
kWEBP_Type,
kKTX_Type,
};
static SkImageEncoder* Create(Type);
virtual ~SkImageEncoder();
/* Quality ranges from 0..100 */
enum {
kDefaultQuality = 80
};
/**
* Encode bitmap 'bm', returning the results in an SkData, at quality level
* 'quality' (which can be in range 0-100). If the bitmap cannot be
* encoded, return null. On success, the caller is responsible for
* calling unref() on the data when they are finished.
*/
SkData* encodeData(const SkBitmap&, int quality);
/**
* Encode bitmap 'bm' in the desired format, writing results to
* file 'file', at quality level 'quality' (which can be in range
* 0-100). Returns false on failure.
*/
bool encodeFile(const char file[], const SkBitmap& bm, int quality);
/**
* Encode bitmap 'bm' in the desired format, writing results to
* stream 'stream', at quality level 'quality' (which can be in
* range 0-100). Returns false on failure.
*/
bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality);
static SkData* EncodeData(const SkImageInfo&, const void* pixels, size_t rowBytes,
Type, int quality);
static SkData* EncodeData(const SkBitmap&, Type, int quality);
static SkData* EncodeData(const SkPixmap&, Type, int quality);
static bool EncodeFile(const char file[], const SkBitmap&, Type,
int quality);
static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
int quality);
/** Uses SkImageEncoder to serialize images that are not already
encoded as SkImageEncoder::kPNG_Type images. */
static SkPixelSerializer* CreatePixelSerializer();
protected:
/**
* Encode bitmap 'bm' in the desired format, writing results to
* stream 'stream', at quality level 'quality' (which can be in
* range 0-100).
*
* This must be overridden by each SkImageEncoder implementation.
*/
virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0;
};
// This macro declares a global (i.e., non-class owned) creation entry point
// for each encoder (e.g., CreateJPEGImageEncoder)
#define DECLARE_ENCODER_CREATOR(codec) \
SK_API SkImageEncoder *Create ## codec ();
// This macro defines the global creation entry point for each encoder. Each
// encoder implementation that registers with the encoder factory must call it.
#define DEFINE_ENCODER_CREATOR(codec) \
SkImageEncoder* Create##codec() { return new Sk##codec; }
// All the encoders known by Skia. Note that, depending on the compiler settings,
// not all of these will be available
DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
DECLARE_ENCODER_CREATOR(PNGImageEncoder);
DECLARE_ENCODER_CREATOR(KTXImageEncoder);
DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type);
#endif
#if defined(SK_BUILD_FOR_WIN)
SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type);
#endif
// Typedef to make registering encoder callback easier
// This has to be defined outside SkImageEncoder. :(
typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg;
#endif
#endif // SkImageEncoder_DEFINED

Просмотреть файл

@ -20,6 +20,7 @@
class GrContext;
class GrFragmentProcessor;
class SkColorFilter;
class SkColorSpaceXformer;
struct SkIPoint;
class SkSpecialImage;
class SkImageFilterCache;
@ -223,12 +224,6 @@ public:
*/
sk_sp<SkImageFilter> makeWithLocalMatrix(const SkMatrix&) const;
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
SkImageFilter* newWithLocalMatrix(const SkMatrix& matrix) const {
return this->makeWithLocalMatrix(matrix).release();
}
#endif
/**
* ImageFilters can natively handle scaling and translate components in the CTM. Only some of
* them can handle affine (or more complex) matrices. This call returns true iff the filter
@ -243,14 +238,6 @@ public:
SkFilterQuality quality,
sk_sp<SkImageFilter> input);
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
static SkImageFilter* CreateMatrixFilter(const SkMatrix& matrix,
SkFilterQuality filterQuality,
SkImageFilter* input = nullptr) {
return MakeMatrixFilter(matrix, filterQuality, sk_ref_sp<SkImageFilter>(input)).release();
}
#endif
SK_TO_STRING_PUREVIRT()
SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
@ -284,7 +271,7 @@ protected:
SkImageFilter(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);
virtual ~SkImageFilter();
~SkImageFilter() override;
/**
* Constructs a new SkImageFilter read from an SkReadBuffer object.
@ -297,6 +284,10 @@ protected:
void flatten(SkWriteBuffer&) const override;
const CropRect* getCropRectIfSet() const {
return this->cropRectIsSet() ? &fCropRect : nullptr;
}
/**
* This is the virtual which should be overridden by the derived class
* to perform image filtering.
@ -400,8 +391,46 @@ protected:
*/
Context mapContext(const Context& ctx) const;
#if SK_SUPPORT_GPU
/**
* Returns a version of the passed-in image (possibly the original), that is in a colorspace
* with the same gamut as the one from the OutputProperties. This allows filters that do many
* texture samples to guarantee that any color space conversion has happened before running.
*/
static sk_sp<SkSpecialImage> ImageToColorSpace(SkSpecialImage* src, const OutputProperties&);
#endif
/**
* Returns an image filter transformed into a new color space via the |xformer|.
*/
sk_sp<SkImageFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
return this->onMakeColorSpace(xformer);
}
virtual sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const {
return sk_ref_sp(const_cast<SkImageFilter*>(this));
}
private:
// For makeColorSpace().
friend class ArithmeticImageFilterImpl;
friend class SkAlphaThresholdFilterImpl;
friend class SkBlurImageFilterImpl;
friend class SkColorFilterImageFilter;
friend class SkColorSpaceXformer;
friend class SkComposeImageFilter;
friend class SkDisplacementMapEffect;
friend class SkDropShadowImageFilter;
friend class SkImageSource;
friend class SkMagnifierImageFilter;
friend class SkMatrixConvolutionImageFilter;
friend class SkMergeImageFilter;
friend class SkMorphologyImageFilter;
friend class SkOffsetImageFilter;
friend class SkTileImageFilter;
friend class SkXfermodeImageFilter_Base;
friend class SkGraphics;
static void PurgeCache();
void init(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);

Просмотреть файл

@ -10,55 +10,20 @@
#include "SkBitmap.h"
#include "SkColor.h"
#include "SkImage.h"
#include "SkImageInfo.h"
#include "SkYUVSizeInfo.h"
class GrContext;
class GrTexture;
class GrTextureParams;
class GrContextThreadSafeProxy;
class GrTextureProxy;
class GrSamplerParams;
class SkBitmap;
class SkData;
class SkImageGenerator;
class SkMatrix;
class SkPaint;
class SkPicture;
#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX
#define SK_REFENCODEDDATA_CTXPARAM
#else
#define SK_REFENCODEDDATA_CTXPARAM GrContext* ctx
#endif
/**
* Takes ownership of SkImageGenerator. If this method fails for
* whatever reason, it will return false and immediatetely delete
* the generator. If it succeeds, it will modify destination
* bitmap.
*
* If generator is NULL, will safely return false.
*
* If this fails or when the SkDiscardablePixelRef that is
* installed into destination is destroyed, it will
* delete the generator. Therefore, generator should be
* allocated with new.
*
* @param destination Upon success, this bitmap will be
* configured and have a pixelref installed.
*
* @return true iff successful.
*/
SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
/**
* On success, installs a discardable pixelref into destination, based on encoded data.
* Regardless of success or failure, the caller must still balance their ownership of encoded.
*/
SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkData* encoded, SkBitmap* destination);
/**
* An interface that allows a purgeable PixelRef (such as a
* SkDiscardablePixelRef) to decode and re-decode an image as needed.
*/
class SK_API SkImageGenerator : public SkNoncopyable {
public:
/**
@ -79,11 +44,7 @@ public:
* unref() on the data when it is finished.
*/
SkData* refEncodedData(GrContext* ctx = nullptr) {
#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX
return this->onRefEncodedData();
#else
return this->onRefEncodedData(ctx);
#endif
}
/**
@ -151,104 +112,49 @@ public:
*/
bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]);
#if SK_SUPPORT_GPU
/**
* If the generator can natively/efficiently return its pixels as a GPU image (backed by a
* texture) this will return that image. If not, this will return NULL.
*
* Regarding the GrContext parameter:
* This routine also supports retrieving only a subset of the pixels. That subset is specified
* by the following rectangle:
*
* The caller may pass NULL for the context. In that case the generator may assume that its
* internal context is current. If it has no internal context, then it should just return
* null.
* subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
*
* If the caller passes a non-null context, then the generator should only succeed if:
* - it has no intrinsic context, and will use the caller's
* - its internal context is the same
* - it can somehow convert its texture into one that is valid for the provided context.
* If subset is not contained inside the generator's bounds, this returns false.
*
* Regarding the GrTextureParams parameter:
*
* If the context (the provided one or the generator's intrinsic one) determines that to
* support the specified usage, it must return a different sized texture it may,
* so the caller must inspect the texture's width/height and compare them to the generator's
* getInfo() width/height. For readback usage use GrTextureParams::ClampNoFilter()
*/
GrTexture* generateTexture(GrContext*, const SkIRect* subset = nullptr);
struct SupportedSizes {
SkISize fSizes[2];
};
/**
* Some generators can efficiently scale their contents. If this is supported, the generator
* may only support certain scaled dimensions. Call this with the desired scale factor,
* and it will return true if scaling is supported, and in supportedSizes[] it will return
* the nearest supported dimensions.
*
* If no native scaling is supported, or scale is invalid (e.g. scale <= 0 || scale > 1)
* this will return false, and the supportedsizes will be undefined.
*/
bool computeScaledDimensions(SkScalar scale, SupportedSizes*);
/**
* Scale the generator's pixels to fit into scaledSize.
* This routine also support retrieving only a subset of the pixels. That subset is specified
* by the following rectangle (in the scaled space):
*
* subset = SkIRect::MakeXYWH(subsetOrigin.x(), subsetOrigin.y(),
* subsetPixels.width(), subsetPixels.height())
*
* If subset is not contained inside the scaledSize, this returns false.
*
* whole = SkIRect::MakeWH(scaledSize.width(), scaledSize.height())
* whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
* if (!whole.contains(subset)) {
* return false;
* }
*
* If the requested colortype/alphatype in pixels is not supported,
* or the requested scaledSize is not supported, or the generator encounters an error,
* this returns false.
* Regarding the GrContext parameter:
*
* It must be non-NULL. The generator should only succeed if:
* - its internal context is the same
* - it can somehow convert its texture into one that is valid for the provided context.
*/
bool generateScaledPixels(const SkISize& scaledSize, const SkIPoint& subsetOrigin,
const SkPixmap& subsetPixels);
bool generateScaledPixels(const SkPixmap& scaledPixels) {
return this->generateScaledPixels(SkISize::Make(scaledPixels.width(),
scaledPixels.height()),
SkIPoint::Make(0, 0), scaledPixels);
}
sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
const SkIPoint& origin);
#endif
/**
* If the default image decoder system can interpret the specified (encoded) data, then
* this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
* the caller is still responsible for managing their ownership of the data.
*/
static SkImageGenerator* NewFromEncoded(SkData*);
static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
/** Return a new image generator backed by the specified picture. If the size is empty or
* the picture is NULL, this returns NULL.
* The optional matrix and paint arguments are passed to drawPicture() at rasterization
* time.
*/
static SkImageGenerator* NewFromPicture(const SkISize&, const SkPicture*, const SkMatrix*,
const SkPaint*);
bool tryGenerateBitmap(SkBitmap* bm) {
return this->tryGenerateBitmap(bm, nullptr, nullptr);
}
bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator) {
return this->tryGenerateBitmap(bm, &info, allocator);
}
void generateBitmap(SkBitmap* bm) {
if (!this->tryGenerateBitmap(bm, nullptr, nullptr)) {
sk_throw();
}
}
void generateBitmap(SkBitmap* bm, const SkImageInfo& info) {
if (!this->tryGenerateBitmap(bm, &info, nullptr)) {
sk_throw();
}
}
static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
const SkMatrix*, const SkPaint*,
SkImage::BitDepth,
sk_sp<SkColorSpace>);
protected:
enum {
@ -257,7 +163,7 @@ protected:
SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
virtual SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM);
virtual SkData* onRefEncodedData(GrContext* ctx);
virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
SkPMColor ctable[], int* ctableCount);
@ -269,27 +175,38 @@ protected:
return false;
}
virtual GrTexture* onGenerateTexture(GrContext*, const SkIRect*) {
return nullptr;
struct Options {
Options()
: fColorTable(nullptr)
, fColorTableCount(nullptr)
, fBehavior(SkTransferFunctionBehavior::kRespect)
{}
SkPMColor* fColorTable;
int* fColorTableCount;
SkTransferFunctionBehavior fBehavior;
};
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts);
virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const Options& opts) {
return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
}
virtual bool onComputeScaledDimensions(SkScalar, SupportedSizes*) {
return false;
}
virtual bool onGenerateScaledPixels(const SkISize&, const SkIPoint&, const SkPixmap&) {
return false;
}
bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo* optionalInfo, SkBitmap::Allocator*);
#if SK_SUPPORT_GPU
virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
const SkIPoint&);
#endif
private:
const SkImageInfo fInfo;
const uint32_t fUniqueID;
friend class SkImageCacherator;
// This is our default impl, which may be different on different platforms.
// It is called from NewFromEncoded() after it has checked for any runtime factory.
// The SkData will never be NULL, as that will have been checked by NewFromEncoded.
static SkImageGenerator* NewFromEncodedImpl(SkData*);
static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
};
#endif // SkImageGenerator_DEFINED

Просмотреть файл

@ -169,9 +169,9 @@ enum SkYUVColorSpace {
///////////////////////////////////////////////////////////////////////////////
enum class SkSourceGammaTreatment {
kRespect,
kIgnore,
enum class SkDestinationSurfaceColorMode {
kLegacy,
kGammaAndColorSpaceAware,
};
/**
@ -234,6 +234,7 @@ public:
SkColorType colorType() const { return fColorType; }
SkAlphaType alphaType() const { return fAlphaType; }
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
@ -277,7 +278,11 @@ public:
}
size_t minRowBytes() const {
return (size_t)this->minRowBytes64();
uint64_t minRowBytes = this->minRowBytes64();
if (!sk_64_isS32(minRowBytes)) {
return 0;
}
return sk_64_asS32(minRowBytes);
}
size_t computeOffset(int x, int y, size_t rowBytes) const {
@ -302,7 +307,7 @@ public:
if (0 == fHeight) {
return 0;
}
return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
return sk_64_mul(fHeight - 1, rowBytes) + sk_64_mul(fWidth, this->bytesPerPixel());
}
size_t getSafeSize(size_t rowBytes) const {
@ -344,16 +349,4 @@ private:
{}
};
///////////////////////////////////////////////////////////////////////////////
static inline bool SkColorAndColorSpaceAreGammaCorrect(SkColorType ct, SkColorSpace* cs) {
// Anything with a color-space attached is gamma-correct, as is F16.
// To get legacy behavior, you need to ask for non-F16, with a nullptr color space.
return (cs != nullptr) || kRGBA_F16_SkColorType == ct;
}
static inline bool SkImageInfoIsGammaCorrect(const SkImageInfo& info) {
return SkColorAndColorSpaceAreGammaCorrect(info.colorType(), info.colorSpace());
}
#endif

Просмотреть файл

@ -10,12 +10,12 @@
#define SkLights_DEFINED
#include "../private/SkTArray.h"
#include "SkImage.h"
#include "SkPoint3.h"
#include "SkRefCnt.h"
class SkReadBuffer;
class SkWriteBuffer;
class SkImage;
class SK_API SkLights : public SkRefCnt {
public:

Просмотреть файл

@ -22,12 +22,10 @@ public:
* lifetime of the pixel storage buffer, as this pixelref will not try
* to delete it.
*
* The pixelref will ref() the colortable (if not NULL).
*
* Returns NULL on failure.
*/
static SkMallocPixelRef* NewDirect(const SkImageInfo&, void* addr,
size_t rowBytes, SkColorTable*);
static sk_sp<SkPixelRef> MakeDirect(const SkImageInfo&, void* addr,
size_t rowBytes, sk_sp<SkColorTable>);
/**
* Return a new SkMallocPixelRef, automatically allocating storage for the
@ -39,22 +37,18 @@ public:
*
* Returns NULL on failure.
*/
static SkMallocPixelRef* NewAllocate(const SkImageInfo& info,
size_t rowBytes, SkColorTable*);
static sk_sp<SkPixelRef> MakeAllocate(const SkImageInfo&, size_t rowBytes, sk_sp<SkColorTable>);
/**
* Identical to NewAllocate, except all pixel bytes are zeroed.
* Identical to MakeAllocate, except all pixel bytes are zeroed.
*/
static SkMallocPixelRef* NewZeroed(const SkImageInfo& info,
size_t rowBytes, SkColorTable*);
static sk_sp<SkPixelRef> MakeZeroed(const SkImageInfo&, size_t rowBytes, sk_sp<SkColorTable>);
/**
* Return a new SkMallocPixelRef with the provided pixel storage,
* rowBytes, and optional colortable. On destruction, ReleaseProc
* will be called.
*
* This pixelref will ref() the specified colortable (if not NULL).
*
* If ReleaseProc is NULL, the pixels will never be released. This
* can be useful if the pixels were stack allocated. However, such an
* SkMallocPixelRef must not live beyond its pixels (e.g. by copying
@ -63,10 +57,10 @@ public:
* Returns NULL on failure.
*/
typedef void (*ReleaseProc)(void* addr, void* context);
static SkMallocPixelRef* NewWithProc(const SkImageInfo& info,
size_t rowBytes, SkColorTable*,
void* addr, ReleaseProc proc,
void* context);
static sk_sp<SkPixelRef> MakeWithProc(const SkImageInfo& info,
size_t rowBytes, sk_sp<SkColorTable>,
void* addr, ReleaseProc proc,
void* context);
/**
* Return a new SkMallocPixelRef that will use the provided
@ -74,51 +68,56 @@ public:
* The SkData will be ref()ed and on destruction of the PielRef,
* the SkData will be unref()ed.
*
* This pixelref will ref() the specified colortable (if not NULL).
*
* Returns NULL on failure.
*/
static sk_sp<SkPixelRef> MakeWithData(const SkImageInfo& info,
size_t rowBytes,
sk_sp<SkColorTable>,
sk_sp<SkData> data);
#ifdef SK_SUPPORT_LEGACY_PIXELREFFACTORY
static SkMallocPixelRef* NewDirect(const SkImageInfo& info, void* addr,
size_t rowBytes, SkColorTable* ctable) {
return (SkMallocPixelRef*)MakeDirect(info, addr, rowBytes, sk_ref_sp(ctable)).release();
}
static SkMallocPixelRef* NewAllocate(const SkImageInfo& info, size_t rb, SkColorTable* ct) {
return (SkMallocPixelRef*)MakeAllocate(info, rb, sk_ref_sp(ct)).release();
}
static SkMallocPixelRef* NewZeroed(const SkImageInfo& info, size_t rowBytes, SkColorTable* ct) {
return (SkMallocPixelRef*)MakeZeroed(info, rowBytes, sk_ref_sp(ct)).release();
}
static SkMallocPixelRef* NewWithProc(const SkImageInfo& info,
size_t rowBytes, SkColorTable* ctable,
void* addr, ReleaseProc proc,
void* ctx) {
return (SkMallocPixelRef*)MakeWithProc(info, rowBytes, sk_ref_sp(ctable), addr, proc, ctx).release();
}
static SkMallocPixelRef* NewWithData(const SkImageInfo& info,
size_t rowBytes,
SkColorTable* ctable,
SkData* data);
void* getAddr() const { return fStorage; }
class PRFactory : public SkPixelRefFactory {
public:
SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override;
};
class ZeroedPRFactory : public SkPixelRefFactory {
public:
SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override;
};
#endif
protected:
// The ownPixels version of this constructor is deprecated.
SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
bool ownPixels);
virtual ~SkMallocPixelRef();
~SkMallocPixelRef() override;
#ifdef SK_SUPPORT_LEGACY_NO_ADDR_PIXELREF
bool onNewLockPixels(LockRec*) override;
void onUnlockPixels() override;
#endif
size_t getAllocatedSizeInBytes() const override;
private:
// Uses alloc to implement NewAllocate or NewZeroed.
static SkMallocPixelRef* NewUsing(void*(*alloc)(size_t),
const SkImageInfo&,
size_t rowBytes,
SkColorTable*);
static sk_sp<SkPixelRef> MakeUsing(void*(*alloc)(size_t),
const SkImageInfo&,
size_t rowBytes,
sk_sp<SkColorTable>);
void* fStorage;
SkColorTable* fCTable;
size_t fRB;
ReleaseProc fReleaseProc;
void* fReleaseProcContext;
ReleaseProc fReleaseProc;
void* fReleaseProcContext;
SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, sk_sp<SkColorTable>,
ReleaseProc proc, void* context);
typedef SkPixelRef INHERITED;

Просмотреть файл

@ -18,10 +18,13 @@
class GrClip;
class GrContext;
class GrDrawContext;
class GrRenderTargetContext;
class GrPaint;
class GrFragmentProcessor;
class GrRenderTarget;
class GrTextureProvider;
class GrResourceProvider;
class GrTexture;
class GrTextureProxy;
class SkBitmap;
class SkBlitter;
class SkCachedData;
@ -109,23 +112,23 @@ public:
SkRect* maskRect) const;
/**
* Try to directly render the mask filter into the target. Returns
* true if drawing was successful.
* Try to directly render the mask filter into the target. Returns true if drawing was
* successful. If false is returned then paint is unmodified.
*/
virtual bool directFilterMaskGPU(GrTextureProvider* texProvider,
GrDrawContext* drawContext,
GrPaint* grp,
virtual bool directFilterMaskGPU(GrContext*,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
const GrClip&,
const SkMatrix& viewMatrix,
const SkStrokeRec& strokeRec,
const SkPath& path) const;
/**
* Try to directly render a rounded rect mask filter into the target. Returns
* true if drawing was successful.
* true if drawing was successful. If false is returned then paint is unmodified.
*/
virtual bool directFilterRRectMaskGPU(GrContext*,
GrDrawContext* drawContext,
GrPaint* grp,
GrRenderTargetContext* renderTargetContext,
GrPaint&& paint,
const GrClip&,
const SkMatrix& viewMatrix,
const SkStrokeRec& strokeRec,
@ -139,10 +142,10 @@ public:
* Implementations are free to get the GrContext from the src texture in order to create
* additional textures and perform multiple passes.
*/
virtual bool filterMaskGPU(GrTexture* src,
const SkMatrix& ctm,
const SkIRect& maskRect,
GrTexture** result) const;
virtual sk_sp<GrTextureProxy> filterMaskGPU(GrContext*,
sk_sp<GrTextureProxy> srcProxy,
const SkMatrix& ctm,
const SkIRect& maskRect) const;
#endif
/**

Просмотреть файл

@ -21,6 +21,8 @@ class SkString;
SkMatrix does not have a constructor, so it must be explicitly initialized
using either reset() - to construct an identity matrix, or one of the set
functions (e.g. setTranslate, setRotate, etc.).
SkMatrix is not thread safe unless you've first called SkMatrix::getType().
*/
SK_BEGIN_REQUIRE_DENSE
class SK_API SkMatrix {
@ -461,8 +463,7 @@ public:
/** Like mapPoints but with custom byte stride between the points.
*/
void mapPointsWithStride(SkPoint dst[], SkPoint src[],
size_t stride, int count) const {
void mapPointsWithStride(SkPoint dst[], const SkPoint src[], size_t stride, int count) const {
SkASSERT(stride >= sizeof(SkPoint));
SkASSERT(0 == stride % sizeof(SkScalar));
for (int i = 0; i < count; ++i) {
@ -815,6 +816,14 @@ private:
return ((fTypeMask & 0xF) == 0);
}
inline void updateTranslateMask() {
if ((fMat[kMTransX] != 0) | (fMat[kMTransY] != 0)) {
fTypeMask |= kTranslate_Mask;
} else {
fTypeMask &= ~kTranslate_Mask;
}
}
bool SK_WARN_UNUSED_RESULT invertNonIdentity(SkMatrix* inverse) const;
static bool Poly2Proc(const SkPoint[], SkMatrix*, const SkPoint& scale);

Просмотреть файл

@ -126,6 +126,12 @@ struct SkVector4 {
}
};
/** \class SkMatrix44
The SkMatrix44 class holds a 4x4 matrix.
SkMatrix44 is not thread safe unless you've first called SkMatrix44::getType().
*/
class SK_API SkMatrix44 {
public:
@ -491,7 +497,10 @@ private:
return 0 == fTypeMask;
}
inline const SkMScalar* values() const { return &fMat[0][0]; }
friend class SkColorSpace;
friend class SkColorSpace_XYZ;
};
#endif

Просмотреть файл

@ -5,5 +5,5 @@
* found in the LICENSE file.
*/
#ifndef SK_MILESTONE
#define SK_MILESTONE 55
#define SK_MILESTONE 59
#endif

Просмотреть файл

@ -57,7 +57,7 @@ public:
private:
struct DrawData {
SkCanvas* fCanvas; // reffed
SkCanvas* fCanvas;
const SkPicture* fPicture; // reffed
SkMatrix fMatrix;
SkPaint* fPaint; // owned

Просмотреть файл

@ -12,9 +12,7 @@
#include "SkColor.h"
#include "SkFilterQuality.h"
#include "SkMatrix.h"
#include "SkXfermode.h"
//#define SK_SUPPORT_LEGACY_XFERMODE_OBJECT
#include "SkRefCnt.h"
class SkAutoDescriptor;
class SkAutoGlyphCache;
@ -39,8 +37,6 @@ class SkSurfaceProps;
class SkTextBlob;
class SkTypeface;
#define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag
/** \class SkPaint
The SkPaint class holds the style and color information about how to draw
@ -105,8 +101,6 @@ public:
enum Flags {
kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
kDither_Flag = 0x04, //!< mask to enable dithering
kUnderlineText_Flag = 0x08, //!< mask to enable underline text
kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
kLinearText_Flag = 0x40, //!< mask to enable linear-text
kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
@ -119,9 +113,18 @@ public:
// when adding extra flags, note that the fFlags member is specified
// with a bit-width and you'll have to expand it.
kAllFlags = 0xFFFF
kAllFlags = 0xFFFF,
};
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
enum ReserveFlags {
// These are not used by paint, but the bits are reserved for private use by the
// android framework.
kUnderlineText_ReserveFlag = 0x08, //!< mask to enable underline text
kStrikeThruText_ReserveFlag = 0x10, //!< mask to enable strike-thru text
};
#endif
/** Return the paint's flags. Use the Flag enum to test flag values.
@return the paint's flags (see enums ending in _Flag for bit masks)
*/
@ -230,32 +233,6 @@ public:
*/
void setVerticalText(bool);
/** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
@return true if the underlineText bit is set in the paint's flags.
*/
bool isUnderlineText() const {
return SkToBool(this->getFlags() & kUnderlineText_Flag);
}
/** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
@param underlineText true to set the underlineText bit in the paint's
flags, false to clear it.
*/
void setUnderlineText(bool underlineText);
/** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
@return true if the strikeThruText bit is set in the paint's flags.
*/
bool isStrikeThruText() const {
return SkToBool(this->getFlags() & kStrikeThruText_Flag);
}
/** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
@param strikeThruText true to set the strikeThruText bit in the
paint's flags, false to clear it.
*/
void setStrikeThruText(bool strikeThruText);
/** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
@return true if the kFakeBoldText_Flag bit is set in the paint's flags.
*/
@ -483,6 +460,7 @@ public:
@return the paint's shader (or NULL)
*/
SkShader* getShader() const { return fShader.get(); }
sk_sp<SkShader> refShader() const;
/** Set or clear the shader object.
* Shaders specify the source color(s) for what is being drawn. If a paint
@ -503,61 +481,24 @@ public:
* If a previous shader exists, its reference count is decremented.
* If shader is not NULL, its reference count is incremented.
* @param shader May be NULL. The shader to be installed in the paint
* @return shader
*/
void setShader(sk_sp<SkShader>);
#ifdef SK_SUPPORT_LEGACY_CREATESHADER_PTR
SkShader* setShader(SkShader* shader);
#endif
/** Get the paint's colorfilter. If there is a colorfilter, its reference
count is not changed.
@return the paint's colorfilter (or NULL)
*/
SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
sk_sp<SkColorFilter> refColorFilter() const;
/** Set or clear the paint's colorfilter, returning the parameter.
/** Set or clear the paint's colorfilter.
<p />
If the paint already has a filter, its reference count is decremented.
If filter is not NULL, its reference count is incremented.
@param filter May be NULL. The filter to be installed in the paint
@return filter
*/
#ifdef SK_SUPPORT_LEGACY_COLORFILTER_PTR
SkColorFilter* setColorFilter(SkColorFilter* filter);
#endif
void setColorFilter(sk_sp<SkColorFilter>);
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
/** Get the paint's xfermode object.
<p />
The xfermode's reference count is not affected.
@return the paint's xfermode (or NULL)
*/
SkXfermode* getXfermode() const;
/** Set or clear the xfermode object.
<p />
Pass NULL to clear any previous xfermode.
As a convenience, the parameter passed is also returned.
If a previous xfermode exists, its reference count is decremented.
If xfermode is not NULL, its reference count is incremented.
@param xfermode May be NULL. The new xfermode to be installed in the
paint
@return xfermode
*/
void setXfermode(sk_sp<SkXfermode>);
#ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
SkXfermode* setXfermode(SkXfermode* xfermode);
#endif
/** Create an xfermode based on the specified Mode, and assign it into the
paint, returning the mode that was set. If the Mode is SrcOver, then
the paint's xfermode is set to null.
*/
SkXfermode* setXfermodeMode(SkXfermode::Mode);
#endif
SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }
bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }
void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }
@ -568,6 +509,7 @@ public:
@return the paint's patheffect (or NULL)
*/
SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
sk_sp<SkPathEffect> refPathEffect() const;
/** Set or clear the patheffect object.
<p />
@ -580,9 +522,6 @@ public:
@return effect
*/
void setPathEffect(sk_sp<SkPathEffect>);
#ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
SkPathEffect* setPathEffect(SkPathEffect* effect);
#endif
/** Get the paint's maskfilter object.
<p />
@ -590,6 +529,7 @@ public:
@return the paint's maskfilter (or NULL)
*/
SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
sk_sp<SkMaskFilter> refMaskFilter() const;
/** Set or clear the maskfilter object.
<p />
@ -601,9 +541,6 @@ public:
the paint
@return maskfilter
*/
#ifdef SK_SUPPORT_LEGACY_MASKFILTER_PTR
SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
#endif
void setMaskFilter(sk_sp<SkMaskFilter>);
// These attributes are for text/fonts
@ -615,6 +552,7 @@ public:
@return the paint's typeface (or NULL)
*/
SkTypeface* getTypeface() const { return fTypeface.get(); }
sk_sp<SkTypeface> refTypeface() const;
/** Set or clear the typeface object.
<p />
@ -627,9 +565,6 @@ public:
@return typeface
*/
void setTypeface(sk_sp<SkTypeface>);
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
SkTypeface* setTypeface(SkTypeface* typeface);
#endif
/** Get the paint's rasterizer (or NULL).
<p />
@ -637,6 +572,7 @@ public:
@return the paint's rasterizer (or NULL)
*/
SkRasterizer* getRasterizer() const { return fRasterizer.get(); }
sk_sp<SkRasterizer> refRasterizer() const;
/** Set or clear the rasterizer object.
<p />
@ -649,13 +585,10 @@ public:
the paint.
@return rasterizer
*/
#ifdef SK_SUPPORT_LEGACY_MINOR_EFFECT_PTR
SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
#endif
void setRasterizer(sk_sp<SkRasterizer>);
SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
SkImageFilter* setImageFilter(SkImageFilter*);
sk_sp<SkImageFilter> refImageFilter() const;
void setImageFilter(sk_sp<SkImageFilter>);
/**
@ -663,6 +596,8 @@ public:
* reference count.
*/
SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }
sk_sp<SkDrawLooper> refDrawLooper() const;
SkDrawLooper* getLooper() const { return fDrawLooper.get(); }
/**
* Set or clear the looper object.
@ -674,9 +609,7 @@ public:
* @param looper May be NULL. The new looper to be installed in the paint.
*/
void setDrawLooper(sk_sp<SkDrawLooper>);
#ifdef SK_SUPPORT_LEGACY_MINOR_EFFECT_PTR
SkDrawLooper* setLooper(SkDrawLooper* looper);
#endif
void setLooper(sk_sp<SkDrawLooper>);
enum Align {
@ -755,7 +688,7 @@ public:
A set flag indicates that the metric may be trusted.
*/
enum FontMetricsFlags {
kUnderlineThinknessIsValid_Flag = 1 << 0,
kUnderlineThicknessIsValid_Flag = 1 << 0,
kUnderlinePositionIsValid_Flag = 1 << 1,
};
@ -781,21 +714,21 @@ public:
*/
SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined
/** If the fontmetrics has a valid underlinethickness, return true, and set the
/** If the fontmetrics has a valid underline thickness, return true, and set the
thickness param to that value. If it doesn't return false and ignore the
thickness param.
*/
bool hasUnderlineThickness(SkScalar* thickness) const {
if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) {
if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
*thickness = fUnderlineThickness;
return true;
}
return false;
}
/** If the fontmetrics has a valid underlineposition, return true, and set the
thickness param to that value. If it doesn't return false and ignore the
thickness param.
/** If the fontmetrics has a valid underline position, return true, and set the
position param to that value. If it doesn't return false and ignore the
position param.
*/
bool hasUnderlinePosition(SkScalar* position) const {
if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
@ -1111,7 +1044,7 @@ private:
SkColor fColor;
SkScalar fWidth;
SkScalar fMiterLimit;
uint32_t fBlendMode; // just need 5-6 bits for SkXfermode::Mode
uint32_t fBlendMode; // just need 5-6 bits
union {
struct {
// all of these bitfields should add up to 32

Просмотреть файл

@ -23,6 +23,8 @@ class SkWStream;
The SkPath class encapsulates compound (multiple contour) geometric paths
consisting of straight line segments, quadratic curves, and cubic curves.
SkPath is not thread safe unless you've first called SkPath::updateBoundsCache().
*/
class SK_API SkPath {
public:
@ -357,6 +359,19 @@ public:
this->getBounds();
}
/**
* Computes a bounds that is conservatively "snug" around the path. This assumes that the
* path will be filled. It does not attempt to collapse away contours that are logically
* empty (e.g. moveTo(x, y) + lineTo(x, y)) but will include them in the calculation.
*
* It differs from getBounds() in that it will look at the snug bounds of curves, whereas
* getBounds() just returns the bounds of the control-points. Thus computing this may be
* slower than just calling getBounds().
*
* If the path is empty (i.e. no points or verbs), it will return SkRect::MakeEmpty().
*/
SkRect computeTightBounds() const;
/**
* Does a conservative test to see whether a rectangle is inside a path. Currently it only
* will ever return true for single convex contour paths. The empty-status of the rect is not
@ -1121,12 +1136,12 @@ private:
kCurrent_Version = 2
};
SkAutoTUnref<SkPathRef> fPathRef;
sk_sp<SkPathRef> fPathRef;
int fLastMoveToIndex;
uint8_t fFillType;
mutable uint8_t fConvexity;
mutable SkAtomic<uint8_t, sk_memory_order_relaxed> fFirstDirection;// SkPathPriv::FirstDirection
mutable SkBool8 fIsVolatile;
SkBool8 fIsVolatile;
/** Resets all fields other than fPathRef to their initial 'empty' values.
* Assumes the caller has already emptied fPathRef.
@ -1190,6 +1205,8 @@ private:
friend class SkAutoPathBoundsUpdate;
friend class SkAutoDisableOvalCheck;
friend class SkAutoDisableDirectionCheck;
friend class SkPathWriter;
friend class SkOpBuilder;
friend class SkBench_AddPathTest; // perf test reversePathTo
friend class PathTest_Private; // unit test reversePathTo
friend class ForceIsRRect_Private; // unit test isRRect

Просмотреть файл

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkPathEffect_DEFINED
#define SkPathEffect_DEFINED
@ -28,6 +26,23 @@ class SkStrokeRec;
*/
class SK_API SkPathEffect : public SkFlattenable {
public:
/**
* Returns a patheffect that apples each effect (first and second) to the original path,
* and returns a path with the sum of these.
*
* result = first(path) + second(path)
*
*/
static sk_sp<SkPathEffect> MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second);
/**
* Returns a patheffect that applies the inner effect to the path, and then applies the
* outer effect to the result of the inner's.
*
* result = outer(inner(path))
*/
static sk_sp<SkPathEffect> MakeCompose(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner);
/**
* Given a src path (input) and a stroke-rec (input and output), apply
* this effect to the src path, returning the new path in dst, and return
@ -138,6 +153,8 @@ public:
virtual bool exposedInAndroidJavaAPI() const { return false; }
#endif
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
protected:
SkPathEffect() {}
@ -149,125 +166,4 @@ private:
typedef SkFlattenable INHERITED;
};
/** \class SkPairPathEffect
Common baseclass for Compose and Sum. This subclass manages two pathEffects,
including flattening them. It does nothing in filterPath, and is only useful
for managing the lifetimes of its two arguments.
*/
class SK_API SkPairPathEffect : public SkPathEffect {
protected:
SkPairPathEffect(sk_sp<SkPathEffect> pe0, sk_sp<SkPathEffect> pe1);
void flatten(SkWriteBuffer&) const override;
// these are visible to our subclasses
sk_sp<SkPathEffect> fPE0;
sk_sp<SkPathEffect> fPE1;
SK_TO_STRING_OVERRIDE()
private:
typedef SkPathEffect INHERITED;
};
/** \class SkComposePathEffect
This subclass of SkPathEffect composes its two arguments, to create
a compound pathEffect.
*/
class SK_API SkComposePathEffect : public SkPairPathEffect {
public:
/** Construct a pathEffect whose effect is to apply first the inner pathEffect
and the the outer pathEffect (e.g. outer(inner(path)))
The reference counts for outer and inner are both incremented in the constructor,
and decremented in the destructor.
*/
static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner) {
if (!outer) {
return inner;
}
if (!inner) {
return outer;
}
return sk_sp<SkPathEffect>(new SkComposePathEffect(outer, inner));
}
#ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
static SkPathEffect* Create(SkPathEffect* outer, SkPathEffect* inner) {
return Make(sk_ref_sp(outer), sk_ref_sp(inner)).release();
}
#endif
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
bool exposedInAndroidJavaAPI() const override { return true; }
#endif
protected:
SkComposePathEffect(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner)
: INHERITED(outer, inner) {}
private:
// illegal
SkComposePathEffect(const SkComposePathEffect&);
SkComposePathEffect& operator=(const SkComposePathEffect&);
typedef SkPairPathEffect INHERITED;
};
/** \class SkSumPathEffect
This subclass of SkPathEffect applies two pathEffects, one after the other.
Its filterPath() returns true if either of the effects succeeded.
*/
class SK_API SkSumPathEffect : public SkPairPathEffect {
public:
/** Construct a pathEffect whose effect is to apply two effects, in sequence.
(e.g. first(path) + second(path))
The reference counts for first and second are both incremented in the constructor,
and decremented in the destructor.
*/
static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
if (!first) {
return second;
}
if (!second) {
return first;
}
return sk_sp<SkPathEffect>(new SkSumPathEffect(first, second));
}
#ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
static SkPathEffect* Create(SkPathEffect* first, SkPathEffect* second) {
return Make(sk_ref_sp(first), sk_ref_sp(second)).release();
}
#endif
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
bool exposedInAndroidJavaAPI() const override { return true; }
#endif
protected:
SkSumPathEffect(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second)
: INHERITED(first, second) {}
private:
// illegal
SkSumPathEffect(const SkSumPathEffect&);
SkSumPathEffect& operator=(const SkSumPathEffect&);
typedef SkPairPathEffect INHERITED;
};
#endif

Просмотреть файл

@ -26,8 +26,8 @@ class SkWBuffer;
* modify the contents. To modify or append to the verbs/points wrap the SkPathRef in an
* SkPathRef::Editor object. Installing the editor resets the generation ID. It also performs
* copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller passes the Editor's
* constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef after the editor's
* constructor returns.
* constructor a pointer to a sk_sp<SkPathRef>, which may be updated to point to a new SkPathRef
* after the editor's constructor returns.
*
* The points and verbs are stored in a single allocation. The points are at the begining of the
* allocation while the verbs are stored at end of the allocation, in reverse order. Thus the points
@ -40,7 +40,7 @@ class SK_API SkPathRef final : public SkNVRefCnt<SkPathRef> {
public:
class Editor {
public:
Editor(SkAutoTUnref<SkPathRef>* pathRef,
Editor(sk_sp<SkPathRef>* pathRef,
int incReserveVerbs = 0,
int incReservePoints = 0);
@ -230,7 +230,7 @@ public:
/**
* Transforms a path ref by a matrix, allocating a new one only if necessary.
*/
static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst,
static void CreateTransformedCopy(sk_sp<SkPathRef>* dst,
const SkPathRef& src,
const SkMatrix& matrix);
@ -241,7 +241,7 @@ public:
* repopulated with approximately the same number of verbs and points. A new path ref is created
* only if necessary.
*/
static void Rewind(SkAutoTUnref<SkPathRef>* pathRef);
static void Rewind(sk_sp<SkPathRef>* pathRef);
~SkPathRef();
int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; }

Просмотреть файл

@ -52,21 +52,6 @@ public:
*/
typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
#ifdef SK_SUPPORT_LEGACY_PICTUREINSTALLPIXELREF
/**
* Recreate a picture that was serialized into a stream.
* @param SkStream Serialized picture data. Ownership is unchanged by this call.
* @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
* encoded bitmap data from the stream.
* @return A new SkPicture representing the serialized data, or NULL if the stream is
* invalid.
*/
static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc proc);
static sk_sp<SkPicture> MakeFromStream(SkStream* stream, std::nullptr_t) {
return MakeFromStream(stream);
}
#endif
/**
* Recreate a picture that was serialized into a stream.
*
@ -182,18 +167,6 @@ public:
static void SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set);
static bool PictureIOSecurityPrecautionsEnabled();
#ifdef SK_SUPPORT_LEGACY_PICTURE_PTR
static SkPicture* CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
return MakeFromStream(stream, proc).release();
}
static SkPicture* CreateFromStream(SkStream* stream) {
return MakeFromStream(stream).release();
}
static SkPicture* CreateFromBuffer(SkReadBuffer& rbuf) {
return MakeFromBuffer(rbuf).release();
}
#endif
private:
// Subclass whitelist.
SkPicture();
@ -225,10 +198,12 @@ private:
// V48: Read and write extended SkTextBlobs.
// V49: Gradients serialized as SkColor4f + SkColorSpace
// V50: SkXfermode -> SkBlendMode
// V51: more SkXfermode -> SkBlendMode
// V52: Remove SkTextBlob::fRunCount
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
static const uint32_t CURRENT_PICTURE_VERSION = 50;
static const uint32_t CURRENT_PICTURE_VERSION = 52;
static_assert(MIN_PICTURE_VERSION <= 41,
"Remove kFontFileName and related code from SkFontDescriptor.cpp.");

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше