JS - Collect and execute actions at doc and pages level
* the goal is to execute actions like Open or OpenAction * can be tested with issue6106.pdf (auto-print) * once #12701 is merged, we can add page actions
This commit is contained in:
parent
142f131ee1
commit
1e2173f038
@ -21,11 +21,9 @@ import {
|
||||
AnnotationReplyType,
|
||||
AnnotationType,
|
||||
assert,
|
||||
bytesToString,
|
||||
escapeString,
|
||||
getModificationDate,
|
||||
isString,
|
||||
objectSize,
|
||||
OPS,
|
||||
shadow,
|
||||
stringToPDFString,
|
||||
@ -34,17 +32,9 @@ import {
|
||||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { Catalog, FileSpec, ObjectLoader } from "./obj.js";
|
||||
import {
|
||||
Dict,
|
||||
isDict,
|
||||
isName,
|
||||
isRef,
|
||||
isStream,
|
||||
Name,
|
||||
RefSet,
|
||||
} from "./primitives.js";
|
||||
import { collectActions, getInheritableProperty } from "./core_utils.js";
|
||||
import { Dict, isDict, isName, isRef, isStream, Name } from "./primitives.js";
|
||||
import { ColorSpace } from "./colorspace.js";
|
||||
import { getInheritableProperty } from "./core_utils.js";
|
||||
import { OperatorList } from "./operator_list.js";
|
||||
import { StringStream } from "./stream.js";
|
||||
import { writeDict } from "./writer.js";
|
||||
@ -977,7 +967,7 @@ class WidgetAnnotation extends Annotation {
|
||||
|
||||
data.annotationType = AnnotationType.WIDGET;
|
||||
data.fieldName = this._constructFieldName(dict);
|
||||
data.actions = this._collectActions(params.xref, dict);
|
||||
data.actions = collectActions(params.xref, dict, AnnotationActionEventType);
|
||||
|
||||
const fieldValue = getInheritableProperty({
|
||||
dict,
|
||||
@ -1459,78 +1449,6 @@ class WidgetAnnotation extends Annotation {
|
||||
return localResources || Dict.empty;
|
||||
}
|
||||
|
||||
_collectJS(entry, xref, list, parents) {
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
let parent = null;
|
||||
if (isRef(entry)) {
|
||||
if (parents.has(entry)) {
|
||||
// If we've already found entry then we've a cycle.
|
||||
return;
|
||||
}
|
||||
parent = entry;
|
||||
parents.put(parent);
|
||||
entry = xref.fetch(entry);
|
||||
}
|
||||
if (Array.isArray(entry)) {
|
||||
for (const element of entry) {
|
||||
this._collectJS(element, xref, list, parents);
|
||||
}
|
||||
} else if (entry instanceof Dict) {
|
||||
if (isName(entry.get("S"), "JavaScript") && entry.has("JS")) {
|
||||
const js = entry.get("JS");
|
||||
let code;
|
||||
if (isStream(js)) {
|
||||
code = bytesToString(js.getBytes());
|
||||
} else {
|
||||
code = js;
|
||||
}
|
||||
code = stringToPDFString(code);
|
||||
if (code) {
|
||||
list.push(code);
|
||||
}
|
||||
}
|
||||
this._collectJS(entry.getRaw("Next"), xref, list, parents);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
parents.remove(parent);
|
||||
}
|
||||
}
|
||||
|
||||
_collectActions(xref, dict) {
|
||||
const actions = Object.create(null);
|
||||
if (dict.has("AA")) {
|
||||
const additionalActions = dict.get("AA");
|
||||
for (const key of additionalActions.getKeys()) {
|
||||
const action = AnnotationActionEventType[key];
|
||||
if (!action) {
|
||||
continue;
|
||||
}
|
||||
const actionDict = additionalActions.getRaw(key);
|
||||
const parents = new RefSet();
|
||||
const list = [];
|
||||
this._collectJS(actionDict, xref, list, parents);
|
||||
if (list.length > 0) {
|
||||
actions[action] = list;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collect the Action if any (we may have one on pushbutton).
|
||||
if (dict.has("A")) {
|
||||
const actionDict = dict.get("A");
|
||||
const parents = new RefSet();
|
||||
const list = [];
|
||||
this._collectJS(actionDict, xref, list, parents);
|
||||
if (list.length > 0) {
|
||||
actions.Action = list;
|
||||
}
|
||||
}
|
||||
return objectSize(actions) > 0 ? actions : null;
|
||||
}
|
||||
|
||||
getFieldObject() {
|
||||
if (this.data.fieldType === "Sig") {
|
||||
return {
|
||||
|
@ -13,7 +13,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { assert, BaseException, warn } from "../shared/util.js";
|
||||
import {
|
||||
assert,
|
||||
BaseException,
|
||||
bytesToString,
|
||||
objectSize,
|
||||
stringToPDFString,
|
||||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { Dict, isName, isRef, isStream, RefSet } from "./primitives.js";
|
||||
|
||||
function getLookupTableFactory(initializer) {
|
||||
let lookup;
|
||||
@ -240,7 +248,80 @@ function escapePDFName(str) {
|
||||
return buffer.join("");
|
||||
}
|
||||
|
||||
function _collectJS(entry, xref, list, parents) {
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
let parent = null;
|
||||
if (isRef(entry)) {
|
||||
if (parents.has(entry)) {
|
||||
// If we've already found entry then we've a cycle.
|
||||
return;
|
||||
}
|
||||
parent = entry;
|
||||
parents.put(parent);
|
||||
entry = xref.fetch(entry);
|
||||
}
|
||||
if (Array.isArray(entry)) {
|
||||
for (const element of entry) {
|
||||
_collectJS(element, xref, list, parents);
|
||||
}
|
||||
} else if (entry instanceof Dict) {
|
||||
if (isName(entry.get("S"), "JavaScript") && entry.has("JS")) {
|
||||
const js = entry.get("JS");
|
||||
let code;
|
||||
if (isStream(js)) {
|
||||
code = bytesToString(js.getBytes());
|
||||
} else {
|
||||
code = js;
|
||||
}
|
||||
code = stringToPDFString(code);
|
||||
if (code) {
|
||||
list.push(code);
|
||||
}
|
||||
}
|
||||
_collectJS(entry.getRaw("Next"), xref, list, parents);
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
parents.remove(parent);
|
||||
}
|
||||
}
|
||||
|
||||
function collectActions(xref, dict, eventType) {
|
||||
const actions = Object.create(null);
|
||||
if (dict.has("AA")) {
|
||||
const additionalActions = dict.get("AA");
|
||||
for (const key of additionalActions.getKeys()) {
|
||||
const action = eventType[key];
|
||||
if (!action) {
|
||||
continue;
|
||||
}
|
||||
const actionDict = additionalActions.getRaw(key);
|
||||
const parents = new RefSet();
|
||||
const list = [];
|
||||
_collectJS(actionDict, xref, list, parents);
|
||||
if (list.length > 0) {
|
||||
actions[action] = list;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collect the Action if any (we may have one on pushbutton).
|
||||
if (dict.has("A")) {
|
||||
const actionDict = dict.get("A");
|
||||
const parents = new RefSet();
|
||||
const list = [];
|
||||
_collectJS(actionDict, xref, list, parents);
|
||||
if (list.length > 0) {
|
||||
actions.Action = list;
|
||||
}
|
||||
}
|
||||
return objectSize(actions) > 0 ? actions : null;
|
||||
}
|
||||
|
||||
export {
|
||||
collectActions,
|
||||
escapePDFName,
|
||||
getLookupTableFactory,
|
||||
getArrayLookupTableFactory,
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
isNum,
|
||||
isString,
|
||||
OPS,
|
||||
PageActionEventType,
|
||||
shadow,
|
||||
stringToBytes,
|
||||
stringToPDFString,
|
||||
@ -42,6 +43,7 @@ import {
|
||||
Ref,
|
||||
} from "./primitives.js";
|
||||
import {
|
||||
collectActions,
|
||||
getInheritableProperty,
|
||||
isWhiteSpace,
|
||||
MissingDataException,
|
||||
@ -467,6 +469,16 @@ class Page {
|
||||
|
||||
return shadow(this, "_parsedAnnotations", parsedAnnotations);
|
||||
}
|
||||
|
||||
get jsActions() {
|
||||
const actions = collectActions(
|
||||
this.xref,
|
||||
this.pageDict,
|
||||
PageActionEventType
|
||||
);
|
||||
|
||||
return shadow(this, "jsActions", actions);
|
||||
}
|
||||
}
|
||||
|
||||
const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
bytesToString,
|
||||
createPromiseCapability,
|
||||
createValidAbsoluteUrl,
|
||||
DocumentActionEventType,
|
||||
FormatError,
|
||||
info,
|
||||
InvalidPDFException,
|
||||
@ -47,13 +48,14 @@ import {
|
||||
RefSet,
|
||||
RefSetCache,
|
||||
} from "./primitives.js";
|
||||
import { Lexer, Parser } from "./parser.js";
|
||||
import {
|
||||
collectActions,
|
||||
MissingDataException,
|
||||
toRomanNumerals,
|
||||
XRefEntryException,
|
||||
XRefParseException,
|
||||
} from "./core_utils.js";
|
||||
import { Lexer, Parser } from "./parser.js";
|
||||
import { CipherTransformFactory } from "./crypto.js";
|
||||
import { ColorSpace } from "./colorspace.js";
|
||||
import { GlobalImageCache } from "./image_utils.js";
|
||||
@ -873,11 +875,11 @@ class Catalog {
|
||||
return shadow(this, "attachments", attachments);
|
||||
}
|
||||
|
||||
get javaScript() {
|
||||
_collectJavaScript() {
|
||||
const obj = this._catDict.get("Names");
|
||||
|
||||
let javaScript = null;
|
||||
function appendIfJavaScriptDict(jsDict) {
|
||||
function appendIfJavaScriptDict(name, jsDict) {
|
||||
const type = jsDict.get("S");
|
||||
if (!isName(type, "JavaScript")) {
|
||||
return;
|
||||
@ -890,10 +892,10 @@ class Catalog {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!javaScript) {
|
||||
javaScript = [];
|
||||
if (javaScript === null) {
|
||||
javaScript = Object.create(null);
|
||||
}
|
||||
javaScript.push(stringToPDFString(js));
|
||||
javaScript[name] = stringToPDFString(js);
|
||||
}
|
||||
|
||||
if (obj && obj.has("JavaScript")) {
|
||||
@ -904,7 +906,7 @@ class Catalog {
|
||||
// defensive so we don't cause errors on document load.
|
||||
const jsDict = names[name];
|
||||
if (isDict(jsDict)) {
|
||||
appendIfJavaScriptDict(jsDict);
|
||||
appendIfJavaScriptDict(name, jsDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -912,10 +914,43 @@ class Catalog {
|
||||
// Append OpenAction "JavaScript" actions to the JavaScript array.
|
||||
const openAction = this._catDict.get("OpenAction");
|
||||
if (isDict(openAction) && isName(openAction.get("S"), "JavaScript")) {
|
||||
appendIfJavaScriptDict(openAction);
|
||||
appendIfJavaScriptDict("OpenAction", openAction);
|
||||
}
|
||||
|
||||
return shadow(this, "javaScript", javaScript);
|
||||
return javaScript;
|
||||
}
|
||||
|
||||
get javaScript() {
|
||||
const javaScript = this._collectJavaScript();
|
||||
return shadow(
|
||||
this,
|
||||
"javaScript",
|
||||
javaScript ? Object.values(javaScript) : null
|
||||
);
|
||||
}
|
||||
|
||||
get jsActions() {
|
||||
const js = this._collectJavaScript();
|
||||
let actions = collectActions(
|
||||
this.xref,
|
||||
this._catDict,
|
||||
DocumentActionEventType
|
||||
);
|
||||
|
||||
if (!actions && js) {
|
||||
actions = Object.create(null);
|
||||
}
|
||||
if (actions && js) {
|
||||
for (const [key, val] of Object.entries(js)) {
|
||||
if (key in actions) {
|
||||
actions[key].push(val);
|
||||
} else {
|
||||
actions[key] = [val];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return shadow(this, "jsActions", actions);
|
||||
}
|
||||
|
||||
fontFallback(id, handler) {
|
||||
|
@ -481,6 +481,16 @@ class WorkerMessageHandler {
|
||||
return pdfManager.ensureCatalog("javaScript");
|
||||
});
|
||||
|
||||
handler.on("GetDocJSActions", function wphSetupGetDocJSActions(data) {
|
||||
return pdfManager.ensureCatalog("jsActions");
|
||||
});
|
||||
|
||||
handler.on("GetPageJSActions", function ({ pageIndex }) {
|
||||
return pdfManager.getPage(pageIndex).then(function (page) {
|
||||
return page.jsActions;
|
||||
});
|
||||
});
|
||||
|
||||
handler.on("GetOutline", function wphSetupGetOutline(data) {
|
||||
return pdfManager.ensureCatalog("documentOutline");
|
||||
});
|
||||
|
@ -753,6 +753,17 @@ class PDFDocumentProxy {
|
||||
return this._transport.getJavaScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<Object | null>} A promise that is resolved with
|
||||
* an {Object} with the JavaScript actions:
|
||||
* - from the name tree (like getJavaScript);
|
||||
* - from A or AA entries in the catalog dictionary.
|
||||
* , or `null` if no JavaScript exists.
|
||||
*/
|
||||
getJSActions() {
|
||||
return this._transport.getDocJSActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} OutlineNode
|
||||
* @property {string} title
|
||||
@ -1124,6 +1135,20 @@ class PDFPageProxy {
|
||||
return this.annotationsPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GetAnnotationsParameters} params - Annotation parameters.
|
||||
* @returns {Promise<Array<any>>} A promise that is resolved with an
|
||||
* {Array} of the annotation objects.
|
||||
*/
|
||||
getJSActions() {
|
||||
if (!this._jsActionsPromise) {
|
||||
this._jsActionsPromise = this._transport.getPageJSActions(
|
||||
this._pageIndex
|
||||
);
|
||||
}
|
||||
return this._jsActionsPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the process of rendering a page to the desired context.
|
||||
*
|
||||
@ -1405,6 +1430,7 @@ class PDFPageProxy {
|
||||
}
|
||||
this.objs.clear();
|
||||
this.annotationsPromise = null;
|
||||
this._jsActionsPromise = null;
|
||||
this.pendingCleanup = false;
|
||||
return Promise.all(waitOn);
|
||||
}
|
||||
@ -1438,6 +1464,7 @@ class PDFPageProxy {
|
||||
this._intentStates.clear();
|
||||
this.objs.clear();
|
||||
this.annotationsPromise = null;
|
||||
this._jsActionsPromise = null;
|
||||
if (resetStats && this._stats) {
|
||||
this._stats = new StatTimer();
|
||||
}
|
||||
@ -2631,6 +2658,16 @@ class WorkerTransport {
|
||||
return this.messageHandler.sendWithPromise("GetJavaScript", null);
|
||||
}
|
||||
|
||||
getDocJSActions() {
|
||||
return this.messageHandler.sendWithPromise("GetDocJSActions", null);
|
||||
}
|
||||
|
||||
getPageJSActions(pageIndex) {
|
||||
return this.messageHandler.sendWithPromise("GetPageJSActions", {
|
||||
pageIndex,
|
||||
});
|
||||
}
|
||||
|
||||
getOutline() {
|
||||
return this.messageHandler.sendWithPromise("GetOutline", null);
|
||||
}
|
||||
|
26
src/scripting_api/common.js
Normal file
26
src/scripting_api/common.js
Normal file
@ -0,0 +1,26 @@
|
||||
/* Copyright 2020 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function createActionsMap(actions) {
|
||||
const actionsMap = new Map();
|
||||
if (actions) {
|
||||
for (const [eventType, actionsForEvent] of Object.entries(actions)) {
|
||||
actionsMap.set(eventType, actionsForEvent);
|
||||
}
|
||||
}
|
||||
return actionsMap;
|
||||
}
|
||||
|
||||
export { createActionsMap };
|
@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createActionsMap } from "./common.js";
|
||||
import { PDFObject } from "./pdf_object.js";
|
||||
import { PrintParams } from "./print_params.js";
|
||||
import { ZoomType } from "./constants.js";
|
||||
@ -88,6 +89,48 @@ class Doc extends PDFObject {
|
||||
|
||||
this._zoomType = ZoomType.none;
|
||||
this._zoom = data.zoom || 100;
|
||||
this._actions = createActionsMap(data.actions);
|
||||
this._globalEval = data.globalEval;
|
||||
}
|
||||
|
||||
_dispatchDocEvent(name) {
|
||||
if (name === "Open") {
|
||||
const dontRun = new Set([
|
||||
"WillClose",
|
||||
"WillSave",
|
||||
"DidSave",
|
||||
"WillPrint",
|
||||
"DidPrint",
|
||||
"OpenAction",
|
||||
]);
|
||||
for (const actionName of this._actions.keys()) {
|
||||
if (!dontRun.has(actionName)) {
|
||||
this._runActions(actionName);
|
||||
}
|
||||
}
|
||||
this._runActions("OpenAction");
|
||||
} else {
|
||||
this._runActions(name);
|
||||
}
|
||||
}
|
||||
|
||||
_dispatchPageEvent(name, action, pageNumber) {
|
||||
if (name === "PageOpen") {
|
||||
this._pageNum = pageNumber - 1;
|
||||
}
|
||||
|
||||
this._globalEval(action);
|
||||
}
|
||||
|
||||
_runActions(name) {
|
||||
if (!this._actions.has(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actions = this._actions.get(name);
|
||||
for (const action of actions) {
|
||||
this._globalEval(action);
|
||||
}
|
||||
}
|
||||
|
||||
_addField(name, field) {
|
||||
@ -954,7 +997,7 @@ class Doc extends PDFObject {
|
||||
nEnd = -1;
|
||||
}
|
||||
|
||||
this._send({ id: "print", start: nStart, end: nEnd });
|
||||
this._send({ command: "print", start: nStart, end: nEnd });
|
||||
}
|
||||
|
||||
removeDataObject() {
|
||||
|
@ -65,12 +65,28 @@ class EventDispatcher {
|
||||
dispatch(baseEvent) {
|
||||
const id = baseEvent.id;
|
||||
if (!(id in this._objects)) {
|
||||
let event;
|
||||
if (id === "doc" || id === "page") {
|
||||
event = globalThis.event = new Event(baseEvent);
|
||||
event.source = event.target = this._document.wrapped;
|
||||
event.name = baseEvent.name;
|
||||
}
|
||||
if (id === "doc") {
|
||||
this._document.obj._dispatchDocEvent(event.name);
|
||||
}
|
||||
if (id === "page") {
|
||||
this._document.obj._dispatchPageEvent(
|
||||
event.name,
|
||||
baseEvent.action,
|
||||
baseEvent.pageNumber
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const name = baseEvent.name.replace(" ", "");
|
||||
const source = this._objects[id];
|
||||
globalThis.event = new Event(baseEvent);
|
||||
const event = (globalThis.event = new Event(baseEvent));
|
||||
let savedChange;
|
||||
|
||||
if (source.obj._isButton()) {
|
||||
@ -156,7 +172,7 @@ class EventDispatcher {
|
||||
const first = this._calculationOrder[0];
|
||||
const source = this._objects[first];
|
||||
globalThis.event = new Event({});
|
||||
this.runCalculate(source, event);
|
||||
this.runCalculate(source, globalThis.event);
|
||||
}
|
||||
|
||||
runCalculate(source, event) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
import { Color } from "./color.js";
|
||||
import { createActionsMap } from "./common.js";
|
||||
import { PDFObject } from "./pdf_object.js";
|
||||
|
||||
class Field extends PDFObject {
|
||||
@ -72,7 +73,7 @@ class Field extends PDFObject {
|
||||
|
||||
// Private
|
||||
this._document = data.doc;
|
||||
this._actions = this._createActionsMap(data.actions);
|
||||
this._actions = createActionsMap(data.actions);
|
||||
|
||||
this._fillColor = data.fillColor || ["T"];
|
||||
this._strokeColor = data.strokeColor || ["G", 0];
|
||||
@ -133,16 +134,6 @@ class Field extends PDFObject {
|
||||
this._send({ id: this._id, focus: true });
|
||||
}
|
||||
|
||||
_createActionsMap(actions) {
|
||||
const actionsMap = new Map();
|
||||
if (actions) {
|
||||
for (const [eventType, actionsForEvent] of Object.entries(actions)) {
|
||||
actionsMap.set(eventType, actionsForEvent);
|
||||
}
|
||||
}
|
||||
return actionsMap;
|
||||
}
|
||||
|
||||
_isButton() {
|
||||
return false;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ function initSandbox(params) {
|
||||
const { data } = params;
|
||||
const doc = new Doc({
|
||||
send,
|
||||
globalEval,
|
||||
...data.docInfo,
|
||||
});
|
||||
const _document = { obj: doc, wrapped: new Proxy(doc, proxyHandler) };
|
||||
@ -67,16 +68,17 @@ function initSandbox(params) {
|
||||
const util = new Util({ externalCall });
|
||||
const aform = new AForm(doc, app, util);
|
||||
|
||||
for (const [name, objs] of Object.entries(data.objects)) {
|
||||
const obj = objs[0];
|
||||
obj.send = send;
|
||||
obj.globalEval = globalEval;
|
||||
obj.doc = _document.wrapped;
|
||||
obj.globalEval = globalEval;
|
||||
const field = new Field(obj);
|
||||
const wrapped = new Proxy(field, proxyHandler);
|
||||
doc._addField(name, wrapped);
|
||||
app._objects[obj.id] = { obj: field, wrapped };
|
||||
if (data.objects) {
|
||||
for (const [name, objs] of Object.entries(data.objects)) {
|
||||
const obj = objs[0];
|
||||
obj.send = send;
|
||||
obj.globalEval = globalEval;
|
||||
obj.doc = _document.wrapped;
|
||||
const field = new Field(obj);
|
||||
const wrapped = new Proxy(field, proxyHandler);
|
||||
doc._addField(name, wrapped);
|
||||
app._objects[obj.id] = { obj: field, wrapped };
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.event = null;
|
||||
|
@ -159,6 +159,9 @@ const AnnotationActionEventType = {
|
||||
F: "Format",
|
||||
V: "Validate",
|
||||
C: "Calculate",
|
||||
};
|
||||
|
||||
const DocumentActionEventType = {
|
||||
WC: "WillClose",
|
||||
WS: "WillSave",
|
||||
DS: "DidSave",
|
||||
@ -166,6 +169,11 @@ const AnnotationActionEventType = {
|
||||
DP: "DidPrint",
|
||||
};
|
||||
|
||||
const PageActionEventType = {
|
||||
O: "PageOpen",
|
||||
C: "PageClose",
|
||||
};
|
||||
|
||||
const StreamType = {
|
||||
UNKNOWN: "UNKNOWN",
|
||||
FLATE: "FLATE",
|
||||
@ -1011,9 +1019,11 @@ export {
|
||||
FontType,
|
||||
ImageKind,
|
||||
CMapCompressionType,
|
||||
DocumentActionEventType,
|
||||
AbortException,
|
||||
InvalidPDFException,
|
||||
MissingPDFException,
|
||||
PageActionEventType,
|
||||
PasswordException,
|
||||
PasswordResponses,
|
||||
PermissionFlag,
|
||||
|
@ -27,6 +27,20 @@ describe("Interaction", () => {
|
||||
await closePages(pages);
|
||||
});
|
||||
|
||||
it("must check that first text field has focus", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
// The document has an open action in order to give
|
||||
// the focus to 401R.
|
||||
await page.waitForTimeout(1000);
|
||||
const id = await page.evaluate(
|
||||
() => window.document.activeElement.id
|
||||
);
|
||||
expect(id).withContext(`In ${browserName}`).toEqual("401R");
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("must show a text field and then make in invisible when content is removed", async () => {
|
||||
await Promise.all(
|
||||
pages.map(async ([browserName, page]) => {
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -178,6 +178,7 @@
|
||||
!pattern_text_embedded_font.pdf
|
||||
!devicen.pdf
|
||||
!cmykjpeg.pdf
|
||||
!docactions.pdf
|
||||
!issue840.pdf
|
||||
!160F-2019.pdf
|
||||
!issue4402_reduced.pdf
|
||||
|
426
test/pdfs/docactions.pdf
Normal file
426
test/pdfs/docactions.pdf
Normal file
@ -0,0 +1,426 @@
|
||||
%PDF-1.5
|
||||
%¿÷¢þ
|
||||
1 0 obj
|
||||
<< /Type /ObjStm /Length 9839 /N 70 /First 545 >>
|
||||
stream
|
||||
2 0 3 33 4 227 5 301 6 1602 7 1672 8 1755 9 1808 10 1936 11 1990 12 2115 13 2169 14 2464 15 2517 16 2561 17 2606 18 2730 19 2824 20 2877 21 3110 22 3155 23 3208 24 3441 25 3486 26 3539 27 3772 28 3817 29 3870 30 4103 31 4148 32 4201 33 4434 34 4479 35 4532 36 4765 37 4810 38 4905 39 4958 40 5191 41 5236 42 5289 43 5522 44 5567 45 5620 46 5855 47 5900 48 5953 49 6188 50 6233 51 6286 52 6521 53 6566 54 6599 55 6652 56 6887 57 6932 58 6992 59 7107 60 7703 61 7927 62 7935 63 8215 64 8430 65 8632 66 8692 67 8846 68 8989 69 9068 70 9138 71 9177
|
||||
<< /D [ 3 0 R /Fit ] /S /GoTo >>
|
||||
<< /AA << /O << /JS (console.println\('Open the document'\); ) /S /JavaScript >> >> /Annots [ 13 0 R ] /Contents 73 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 14 0 R /Type /Page >>
|
||||
<< /JS (console.println('Open Action');) /S /JavaScript >>
|
||||
<< /Differences [ 24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde 39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright /minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot /.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] /Type /Encoding >>
|
||||
<< /BaseFont /ZapfDingbats /Name /ZaDb /Subtype /Type1 /Type /Font >>
|
||||
<< /BaseFont /Helvetica /Encoding 5 0 R /Name /Helv /Subtype /Type1 /Type /Font >>
|
||||
<< /Font << /F30 9 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /BaseFont /GCRMMP+Dingbats /FirstChar 123 /FontDescriptor 64 0 R /LastChar 123 /Subtype /Type1 /Type /Font /Widths 61 0 R >>
|
||||
<< /Font << /F31 11 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /BaseFont /XYLNGW+CMSS10 /FirstChar 80 /FontDescriptor 63 0 R /LastChar 117 /Subtype /Type1 /Type /Font /Widths 60 0 R >>
|
||||
<< /Font << /F31 11 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /F << /JS (console.println\('text entered='+event.value\);) /S /JavaScript >> >> /BS << /S /S /W 1 >> /DA (/Helv 10 Tf 0 0 0 rg) /DV () /F 4 /FT /Tx /MK << /BC [ 1 0 0 ] /BG [ 1 1 1 ] >> /Q 0 /Rect [ 184.744 652.309 271.776 668.194 ] /Subtype /Widget /T (field1) /Type /Annot /V () >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /D [ 3 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /D [ 3 0 R /XYZ 106.869 667.198 null ] >>
|
||||
<< /BaseFont /CFMZGO+CMR10 /FirstChar 12 /FontDescriptor 62 0 R /LastChar 121 /Subtype /Type1 /Type /Font /Widths 59 0 R >>
|
||||
<< /Count 6 /Kids [ 3 0 R 20 0 R 23 0 R 26 0 R 29 0 R 32 0 R ] /Parent 65 0 R /Type /Pages >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 2'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 2'\);) /S /JavaScript >> >> /Contents 74 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 19 0 R /Type /Page >>
|
||||
<< /D [ 20 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 3'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 3'\);) /S /JavaScript >> >> /Contents 75 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 22 0 R /Type /Page >>
|
||||
<< /D [ 23 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 4'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 4'\);) /S /JavaScript >> >> /Contents 76 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 25 0 R /Type /Page >>
|
||||
<< /D [ 26 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 5'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 5'\);) /S /JavaScript >> >> /Contents 77 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 28 0 R /Type /Page >>
|
||||
<< /D [ 29 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 6'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 6'\);) /S /JavaScript >> >> /Contents 78 0 R /MediaBox [ 0 0 612 792 ] /Parent 18 0 R /Resources 31 0 R /Type /Page >>
|
||||
<< /D [ 32 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 7'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 7'\);) /S /JavaScript >> >> /Contents 79 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 34 0 R /Type /Page >>
|
||||
<< /D [ 35 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Count 6 /Kids [ 35 0 R 39 0 R 42 0 R 45 0 R 48 0 R 51 0 R ] /Parent 65 0 R /Type /Pages >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 8'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 8'\);) /S /JavaScript >> >> /Contents 80 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 38 0 R /Type /Page >>
|
||||
<< /D [ 39 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 9'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 9'\);) /S /JavaScript >> >> /Contents 81 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 41 0 R /Type /Page >>
|
||||
<< /D [ 42 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 10'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 10'\);) /S /JavaScript >> >> /Contents 82 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 44 0 R /Type /Page >>
|
||||
<< /D [ 45 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 11'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 11'\);) /S /JavaScript >> >> /Contents 83 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 47 0 R /Type /Page >>
|
||||
<< /D [ 48 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 12'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 12'\);) /S /JavaScript >> >> /Contents 84 0 R /MediaBox [ 0 0 612 792 ] /Parent 37 0 R /Resources 50 0 R /Type /Page >>
|
||||
<< /D [ 51 0 R /XYZ 159.667 705.06 null ] >>
|
||||
<< /Names [ (Open) 4 0 R ] >>
|
||||
<< /Font << /F8 17 0 R >> /ProcSet [ /PDF /Text ] >>
|
||||
<< /AA << /C << /JS (console.println\('Close page 13'\);) /S /JavaScript >> /O << /JS (console.println\('Open page 13'\);) /S /JavaScript >> >> /Contents 85 0 R /MediaBox [ 0 0 612 792 ] /Parent 57 0 R /Resources 54 0 R /Type /Page >>
|
||||
<< /D [ 55 0 R /XYZ 105.869 705.06 null ] >>
|
||||
<< /Count 1 /Kids [ 55 0 R ] /Parent 65 0 R /Type /Pages >>
|
||||
<< /DA (/Helv 10 Tf 0 g) /DR << /Font << /Helv 7 0 R /ZaDb 6 0 R >> >> /Fields [ 13 0 R ] /NeedAppearances true >>
|
||||
[ 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 ]
|
||||
[ 638.9 736.1 645.8 555.6 680.6 687.5 666.7 944.5 666.7 666.7 611.1 288.9 500 288.9 500 277.8 277.8 480.6 516.7 444.4 516.7 444.4 305.6 500 516.7 238.9 266.7 488.9 238.9 794.4 516.7 500 516.7 516.7 341.7 383.3 361.1 516.7 ]
|
||||
[ 392 ]
|
||||
<< /Ascent 694 /CapHeight 683 /CharSet (/M/a/colon/d/e/eight/fi/five/four/g/l/nine/one/p/seven/six/t/three/two/x/y/zero) /Descent -194 /Flags 4 /FontBBox [ -40 -250 1009 750 ] /FontFile 86 0 R /FontName /CFMZGO+CMR10 /ItalicAngle 0 /StemV 69 /Type /FontDescriptor /XHeight 431 >>
|
||||
<< /Ascent 694 /CapHeight 694 /CharSet (/P/S/b/i/m/t/u) /Descent -194 /Flags 4 /FontBBox [ -61 -250 999 759 ] /FontFile 87 0 R /FontName /XYLNGW+CMSS10 /ItalicAngle 0 /StemV 78 /Type /FontDescriptor /XHeight 444 >>
|
||||
<< /Ascent 708 /CapHeight 708 /CharSet (/a97) /Descent 0 /Flags 4 /FontBBox [ -1 -143 981 819 ] /FontFile 88 0 R /FontName /GCRMMP+Dingbats /ItalicAngle 0 /StemV 0 /Type /FontDescriptor /XHeight 400 >>
|
||||
<< /Count 13 /Kids [ 18 0 R 37 0 R 57 0 R ] /Type /Pages >>
|
||||
<< /Limits [ (Doc-Start) (page.13) ] /Names [ (Doc-Start) 16 0 R (page.1) 15 0 R (page.10) 46 0 R (page.11) 49 0 R (page.12) 52 0 R (page.13) 56 0 R ] >>
|
||||
<< /Limits [ (page.2) (page.7) ] /Names [ (page.2) 21 0 R (page.3) 24 0 R (page.4) 27 0 R (page.5) 30 0 R (page.6) 33 0 R (page.7) 36 0 R ] >>
|
||||
<< /Limits [ (page.8) (page.9) ] /Names [ (page.8) 40 0 R (page.9) 43 0 R ] >>
|
||||
<< /Kids [ 66 0 R 67 0 R 68 0 R ] /Limits [ (Doc-Start) (page.9) ] >>
|
||||
<< /Dests 69 0 R /JavaScript 53 0 R >>
|
||||
<< /AA << >> /AcroForm 58 0 R /Names 70 0 R /OpenAction 2 0 R /PageMode /UseOutlines /Pages 65 0 R /Type /Catalog >>
|
||||
endstream
|
||||
endobj
|
||||
72 0 obj
|
||||
<< /Author () /CreationDate (D:20201207183605+01'00') /Creator (LaTeX with hyperref) /Keywords () /ModDate (D:20201207183605+01'00') /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.21 \(TeX Live 2020/Debian\) kpathsea version 6.3.2) /Producer (pdfTeX-1.40.21) /Subject () /Title () /Trapped /False >>
|
||||
endobj
|
||||
73 0 obj
|
||||
<< /Length 100 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 655.243 Td [(My)-333(text)-334(\014eld:)]TJ 154.421 -565.878 Td [(1)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
74 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(2)]TJ 154.421 -567.87 Td [(2)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
75 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(3)]TJ 154.421 -567.87 Td [(3)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
76 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(4)]TJ 154.421 -567.87 Td [(4)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
77 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(5)]TJ 154.421 -567.87 Td [(5)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
78 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(6)]TJ 154.421 -567.87 Td [(6)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
79 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(7)]TJ 154.421 -567.87 Td [(7)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
80 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(8)]TJ 154.421 -567.87 Td [(8)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
81 0 obj
|
||||
<< /Length 84 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(9)]TJ 154.421 -567.87 Td [(9)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
82 0 obj
|
||||
<< /Length 86 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(10)]TJ 151.931 -567.87 Td [(10)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
83 0 obj
|
||||
<< /Length 85 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(11)]TJ 151.93 -567.87 Td [(11)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
84 0 obj
|
||||
<< /Length 86 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 175.611 657.235 Td [(page)-333(12)]TJ 151.931 -567.87 Td [(12)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
85 0 obj
|
||||
<< /Length 85 >>
|
||||
stream
|
||||
BT
|
||||
/F8 9.9626 Tf 121.813 657.235 Td [(page)-333(13)]TJ 151.93 -567.87 Td [(13)]TJ
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
86 0 obj
|
||||
<< /Length1 1700 /Length2 12121 /Length3 0 /Length 13821 >>
|
||||
stream
|
||||
%!PS-AdobeFont-1.0: CMR10 003.002
|
||||
%%Title: CMR10
|
||||
%Version: 003.002
|
||||
%%CreationDate: Mon Jul 13 16:17:00 2009
|
||||
%%Creator: David M. Jones
|
||||
%Copyright: Copyright (c) 1997, 2009 American Mathematical Society
|
||||
%Copyright: (<http://www.ams.org>), with Reserved Font Name CMR10.
|
||||
% This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
% This license is in the accompanying file OFL.txt, and is also
|
||||
% available with a FAQ at: http://scripts.sil.org/OFL.
|
||||
%%EndComments
|
||||
FontDirectory/CMR10 known{/CMR10 findfont dup/UniqueID known{dup
|
||||
/UniqueID get 5000793 eq exch/FontType get 1 eq and}{pop false}ifelse
|
||||
{save true}{false}ifelse}{false}ifelse
|
||||
11 dict begin
|
||||
/FontType 1 def
|
||||
/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def
|
||||
/FontName /CFMZGO+CMR10 def
|
||||
/FontBBox {-40 -250 1009 750 }readonly def
|
||||
/PaintType 0 def
|
||||
/FontInfo 9 dict dup begin
|
||||
/version (003.002) readonly def
|
||||
/Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050<http://www.ams.org>\051, with Reserved Font Name CMR10.) readonly def
|
||||
/FullName (CMR10) readonly def
|
||||
/FamilyName (Computer Modern) readonly def
|
||||
/Weight (Medium) readonly def
|
||||
/ItalicAngle 0 def
|
||||
/isFixedPitch false def
|
||||
/UnderlinePosition -100 def
|
||||
/UnderlineThickness 50 def
|
||||
end readonly def
|
||||
/Encoding 256 array
|
||||
0 1 255 {1 index exch /.notdef put} for
|
||||
dup 77 /M put
|
||||
dup 97 /a put
|
||||
dup 58 /colon put
|
||||
dup 100 /d put
|
||||
dup 101 /e put
|
||||
dup 56 /eight put
|
||||
dup 12 /fi put
|
||||
dup 53 /five put
|
||||
dup 52 /four put
|
||||
dup 103 /g put
|
||||
dup 108 /l put
|
||||
dup 57 /nine put
|
||||
dup 49 /one put
|
||||
dup 112 /p put
|
||||
dup 55 /seven put
|
||||
dup 54 /six put
|
||||
dup 116 /t put
|
||||
dup 51 /three put
|
||||
dup 50 /two put
|
||||
dup 120 /x put
|
||||
dup 121 /y put
|
||||
dup 48 /zero put
|
||||
readonly def
|
||||
currentdict end
|
||||
currentfile eexec
|
||||
ÙÖoc;„j²„¼ø°Aw-åÎ=Ó%åW˜)-{Ùr½uú•)¯œ‚ßröA•ÉÂÜãE(õ@Úý{ë¹´‡º“Q»û|ü_‘RÑå»
|
||||
ØÐÆϤëA³Å -T@æ|ýq|V<>k¹¿J% qu8P¢øwÄGx³ÅªÛ̆ÖåQæ¯6KüªÒ-<2D>UŒ\<5C>§Ô%¡b<C2A1>Õ"t-*ðxÔõöÓŸÏÿJ‘+
|
||||
}ì<>3¥{Zà2ŽùÕzݬT2sÀ$ZõÌÑ&{Bè–J×{¨¥ÜÆØx¹<¥Ÿ
,—Ü-.è2›¯iR‹n·Ã±vÌÙ¾1ä • „'Æ䓱©·_r"O¯»_‹t±3keè¾fBݼöVÁfj—Ú9Ò³ÿ Ô
Yh뀸Á{û´qÝÉÊÆ-÷†—ºøÉ·ÊãÁ}W§?Å?gw1*Eh[ŠÜÛ:›—ªtÍÀWeI,Úv•8üa…<{‚ñBú1â¤00Z8ÃÌî5 |ñŽ}µðN¾àÔ×lw]ƒÿƒ6Nÿb¿—ðð¤h3E`œ†(¡›EÁ‰¡Þ<C2A1>'Q;²eµÔƒª/ðà.D©yL’â5ØñÇ$¥4IGÃå׮Ɋ\‚yjù9£.îVU»<55>5£Q!äì‹-Íèµ<C3A8>ÈBƒ…Ä9ödèâö««B^éoVùðwˆBÉŽáT7„¡‰¾R€ŸÀsO™GA‹¦÷ãÕà b#íTBv!m·<6D>WT=úãÍÀ¦üw,ªID%'¥ÙMÅKé<‡|Ù]ØD¥Ã°€@‰õ·€2²½Oø( |