Convert old cs4 script to illustrator cc
This is a big ask, but I found this script to remove redundant points at github.com/mekkablue/Glyphs-Scripts
Each time I run, it seems to work, it shows how many points it has removed, but then illustrator crashes, with no kind of error notice.
If I run it via extendscript toolkit it jumps to the following bit of code
var docRef=app.activeDocument;
I would really love to get this to work, if anyone is willing to help me.
RemovetRedundantPoints.jsx
A Javascript for Adobe Illustrator
Author:
Jim Heck
[email protected]
Purpose:
Remove anchorpoints on selected path that are coincident in location.
Finds and optionally removes redundant points from each selected PathItem.
Useful for cleaning up after Offset Path and Outline Stroke commands in CS3.
To Use:
Select the paths, including compound paths to be affected. If no path is
selected, the script will run for all paths in the document that are not
locked. Run the script.
Rights:
This work is licensed under the Creative Commons Attribution 3.0 United States
License. To view a copy of this license, visit
http://creativecommons.org/licenses/by/3.0/us/
or send a letter to Creative Commons, 171 Second Street, Suite 300,
San Francisco, California, 94105, USA.
Version History:
1.8 120108 More fixes to the logic for keeping only a single point.
The direction handles for the remaining point are now correctly calculated
based on relative angle and distance to the original anchor to which a
handle related. Also if a SMOOTH point is remaining, the angle of the
two direction handles has been tweaked to be exactly 180 degrees for
consistency with the definition of a SMOOTH point.
1.7 120106 Change the way direction handles and PointType are handled
when keeping only one point. Retract handles less than 0.5 points to keep
consistent angles for SMOOTH point types. If keepLeadingPoint or
keepTrailingPoint is specified, try to keep the PointType of that point.
In the absence of other indicators, base PointType on the point (leading
or trailing) that has an extended handle.
1.6.1 090914 Tweak defaults to make sense for my work style
1.6 090411 Fix a bug in creating a temporary path. Fix a bug in
findRedundantPoints(), when searching backwards, the tolerance was always
applied against the first point on the path instead of the adjacent point
along the path. Change selection options so that there is more control over
which points are processed on a given path. The new options allow for ignoring
selection of points, restricting processing to only selected points, or
processing redundant points if at least one of them is selected. Correct count
of redundant points removed when both leading and trailing points retained.
1.5 090404 Change default action to remove. Fix a major performance issue
in the docGetSelectedPaths() routine. Searching through all the paths in very
complex files takes a LONG time. Instead, search the document groups array.
BETA: Lots of hacking on the removeRedundantPoints() routine to improve the
look of the resulting curve when applied to the oxbow problem.
1.4.1 090331 Fix a bug in removeRedundantPoints(), needed to compare absolute
error to a tolerance. Also, loosen up the error criteria so less smooth
points are mischaracterized as corners. Tolerance is now 0.02 radians,
which is about 1.15 degrees. For some reason, the redundant points on
arbitrary (non-geometric) outlined paths have lots of slop in the
direction handles.
1.4 090331 Add options to control which points are left on removal, leading,
trailing or both. If neither is retained, the redundant point positions
are averaged. If both are retained, intermediate points are removed, and
inward facing control handles are synthesized (see comments below).
Switched to using the atan2 function instead of atan for calculating theta.
Fixed bugs in docGetSelectedPaths(). CompoundPathItem objects don't seem
to have properly formed pathItems arrays when they contain what appear to
be groups of paths. Also, layer objects can contain layers.
1.3.1 090327 Limit user entered tolerance value to something sane.
1.3 090327 Add user controls to specify a tolerance in points for identifying
redundant points.
1.2.3 090327 Improve results dialog verbiage.
1.2.2 090326 Bug fix. Observe proper unlocking and locking order for
handling of locked objects.
1.2.1 090326 Minor bug fixes including, restricting selection only option
to not be allowed with selection function.
1.2 090326 Add option to remove only redundant points sets with at least one
selected point. Fix broken option to remove locked redundant points.
Add results dialog OK button.
1.1 090325 Improve select action to work across selection or entire document.
Handle nested layers in docGetSelectedPaths(). Clean whitespace.
1.0.1 090325 Minor bug fix.
1.0 090311 Initial release.
* Function: getPairTheta
* Description:
* Return the angle relative to the X axis from the line formed between
* two points, which are passed in as arguments. The angle is measured
* relative to point A (as if A were relocated to the origin, and the angle
* is measured to the X axis itself). The arguments are expected to be
* arrays of two numbers (X, Y) defining the point. The return value is in
* radians (PI to -PI)
function getPairTheta(pairA,pairB){
var deltaX=pairB[0]-pairA[0];
var deltaY=pairB[1]-pairA[1];
/*alert("deltaX="+deltaX+" deltaY="+deltaY);*/
return(Math.atan2(deltaY, deltaX));
* Function: getPairDistance
* Description:
* Return the distance between two points. The arguments are expected to be
* arrays of two numbers (X, Y) defining the point. The return value is the
* distance in units relative to the inputs.
function getPairDistance(pairA,pairB){
var deltaX=pairB[0]-pairA[0];
var deltaY=pairB[1]-pairA[1];
return(Math.sqrt((deltaX*deltaX)+(deltaY*deltaY)));
* Function: findRedundantPoints
* Description:
* Find all sets of redundant points for the input path. A redundant point
* is defined as one that has the same anchor location as a neighboring point.
* The arguments are a path to work on, the tolerance in points to apply to
* determine a point is redundant, and a boolean to indicate that only
* groups of redundant points where at least one point is selected should
* be considered. The return value is an Array of Arrays containing the
* indicies of the redundant pathPoint objects found in the path.
function findRedundantPoints(path, tolerance, anySelected, allSelected){
var anchorDistance = 0;
var redundantPointSets = new Array();
var redundantPoint = new Array();
var selectedRedundantPointSets = new Array();
var selectedRedundantPoint = new Array();
var i = 0;
var j = 0;
var k = 0;
var index;
var selected = false;
if(path.pathPoints.length > 1) {
* The first path point may be coincident with some at the end of the path
* so we check going backwards first. Redundant points pushed on the
* front of the array so they stay in order leftmost to rightmost.
redundantPoint.push(0);
index = 0;
for (i=path.pathPoints.length-1; i>0; i--) {
* Get distance and round to nearest hundredth of a point.
* If points are closer than the tolerance, consider them
* coincident.
anchorDistance = getPairDistance(path.pathPoints[index].anchor, path.pathPoints[i].anchor);
anchorDistance = roundToPrecision(anchorDistance, 0.01);
if (anchorDistance < tolerance) {
redundantPoint.unshift(i);
else {
break;
index = i;
* If we haven't used up all the points, start searching forwards
* up to the point we stopped searching backwards. Test the
* current point against the next point. If the next point matches push
* its index onto the redundantPoint array. When the first one doesn't match,
* check if the redundantPoint array has more than one index. If so add it
* to the redundantPointSets array. Then clean the redundantPoint array
* and push on the next point index.
if(i > 0) {
for (j=0; j<i; j++) {
anchorDistance = getPairDistance(path.pathPoints[j].anchor, path.pathPoints[j+1].anchor);
anchorDistance = roundToPrecision(anchorDistance, 0.01);
if (anchorDistance < tolerance) {
redundantPoint.push(j+1);
else {
if (redundantPoint.length > 1) {
redundantPointSets.push(redundantPoint);
redundantPoint = [];
redundantPoint.push(j+1);
* Push the last redundantPoint array onto the redundantPointSets array if
* its length is greater than one.
if (redundantPoint.length > 1) {
redundantPointSets.push(redundantPoint);
if (anySelected) {
for (i=0; i<redundantPointSets.length; i++) {
var currentPointSet = redundantPointSets[i];
selected = false;
for (j=0; j<currentPointSet.length; j++) {
if (path.pathPoints[currentPointSet[j]].selected ==
PathPointSelection.ANCHORPOINT) {
selected = true;
if (selected) {
selectedRedundantPointSets.push(currentPointSet);
else if (allSelected) {
for (i=0; i<redundantPointSets.length; i++) {
var currentPointSet = redundantPointSets[i];
for (j=currentPointSet.length-1; j>=0; j--) {
var currentPoint = path.pathPoints[currentPointSet[j]];
if (currentPoint.selected == PathPointSelection.ANCHORPOINT) {
selectedRedundantPoint.unshift(currentPointSet[j]);
else {
break;
if (j > 0) {
for (k=0; k<j; k++) {
var currentPoint = path.pathPoints[currentPointSet[k]];
if (currentPoint.selected == PathPointSelection.ANCHORPOINT) {
selectedRedundantPoint.push(currentPointSet[k]);
else {
if (selectedRedundantPoint.length > 1) {
selectedRedundantPointSets.push(selectedRedundantPoint);
selectedRedundantPoint = [];
if (selectedRedundantPoint.length > 1) {
selectedRedundantPointSets.push(selectedRedundantPoint);
selectedRedundantPoint = [];
else {
selectedRedundantPointSets = redundantPointSets;
return(selectedRedundantPointSets);
* Function: countRedundantPoints
* Description:
* Count the number of redundant points given a redundantPointSets array as
* the first parameter.
function countRedundantPoints(redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint) {
var i = 0;
var redundantPoints = 0;
var pointsKept = 1;
if (doKeepLeadingPoint && doKeepTrailingPoint) {
pointsKept = 2;
for (i=0; i<redundantPointSets.length; i++) {
redundantPoints += redundantPointSets[i].length - pointsKept;
return (redundantPoints);
* Function: countSelectedPoints
* Description:
* Count the number of selected anchor points given a path as the first parameter.
function countSelectedPoints(path) {
var i = 0;
var selectedPoints = 0;
for (i=0; i<path.pathPoints.length; i++) {
if (path.pathPoints[i].selected == PathPointSelection.ANCHORPOINT) {
selectedPoints++;
return (selectedPoints);
* Function: removeRedundantPoints
* Description:
* Remove redundant points from a path input as the first parameter. The
* second input parameter should be an array of arrays containing the
* indicies of redundant points, as returned from function
* findRedundantPoints(). From each set of indicies, the first point is
* retained, and the subsequent points are removed from the path. Care is
* taken to preserve the proper leftDirection and rightDirection handles,
* as well as the proper PointType for the remaining point. Returns
* the number of points removed.
function removeRedundantPoints(path, redundantPointSets, keepLeadingPoint, keepTrailingPoint, keepAveragedPoint){
var i = 0;
var j = 0;
var pointsToRemove = new Array();
var tempLayer;
var tempPath;
* For each array of redundant point indicies in array redundantPointSets,
* modify the leadingPoint to have all the properties needed to properly
* describe the set of coincident points.
for (i=0; i<redundantPointSets.length; i++) {
var x = 0;
var y = 0;
var currentPointSet = redundantPointSets[i];
var leadingPoint = path.pathPoints[currentPointSet[0]];
var trailingPoint = path.pathPoints[currentPointSet[currentPointSet.length-1]];
if (keepLeadingPoint && keepTrailingPoint) {
* JAH 090401 REVISIT COMMENT WHEN DONE
* If we are keeping two points, the leftDirection of the leading point
* and rightDirection of the trailing point are already fixed. We have to
* synthesize the inward facing handles, and choose pointType of the two points.
* To allow easy manipultion of the inner handles without disturbing the fixed
* handles, make the points PointType.CORNER. For the direction handles, make
* them parallel to their respective paired handle, and extend them half the
* distance between the two remaining points.
var averagedPoint;
var theta;
var deltaX;
var deltaY;
var pairDistance;
var leftDistance;
var rightDistance;
var firstRemovedIndex = 1;
if (currentPointSet.length > 2) {
averagedPoint = path.pathPoints[currentPointSet[1]];
else {
tempLayer = app.activeDocument.layers.add();
tempLayer.name = "Temp";
tempPath = tempLayer.pathItems.add();
averagedPoint = tempPath.pathPoints.add();
if( currentPointSet.length <= 2 || !keepAveragedPoint ) {
* Use just the leading and trailing points. Create inward facing
* direction handles for the two endpoints based on the relationship
* of the angles between each endpoint and the average point.
* For each endpoint, calcualte the angle of the endpoint to the
* average point, and the endpoint to the other endpoint. Combine
* the angles. The base angle for the inward facing direction handle
* is the angle that points it towards the average point. Add to this
* angle, a multiple of the difference between the angle just mentioned,
* and the angle to the other endpoint. Adding this difference angle
* will bias the curve towards the average point. Finally, set the
* length of the direction handle as the distance from the endpoint
* to the average point multiplied by a factor.
var thetaAverage;
var thetaPair;
var tweakThetaToOppositeEndpoint = 1.0;
var tweakPairDistance = 0.5;
* Since the leading and trailing points will have direction handles pointing
* in different directions, these points must be corner points by necessity.
leadingPoint.pointType = PointType.CORNER;
trailingPoint.pointType = PointType.CORNER;
* Create new average point.
for (j=0; j<currentPointSet.length; j++) {
x += path.pathPoints[currentPointSet[j]].anchor[0];
y += path.pathPoints[currentPointSet[j]].anchor[1];
x /= currentPointSet.length;
y /= currentPointSet.length;
averagedPoint.anchor = Array(x, y);
averagedPoint.leftDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
averagedPoint.rightDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
averagedPoint.pointType = PointType.CORNER;
/* Calcualte new leading point rightDirection */
pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
thetaAverage = getPairTheta(leadingPoint.anchor, averagedPoint.anchor);
thetaPair = getPairTheta(leadingPoint.anchor, trailingPoint.anchor);
theta = thetaAverage + tweakThetaToOppositeEndpoint * (thetaAverage - thetaPair);
/*alert("thetaAverage="+thetaAverage+" thetaPair="+thetaPair" theta="+theta);*/
deltaX = Math.cos(theta) * tweakPairDistance * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistance * pairDistance;
leadingPoint.rightDirection = Array(leadingPoint.anchor[0]+deltaX, leadingPoint.anchor[1]+deltaY);
/* Calcualte new trailing point leftDirection */
pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
thetaAverage = getPairTheta(trailingPoint.anchor, averagedPoint.anchor);
thetaPair = getPairTheta(trailingPoint.anchor, leadingPoint.anchor);
theta = thetaAverage + tweakThetaToOppositeEndpoint * (thetaAverage - thetaPair);
/*alert("thetaAverage="+thetaAverage+" thetaPair="+thetaPair" theta="+theta);*/
deltaX = Math.cos(theta) * tweakPairDistance * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistance * pairDistance;
trailingPoint.leftDirection = Array(trailingPoint.anchor[0]+deltaX, trailingPoint.anchor[1]+deltaY);
else {
* Use just the leading and trailing points, along with a third point added
* at the average of all the removed points. This point will act to anchor
* the curve at the average point. It will also allow the leading and
* trailing points to be smooth points, allowing for a continuous
* curve through them.
* The inward facing direction handles for the two endpoints will be
* shortened extensions of the outward facing direction handles for these
* points. The length of the handles will be a multiple of the
* distance from the direction handle to the average point.
* For the average point, the direction handles will be parallel to the
* angle formed by the angle between the two endpoints. The length
* of the direction handles for this point will be a different multiple
* of the length from each endpoint to the average point.
var thetaAverage;
var thetaPair;
var tweakPairDistanceForAveraged = 0.5;
var tweakPairDistanceForEndpoint = 0.25;
* Since the leading and trailing points will have direction handles that
* are parallel, make them smooth points.
leadingPoint.pointType = PointType.SMOOTH;
trailingPoint.pointType = PointType.SMOOTH;
/* We will be keeping one more point, the averaged point. */
firstRemovedIndex = 2;
* Create new average point.
for (j=0; j<currentPointSet.length; j++) {
x += path.pathPoints[currentPointSet[j]].anchor[0];
y += path.pathPoints[currentPointSet[j]].anchor[1];
x /= currentPointSet.length;
y /= currentPointSet.length;
averagedPoint.anchor = Array(x, y);
averagedPoint.leftDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
averagedPoint.rightDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
averagedPoint.pointType = PointType.SMOOTH;
/* Calcualte new averaged point leftDirection */
pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
theta = getPairTheta(leadingPoint.anchor, trailingPoint.anchor);
/*alert("theta="+theta);*/
if (theta > 0) {
theta += Math.PI;
else {
theta += -Math.PI;
deltaX = Math.cos(theta) * tweakPairDistanceForAveraged * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistanceForAveraged * pairDistance;
averagedPoint.leftDirection = Array(averagedPoint.anchor[0]+deltaX, averagedPoint.anchor[1]+deltaY);
/* Calcualte new averaged point rightDirection */
pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
theta = getPairTheta(trailingPoint.anchor, averagedPoint.anchor);
/*alert("theta="+theta);*/
if (theta > 0) {
theta += Math.PI;
else {
theta += -Math.PI;
deltaX = Math.cos(theta) * tweakPairDistanceForAveraged * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistanceForAveraged * pairDistance;
averagedPoint.rightDirection = Array(averagedPoint.anchor[0]+deltaX, averagedPoint.anchor[1]+deltaY);
/* Calculate direction handles for leading and trailing points */
pairDistance = getPairDistance(leadingPoint.anchor, trailingPoint.anchor);
leftDistance = getPairDistance(leadingPoint.anchor, leadingPoint.leftDirection);
if (leftDistance > 0) {
theta = getPairTheta(leadingPoint.anchor, leadingPoint.leftDirection);
/*alert("theta="+theta);*/
if (theta > 0) {
theta += Math.PI;
else {
theta += -Math.PI;
pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
deltaX = Math.cos(theta) * tweakPairDistanceForEndpoint * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistanceForEndpoint * pairDistance;
leadingPoint.rightDirection = Array(leadingPoint.anchor[0]+deltaX, leadingPoint.anchor[1]+deltaY);
else {
leadingPoint.rightDirection = leadingPoint.anchor;
rightDistance = getPairDistance(trailingPoint.anchor, trailingPoint.rightDirection);
if (rightDistance > 0) {
theta = getPairTheta(trailingPoint.anchor, trailingPoint.rightDirection);
if (theta > 0) {
theta += Math.PI;
else {
theta += -Math.PI;
pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
deltaX = Math.cos(theta) * tweakPairDistanceForEndpoint * pairDistance;
deltaY = Math.sin(theta) * tweakPairDistanceForEndpoint * pairDistance;
trailingPoint.leftDirection = Array(trailingPoint.anchor[0]+deltaX, trailingPoint.anchor[1]+deltaY);
else {
trailingPoint.leftDirection = trailingPoint.anchor;
* Push all points other than the leading and trailing onto the pointsToRemove array
* for later removal. We can't remove them while we are working with later sets.
for (j=firstRemovedIndex; j<currentPointSet.length-1; j++) {
pointsToRemove.push(currentPointSet[j]);
else {
* If we are only keeping one point, we will work with the leading point.
* First, calculate the relative distances and angles of the direction handle for
* the leadingPoint leftDirection handle and the trailingPoint rightDirection
* handle. These values will be used to help properly construct the remaining
* point.
var leftDistance = getPairDistance(leadingPoint.anchor, leadingPoint.leftDirection);
var rightDistance = getPairDistance(trailingPoint.anchor, trailingPoint.rightDirection);
var leftTheta = getPairTheta(leadingPoint.anchor, leadingPoint.leftDirection);
var rightTheta = getPairTheta(trailingPoint.anchor, trailingPoint.rightDirection);
* If we are keeping the leadingPoint, calculate a relative rightDirection handle
* based on the trailingPoint rightDistance and rightTheta. If we are keeping the
* trailingPoint, copy its anchor and rightDirection handle to the leadingPoint,
* and calculate a relative leftDirection handle based on the leadingPoint
* leftDistance and leftTheta. If we are to keep neither leading or trailing point,
* average the position of all the redundant points and calcuate direction handles
* based on the appropriate values.
if (keepLeadingPoint) {
x = leadingPoint.anchor[0] + (Math.cos(rightTheta) * rightDistance);
y = leadingPoint.anchor[1] + (Math.sin(rightTheta) * rightDistance);
leadingPoint.rightDirection = Array(x, y);
else if (keepTrailingPoint) {
leadingPoint.anchor = trailingPoint.anchor;
leadingPoint.rightDirection = trailingPoint.rightDirection;
x = leadingPoint.anchor[0] + (Math.cos(leftTheta) * leftDistance);
y = leadingPoint.anchor[1] + (Math.sin(leftTheta) * leftDistance);
leadingPoint.leftDirection = Array(x, y);
else {
for (j=0; j<currentPointSet.length; j++) {
x += path.pathPoints[currentPointSet[j]].anchor[0];
y += path.pathPoints[currentPointSet[j]].anchor[1];
x /= currentPointSet.length;
y /= currentPointSet.length;
leadingPoint.anchor = Array(x, y);
x = leadingPoint.anchor[0] + (Math.cos(leftTheta) * leftDistance);
y = leadingPoint.anchor[1] + (Math.sin(leftTheta) * leftDistance);
leadingPoint.leftDirection = Array(x, y);
x = leadingPoint.anchor[0] + (Math.cos(rightTheta) * rightDistance);
y = leadingPoint.anchor[1] + (Math.sin(rightTheta) * rightDistance);
leadingPoint.rightDirection = Array(x, y);
* If the distance for a handle is less than half a point and rounds to zero,
* retract that handle fully by setting that direction handle equal to the anchor
* point. This will keep angles consistent for smooth points.
if (Math.round(leftDistance) == 0) {
leadingPoint.leftDirection = leadingPoint.anchor;
if (Math.round(rightDistance) == 0) {
leadingPoint.rightDirection = leadingPoint.anchor;
* Handle the PointType in a minimal manner. If keeping the leadingPoint or keeping
* the trailingPoint, keep the PointType of that point if possible. If both handles
* are extended, measure the angles of the two direction handles. If both handles
* have the same angle relative to the X axis within a tolerance, the PointType
* can be SMOOTH, otherwise it must be CORNER. If the point type is SMOOTH, ensure
* the direction handles are corrected to be exactly 180 degrees apart.
* If not specifically keeping the leading or trailing point and only one handle is
* extended, base the pointType on the the leadingPoint if only the left handle is
* extended and the trailingPoint if only the right handle is extended.
if (Math.round(leftDistance) > 0 && Math.round(rightDistance) > 0) {
var absdiff = Math.abs(leftTheta-rightTheta);
var error = Math.PI - absdiff;
/*alert("leftTheta="+leftTheta+" rightTheta="+rightTheta+" absdiff="+absdiff+" error="+error);*/
if (Math.abs(error) < 0.02) {
if (keepTrailingPoint) {
leadingPoint.pointType = trailingPoint.pointType;
else if (!keepLeadingPoint) {
leadingPoint.pointType = PointType.SMOOTH;
if (leadingPoint.pointType == PointType.SMOOTH) {
if (keepTrailingPoint) {
x = leadingPoint.anchor[0] + (Math.cos(Math.PI + rightTheta) * leftDistance);
y = leadingPoint.anchor[1] + (Math.sin(Math.PI + rightTheta) * leftDistance);
leadingPoint.leftDirection = Array(x, y);
else {
x = leadingPoint.anchor[0] + (Math.cos(Math.PI + leftTheta) * rightDistance);
y = leadingPoint.anchor[1] + (Math.sin(Math.PI + leftTheta) * rightDistance);
leadingPoint.rightDirection = Array(x, y);
else {
leadingPoint.pointType = PointType.CORNER;
else if (keepTrailingPoint) {
leadingPoint.pointType = trailingPoint.pointType;
else if (!keepLeadingPoint && rightDistance > 0) {
leadingPoint.pointType = trailingPoint.pointType;
* Push all other points onto the pointsToRemove array for later removal. We can't
* remove them while we are working with later sets.
for (j=1; j<currentPointSet.length; j++) {
pointsToRemove.push(currentPointSet[j]);
* Sort the pointsToRemove array and then remove the points in reverse order, so the indicies
* remain coherent during the removal.
pointsToRemove.sort(function (a,b) { return a-b });
for (i=pointsToRemove.length-1; i>=0; i--) {
var pointToRemove = path.pathPoints[pointsToRemove[i]];
pointToRemove.remove();
if (tempPath) {
tempPath.remove();
if (tempLayer) {
tempLayer.remove();
return (pointsToRemove.length);
* Function: selectRedundantPoints
* Description:
* Select redundant points on a path input as the first parameter. The
* second input parameter should be an array of arrays containing the
* indicies of redundant points, as returned from function
* findRedundantPoints(). If there are redundant points, deselect all points
* on the path and select the ANCHORPOINT of each redundant point. If there
* are no redundant points on the path, do nothing.
function selectRedundantPoints(path, redundantPointSets){
var i = 0;
var j = 0;
if (redundantPointSets.length > 0) {
for (i=0; i<path.pathPoints.length; i++) {
path.pathPoints[i].selected = PathPointSelection.NOSELECTION;
for (i=0; i<redundantPointSets.length; i++) {
var currentPointSet = redundantPointSets[i];
for (j=0; j<currentPointSet.length; j++) {
path.pathPoints[currentPointSet[j]].selected = PathPointSelection.ANCHORPOINT;
* Function: unlockPath
* Description:
* For a path input as the first parameter, unlock the path and any locked
* parent object. Return an array of objects that have been unlocked.
function unlockPath(path){
var unlockedObjects = new Array();
var parentObjects = new Array();
var currentObject = path;
var i = 0;
while (currentObject.typename != "Document") {
parentObjects.unshift(currentObject);
currentObject = currentObject.parent;
for (i=0; i<parentObjects.length; i++) {
if (parentObjects[i].locked) {
parentObjects[i].locked = false;
unlockedObjects.unshift(parentObjects[i]);
return unlockedObjects;
* Function: lockObjects
* Description:
* For a set of objects as the first parameter, lock each object.
function lockObjects(objects){
var i = 0;
for (i=0; i<objects.length; i++) {
objects[i].locked = true;
* Function: docGetSelectedPaths
* Description:
* Get all the selected paths for the docRef argument passed in as
* a parameter. The second parameter is a boolean that controls if compound
* path items are included (default true), and the third parameter is a
* boolean that controls if locked objects are included (default false).
* Returns an array of paths.
function docGetSelectedPaths(docRef, includeCompound, includeLocked){
var qualifiedPaths = new Array();
var i = 0;
var j = 0;
var nextPath = null;
var currentSelection = new Array();
var nextSelection = docRef.selection;
if (includeCompound == null) {
includeCompound = true;
if (includeLocked == null) {
includeLocked = false;
do {
currentSelection = nextSelection;
nextSelection = [];
for(i=0; i<currentSelection.length; i++){
var currentObject=currentSelection[i];
if (currentObject.typename == "PathItem") {
if (includeLocked || !(currentObject.locked ||
currentObject.layer.locked)) {
qualifiedPaths.push(currentObject);
else if (currentObject.typename == "CompoundPathItem") {
if (includeCompound &&
(includeLocked || !(currentObject.locked ||
currentObject.layer.locked))) {
* For more complex compound paths (e.g. concentric circular bands),
* in CS3 the CompoundPathItem object's pathItems array is empty.
* Inspection of the paths in a document shows the paths contained
* in the CompoundPathItem have groups as parents. To get around
* this seeming bug, in addition to using the pathItems array,
* which still contains individual paths, we also search through
* all the groups in the document adding paths whose parent
* is the CompoundPathItem object.
* WARNING this takes non-negligible time in large documents.
for (j=0; j<currentObject.pathItems.length; j++) {
qualifiedPaths.push(currentObject.pathItems[j]);
for (j=0; j<docRef.groupItems.length; j++) {
if (docRef.groupItems[j].parent == currentObject) {
nextSelection.push(docRef.groupItems[j]);
else if (currentObject.typename == "GroupItem") {
for (j=0; j<currentObject.pathItems.length; j++){
nextSelection.push(currentObject.pathItems[j]);
for (j=0; j<currentObject.compoundPathItems.length; j++){
nextSelection.push(currentObject.compoundPathItems[j]);
for (j=0; j<currentObject.groupItems.length; j++){
nextSelection.push(currentObject.groupItems[j]);
else if (currentObject.typename == "Layer") {
for (j=0; j<currentObject.pathItems.length; j++){
nextSelection.push(currentObject.pathItems[j]);
for (j=0; j<currentObject.compoundPathItems.length; j++){
nextSelection.push(currentObject.compoundPathItems[j]);
for (j=0; j<currentObject.groupItems.length; j++){
nextSelection.push(currentObject.groupItems[j]);
for (j=0; j<currentObject.layers.length; j++){
nextSelection.push(currentObject.layers[j]);
} while (nextSelection.length > 0);
return qualifiedPaths;
* Function: docGetAllPaths
* Description:
* Get all the paths for the docRef argument passed in as a parameter.
* The second parameter is a boolean that controls if compound path items are
* included (default true), and the third parameter is a boolean that controls
* if locked objects are included (default false). Returns an array of paths.
function docGetAllPaths(docRef, includeCompound, includeLocked) {
var qualifiedPaths = new Array();
var i = 0;
var nextPath = null;
if (includeCompound == null) {
includeCompound = true;
if (includeLocked == null) {
includeLocked = false;
for (i=0; i<docRef.pathItems.length; i++) {
nextPath = docRef.pathItems[i];
if (!includeCompound && nextPath.parent.typename == "CompoundPathItem") {
continue;
if (!includeLocked && (nextPath.layer.locked == true || nextPath.locked == true)) {
continue;
qualifiedPaths.push(nextPath);
return qualifiedPaths;
* Function: roundToPrecision
* Description:
* Round a number input as the first parameter to a given precision. The
* second input parameter is the precision to round to (typically a power of
* 10, like 0.1). Returns the rounded value.
function roundToPrecision(value, precision) {
var result;
result = value / precision;
result = Math.round(result);
result = result * precision;
return (result);
* Main code
var dlgInit = new Window('dialog', 'Redundant Path Points');
doInitDialog(dlgInit);
var exitError;
var tolerance = 1 * (dlgInit.tolerancePnl.editText.text);
var doAnalyze = dlgInit.functionPnl.doAnalyze.value;
var doRemove = dlgInit.functionPnl.doRemove.value;
var doSelect = dlgInit.functionPnl.doSelect.value;
var doKeepLeadingPoint = dlgInit.removalPnl.doKeepLeadingPoint.value;
var doKeepTrailingPoint = dlgInit.removalPnl.doKeepTrailingPoint.value;
var doKeepAveragedPoint = dlgInit.removalPnl.doKeepAveragedPoint.value;
var includeCompound = dlgInit.optionPnl.includeCompound.value;
var includeLocked = dlgInit.optionPnl.includeLocked.value;
var ignoreSelected = dlgInit.selectionPnl.ignoreSelected.value;
var anySelected = dlgInit.selectionPnl.anySelected.value;
var allSelected = dlgInit.selectionPnl.allSelected.value;
var docRef=app.activeDocument;
var pathsToProcess = new Array();
var i = 0;
var j = 0;
var totalPaths = 0;
var totalPointsWithRedundancy = 0;
var totalPointsToRemove = 0;
var totalPointsRemoved = 0;
var totalPointsStarting = 0;
var totalPointsRemaining = 0;
var totalPointsSelected = 0;
var redundantPointSets = new Array();
var unlockedObjects = new Array();
try {
if (exitError != 0) {
throw("exit");
exitError = 99;
if (docRef.selection.length > 0) {
pathsToProcess = docGetSelectedPaths(docRef, includeCompound, includeLocked);
else {
var doAll = confirm("Run script for all paths in document?");
if (doAll) {
pathsToProcess = docGetAllPaths(docRef, includeCompound, includeLocked);
if (doSelect) {
if (includeLocked) {
exitError = 2;
throw("exit");
if (!ignoreSelected) {
exitError = 3;
throw("exit");
docRef.selection = null;
for (i=0; i<pathsToProcess.length; i++) {
redundantPointSets = findRedundantPoints(pathsToProcess[i], tolerance, anySelected, allSelected);
totalPaths++;
totalPointsWithRedundancy += redundantPointSets.length;
totalPointsToRemove += countRedundantPoints(redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint);
totalPointsStarting += pathsToProcess[i].pathPoints.length;
totalPointsSelected += countSelectedPoints(pathsToProcess[i]);
if (doRemove) {
if (includeLocked) {
unlockedObjects = unlockPath(pathsToProcess[i]);
else {
unlockedObjects = [];
totalPointsRemoved += removeRedundantPoints(pathsToProcess[i], redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint, doKeepAveragedPoint);
if (unlockedObjects.length > 0) {
lockObjects(unlockedObjects);
if (doSelect) {
selectRedundantPoints(pathsToProcess[i], redundantPointSets);
totalPointsRemaining += pathsToProcess[i].pathPoints.length;
var dlgResults = new Window('dialog', 'Redundant Path Points');
doResultsDialog(dlgResults,
totalPaths,
totalPointsWithRedundancy,
totalPointsToRemove,
totalPointsRemoved,
totalPointsStarting,
totalPointsRemaining,
totalPointsSelected,
tolerance);
catch(er)
if (exitError == 2) {
alert("Select function not supported in conjunction with 'Include Locked Items' option.");
if (exitError == 3) {
alert("Select function supported only with 'Ignore' selection restriction.");
if (exitError == 99) {
alert("ACK! Unexplained error\n");
* Dialog Code
* Function: doInitDialog
function doInitDialog(dlgInit) {
var defaultTolerance = 5.0;
var maxSliderTolerance = 5;
/* Add radio buttons to control functionality */
dlgInit.functionPnl = dlgInit.add('panel', undefined, 'Function:');
(dlgInit.functionPnl.doAnalyze = dlgInit.functionPnl.add('radiobutton', undefined, 'Analyze' )).helpTip = "Find and count redundant points.";
(dlgInit.functionPnl.doRemove = dlgInit.functionPnl.add('radiobutton', undefined, 'Remove' )).helpTip = "Find and remove redundant points.";
(dlgInit.functionPnl.doSelect = dlgInit.functionPnl.add('radiobutton', undefined, 'Select' )).helpTip = "Find and select redundant points.\nWARNING:Manual removal of selected redundant points can change the shape of your curves.\nTips:Hiding bounding box helps to see which points are selected. Modify selection as desired and rerun script to remove specific redundant points.";
dlgInit.functionPnl.doRemove.value = true;
dlgInit.functionPnl.orientation='row';
/* Add radio buttons to control point selection */
dlgInit.selectionPnl = dlgInit.add('panel', undefined, 'Point Selection State:');
(dlgInit.selectionPnl.ignoreSelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'Ignore')).helpTip="Process redundant points on a path regardless of their selection state.";
(dlgInit.selectionPnl.allSelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'All')).helpTip="Process redundant points on a path only if each of them is selected.";
(dlgInit.selectionPnl.anySelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'Any')).helpTip="Process redundant points on a path if any one of them is selected.";
dlgInit.selectionPnl.allSelected.value = true;
dlgInit.selectionPnl.orientation='row';
/* Add a checkbox to control options */
dlgInit.optionPnl = dlgInit.add('panel', undefined, 'Other Options:');
(dlgInit.optionPnl.includeCompound = dlgInit.optionPnl.add('checkbox', undefined, 'Include Compound Path Items?')).helpTip="Work on compound path items.";
(dlgInit.optionPnl.includeLocked = dlgInit.optionPnl.add('checkbox', undefined, 'Include Locked Items?')).helpTip="Work on locked items or items in locked layers.";
dlgInit.optionPnl.includeCompound.value = true;
dlgInit.optionPnl.includeLocked.value = false;
dlgInit.optionPnl.alignChildren='left';
dlgInit.optionPnl.orientation='column';
/* Add a slider and edit box for user entered tolerance */
dlgInit.tolerancePnl = dlgInit.add('panel', undefined, 'Tolerance (in PostScript points):');
(dlgInit.tolerancePnl.slide = dlgInit.tolerancePnl.add('slider', undefined, defaultTolerance, 0.01, maxSliderTolerance)).helpTip="Use slider to set a tolerance value in hundredths of a point.";
(dlgInit.tolerancePnl.editText = dlgInit.tolerancePnl.add('edittext', undefined, defaultTolerance)).helpTip="Enter a tolerance value. Values greater then 5.0 or more precise than 1/100 point can be manually entered here.";
dlgInit.tolerancePnl.editText.characters = 5;
dlgInit.tolerancePnl.orientation='row';
dlgInit.tolerancePnl.slide.onChange = toleranceSliderChanged;
dlgInit.tolerancePnl.editText.onChange = toleranceEditTextChanged;
/* Add a panel control removal options */
dlgInit.removalPnl = dlgInit.add('panel', undefined, 'Removal Options:');
(dlgInit.removalPnl.doKeepLeadingPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Leading Point' )).helpTip = "Keep the leading point (lowest path index, lowest prior to origin cross for closed path).";
(dlgInit.removalPnl.doKeepTrailingPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Trailing Point' )).helpTip = "Keep the trailing point (highest path index, highest following origin cross for closed path).";
(dlgInit.removalPnl.doKeepAveragedPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Averaged Point' )).helpTip = "Keep an averaged point to help smooth transitions.";
dlgInit.removalPnl.keepTips = dlgInit.removalPnl.add('statictext', undefined, 'Keeping neither will cause position of remaining point to be averaged. Keeping both will anchor two ends of a segment while removing intermediate redundant points. An averaged point helps smooth transitions.', {multiline:'true'} );
dlgInit.removalPnl.doKeepLeadingPoint.value = false;
dlgInit.removalPnl.doKeepTrailingPoint.value = false;
dlgInit.removalPnl.doKeepAveragedPoint.value = false;
dlgInit.removalPnl.alignChildren='left';
dlgInit.removalPnl.orientation='column';
/* Add execution buttons */
dlgInit.executeGrp = dlgInit.add('group', undefined, 'Execute:');
dlgInit.executeGrp.orientation='row';
dlgInit.executeGrp.buildBtn1= dlgInit.executeGrp.add('button',undefined, 'Cancel', {name:'cancel'});
dlgInit.executeGrp.buildBtn2 = dlgInit.executeGrp.add('button', undefined, 'OK', {name:'ok'});
dlgInit.executeGrp.buildBtn1.onClick= initActionCanceled;
dlgInit.executeGrp.buildBtn2.onClick= initActionOk;
dlgInit.frameLocation = [100, 100];
dlgInit.alignChildren='fill';
dlgInit.show();
return dlgInit;
function initActionCanceled() {
exitError = 1;
dlgInit.hide();
function initActionOk() {
var proceed = true;
exitError = 0;
if (dlgInit.tolerancePnl.editText.text > 5.0) {
proceed = confirm("Tolerance entered greater than 5.0 PostScript points. Proceed?");
if (proceed) {
dlgInit.hide();
function toleranceSliderChanged() {
dlgInit.tolerancePnl.editText.text = roundToPrecision(dlgInit.tolerancePnl.slide.value, 0.01);
function toleranceEditTextChanged() {
if (dlgInit.tolerancePnl.editText.text > 5000) {
dlgInit.tolerancePnl.editText.text = 5000;
dlgInit.tolerancePnl.slide.value = roundToPrecision(dlgInit.tolerancePnl.editText.text, 0.01);
* Function: doResultsDialog
function doResultsDialog(dlgResults,
totalPaths,
totalPointsWithRedundancy,
totalPointsToRemove,
totalPointsRemoved,
totalPointsStarting,
totalPointsRemaining,
totalPointsSelected,
tolerance) {
/* Add static text to display results */
dlgResults.resultsPnl = dlgResults.add('panel', undefined, 'Results:');
dlgResults.resultsPnl.totalPaths = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPaths.txt = dlgResults.resultsPnl.totalPaths.add('statictext', undefined, 'Paths processed: ');
dlgResults.resultsPnl.totalPaths.txt.alignment = 'right';
dlgResults.resultsPnl.totalPaths.val = dlgResults.resultsPnl.totalPaths.add('statictext', undefined, totalPaths);
dlgResults.resultsPnl.totalPaths.val.characters = 10;
dlgResults.resultsPnl.totalPaths.val.helpTip = "The number of paths processed.";
dlgResults.resultsPnl.totalPointsSelected = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsSelected.txt = dlgResults.resultsPnl.totalPointsSelected.add('statictext', undefined, 'Total points selected: ');
dlgResults.resultsPnl.totalPointsSelected.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsSelected.val = dlgResults.resultsPnl.totalPointsSelected.add('statictext', undefined, totalPointsSelected);
dlgResults.resultsPnl.totalPointsSelected.val.characters = 10;
dlgResults.resultsPnl.totalPointsSelected.val.helpTip = "The total number of points initially selected.";
dlgResults.resultsPnl.separator0 = dlgResults.resultsPnl.add('panel');
dlgResults.resultsPnl.totalPointsWithRedundancy = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsWithRedundancy.txt = dlgResults.resultsPnl.totalPointsWithRedundancy.add('statictext', undefined, 'Points with redundancy: ');
dlgResults.resultsPnl.totalPointsWithRedundancy.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsWithRedundancy.val = dlgResults.resultsPnl.totalPointsWithRedundancy.add('statictext', undefined, totalPointsWithRedundancy);
dlgResults.resultsPnl.totalPointsWithRedundancy.val.characters = 10;
dlgResults.resultsPnl.totalPointsWithRedundancy.val.helpTip = "The number of points with redundancy.";
dlgResults.resultsPnl.totalPointsToRemove = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsToRemove.txt = dlgResults.resultsPnl.totalPointsToRemove.add('statictext', undefined, 'Redundant points to remove: ');
dlgResults.resultsPnl.totalPointsToRemove.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsToRemove.val = dlgResults.resultsPnl.totalPointsToRemove.add('statictext', undefined, totalPointsToRemove);
dlgResults.resultsPnl.totalPointsToRemove.val.characters = 10;
dlgResults.resultsPnl.totalPointsToRemove.val.helpTip = "The number of redundant points that would be removed.";
dlgResults.resultsPnl.totalPointsRemoved = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsRemoved.txt = dlgResults.resultsPnl.totalPointsRemoved.add('statictext', undefined, 'Redundant points removed: ');
dlgResults.resultsPnl.totalPointsRemoved.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsRemoved.val = dlgResults.resultsPnl.totalPointsRemoved.add('statictext', undefined, totalPointsRemoved);
dlgResults.resultsPnl.totalPointsRemoved.val.characters = 10;
dlgResults.resultsPnl.totalPointsRemoved.val.helpTip = "The number of redundant points that were removed.";
dlgResults.resultsPnl.separator1 = dlgResults.resultsPnl.add('panel');
dlgResults.resultsPnl.totalPointsStarting = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsStarting.txt = dlgResults.resultsPnl.totalPointsStarting.add('statictext', undefined, 'Total points starting: ');
dlgResults.resultsPnl.totalPointsStarting.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsStarting.val = dlgResults.resultsPnl.totalPointsStarting.add('statictext', undefined, totalPointsStarting);
dlgResults.resultsPnl.totalPointsStarting.val.characters = 10;
dlgResults.resultsPnl.totalPointsStarting.helpTip = "The total number of points before processing.";
dlgResults.resultsPnl.totalPointsRemaining = dlgResults.resultsPnl.add('group');
dlgResults.resultsPnl.totalPointsRemaining.txt = dlgResults.resultsPnl.totalPointsRemaining.add('statictext', undefined, 'Total points remaining: ');
dlgResults.resultsPnl.totalPointsRemaining.txt.alignment = 'right';
dlgResults.resultsPnl.totalPointsRemaining.val = dlgResults.resultsPnl.totalPointsRemaining.add('statictext', undefined, totalPointsRemaining);
dlgResults.resultsPnl.totalPointsRemaining.val.characters = 10;
dlgResults.resultsPnl.totalPointsRemaining.val.helpTip = "The total number of points after processing.";
dlgResults.resultsPnl.alignChildren='right';
dlgResults.resultsPnl.orientation='column';
dlgResults.note = dlgResults.add('group');
dlgResults.note.txt = dlgResults.note.add('statictext', undefined, 'Combined results across paths qualified based on options');
dlgResults.tolerance = dlgResults.add('group');
dlgResults.tolerance.txt = dlgResults.tolerance.add('statictext', undefined, "Tolerance applied (in PostScript points): ");
dlgResults.tolerance.val = dlgResults.tolerance.add('statictext', undefined, tolerance);
/* Add execution buttons */
dlgResults.executeGrp = dlgResults.add('group', undefined, 'Execute:');
dlgResults.executeGrp.orientation='row';
dlgResults.executeGrp.buildBtn1= dlgResults.executeGrp.add('button',undefined, 'OK', {name:'ok'});
dlgResults.executeGrp.buildBtn1.onClick= resultsActionOk;
dlgResults.frameLocation = [100, 100];
dlgResults.show();
function resultsActionOk() {
exitError = 0;
dlgResults.hide();
you have said you are using cc.
is it fully up to date?
are you not using cc2014?
when run from ESTK are you sure it is pointing to the correct illustrator?
Similar Messages
-
Problems with Freehand Illustrator CS4 script for Macs
A couple of us just downloaded the new Freehand to Illustrator CS4 script for Macs that was released on 5/17/10. Sometimes it works okay, but more often than not we get errors like 'ERROR: 1, Access is denied'. If we instead just open the Freehand file, the file comes in fine. What have been other people's experiences using this new script?
Mac OS X 10.5.5Is the problem there only at the time of conversion or even the FH files are not opening after running the script
Here is what I have done and may be you can follow the exact steps :
1) Create a folder FH on Desktop and paste only the FH files in the folder( My folder does not contain any other file apart from FH files)
2) Create a Folder AI on Desktop and keep it empty
3) File-> Scripts-> FreehandToAI
4) Select the source folder( FH)
5) Now select the destination folder(AI)
It gives the message after conversion "N freehand files are converted to AI". -
Hi.
I am creating a script for Illustrator CS4 using Word VBA.
When I execute the following code,
I get an error ,that is "ActiveX component can't create object".
Set app = CreateObject("Illustrator.Application")
This code works well on Illustrator CS2, but not on CS4.
I don't know why this error occured
Can some give me any advice?
Best Regard.
erieru103http://forums.adobe.com/people/erieru103Hi.
My script works by using CreateObject("Illustrator.Application.CS4").
Thank you for your advice.
The scripting guide says
"If you have multiple versions of Illustrator installed on the same machine and use the CreateObject
method to obtain an application reference, using "Illustrator.Application" creates a reference
to the latest Illustrator version. To specifically target an earlier version, use a version identifier at the
end of the string..."
There was CS3 version installed on my PC.
Before installing CS4, I have unstalled CS3.
Why the error occured??
Best regard.
erieru103 -
Comment convertir un lot de fichiers Illustrator au format PDF (avec "impressions prédéfinies…")
avec un SCRIPT ?In the Sample Scripts is one called Save as PDF. Use that.
-
How can I uninstall old versions of Adobe Illustrator?
How can I uninstall old versions of Adobe Illustrator?
This is for uninstalling CS2, but you might find it helpful. EDITED: but watch out, since I don't know if trashing any of these will remove currently needed Illustrator files, if you have a later version.
To uninstall Adobe Creative Suite in Mac OS 1 -- Double-click Activity Monitor.app in Applications/Utilities, select AHCRemind, and click Quit Process.
2 -- If you intend to install the product on a different computer, transfer the activation. (See “To transfer the product activation” on page 1.)
3 -- If you want to uninstall Adobe Acrobat, double-click the uninstaller in Applications/Adobe Acrobat 7.0 Professional, and follow the on-screen instructions.
4 -- If you want to uninstall Version Cue 2, double-click the uninstaller in Applications/Adobe VersionCue CS2, and follow the on-screen instructions.
Note: If the Version Cue uninstaller fails, see the alternative procecure, “To remove Version Cue manually” on page 4.
5 -- From the Applications folder, drag the following items, if present, to the trash: Note: After you drag the items to the trash in steps 5-8, you must empty the trash before you can reinstall
Adobe Creative Suite 2 on the same computer. • Adobe Acrobat 7.0 Professional • Adobe VersionCue CS2 • Adobe Bridge
• Adobe GoLive CS2 • Adobe Illustrator CS2 • Adobe InDesign CS2 • Adobe Photoshop CS2 • AdobeHelpCenter.app
6 -- From the Utilities folder, drag the following items, if present, to the trash: • Adobe Utilities • Adobe Updater.app
7 -- From the Library folder, drag the following items, if present, to the trash: • Application Support/Adobe/AdobeHelpData • Application Support/Adobe/Assistance • Application Support/Adobe/StartupScripts/Workflow Automation Scripts
• Preferences/Adobe/Workflow • Preferences/com.adobe.ActivationUtility.plist • Preferences/com.adobe.GoLive.plist • Preferences/Adobe Save For Web GL 8.0 Prefs
8 -- From the Users/[user name] folder, drag the following items, if present, to the trash: • Library/Preferences Panes/Opera Preferences
• Library/Caches/Opera Cache
• Documents/AdobeStockPhotos
To remove Version Cue manually (Mac OS only, not recommended)
If you’ve accidentally removed parts of the Version Cue installation manually or if the uninstaller fails, you have to remove the remaining installed Version Cue components manually.
1 -- From the Library/PreferencePanes folder, drag the Version Cue CS2.prefPane folder to the trash. 2 -- From the Library/Preferences folder, drag the com.adobe.versioncueCS2.plist file to the trash. 3 -- From the Library/StartupItems folder, drag the AdobeVersionCueCS2 folder to the trash. 4 -- From the Applications folder, drag the Adobe Version Cue CS2 folder to the trash.
5 -- From [user home]/Library/Preferences/Adobe, drag the Workflow folder to the trash. 6 -- (Optional) From the [user home]/Documents folder, drag the Version Cue folder to the trash. -
Reworking Photoshop layer renaming script for Illustrator
The Photoshop scripting guru Paul R over at RetouchPro has created a really cool script to batch rename and number selected Photoshop layers. I haven't found anything similar on the Illustrator side.
He's given permission for me to post it here in my hopes that some Illustrator scripting genius could come up with a similar script for Illustrator. Would it be terribly difficult to convert this into something Illustrator could use?
http://www.mediafire.com/file/g7usr73u0236p0a/Rename_&_Renumber_Selected_Layers.jsx
http://www.mediafire.com/file/dbah74x13bsa74c/Rename_&_Renumber_Selected_Layers.jsx.zipHola Julio, I updated the script to rename visible Layers or Sublayers, and also fixed the Color
#target illustrator
main();
function main(){
if(!documents.length) return;
//var allLayers = app.activeDocument.layers;
var win = new Window( 'dialog', '' );
g = win.graphics;
// var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.99, 1]); // CS5
var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.50, 0.50, 0.50, 1]); // CS6
g.backgroundColor = myBrush;
win.orientation='stack';
win.p1= win.add("panel", undefined, undefined, {borderStyle:"black"});
win.g1 = win.p1.add('group');
win.g1.orientation = "row";
win.title = win.g1.add('statictext',undefined,'Rename Visible Layers or Sublayers');
win.title.alignment="fill";
var g = win.title.graphics;
g.font = ScriptUI.newFont("Georgia","BOLDITALIC",22);
win.g5 =win.p1.add('group');
win.g5.orientation = "column";
win.g5.alignChildren='left';
win.g5.spacing=10;
win.g5.st1 = win.g5.add('statictext',undefined,'New layer name');
win.g5.et1 = win.g5.add('edittext');
win.g5.et1.preferredSize=[250,20];
win.g10 =win.p1.add('group');
win.g10.orientation = "row";
win.g10.alignment='fill';
win.g10.spacing=10;
win.g10.st1 = win.g10.add('statictext',undefined,'Serial Number');
win.g10.et1 = win.g10.add('edittext',undefined,'1');
win.g10.et1.preferredSize=[50,20];
win.g10.et1.onChanging = function() {
if (this.text.match(/[^\-\.\d]/)) {
this.text = this.text.replace(/[^\-\.\d]/g, '');
win.g10.st1 = win.g10.add('statictext',undefined,'Length');
var nums=[2,3,4,5];
win.g10.dl1 = win.g10.add('dropdownlist',undefined,nums);
win.g10.dl1.selection=0;
win.g15 =win.p1.add('group');
win.g15.orientation = "row";
win.g15.alignment='fill';
win.g15.cb1 = win.g15.add('checkbox',undefined,'Reverse layer order');
win.g15.cb2 = win.g15.add('checkbox',undefined,'Rename Sublayers Only');
win.g100 =win.p1.add('group');
win.g100.orientation = "row";
win.g100.alignment='center';
win.g100.spacing=10;
win.g100.bu1 = win.g100.add('button',undefined,'Rename');
win.g100.bu1.preferredSize=[120,30];
win.g100.bu2 = win.g100.add('button',undefined,'Cancel');
win.g100.bu2.preferredSize=[120,30];
win.g100.bu1.onClick=function(){
if(win.g5.et1.text == ''){
alert("No layer name has been entered!");
return;
win.close(0);
var sublayersOnly = win.g15.cb2.value;
var visibleLayers = [];
getVisibleLayers (app.activeDocument, visibleLayers, sublayersOnly);
if(win.g15.cb1.value) visibleLayers.reverse();
for(b=0; b<visibleLayers.length; b++){
var LayerName = win.g5.et1.text + zeroPad((Number(win.g10.et1.text)+Number(b)), Number(win.g10.dl1.selection.text));
visibleLayers[b].name = LayerName;
win.center();
win.show();
function getVisibleLayers(container, visibleLayers, sublayersOnly) {
for(var a=0; a<container.layers.length; a++){
var ilayer = container.layers[a];
if (ilayer.visible) {
if (sublayersOnly) {
getVisibleLayers (ilayer, visibleLayers, false); // false to process only 1 sublayer depth
else
visibleLayers.push(ilayer);
function zeroPad(n, s) {
n = n.toString();
while (n.length < s) n = '0' + n;
return n; -
Need to convert a SAP Script to Smart Form
Hello,
I need to convert a SAP script to a Smart form.
I am aware of converting it but have a question abt print program?
Can the print program which is currently attached to the SAP script supprot the Smart form?
Could some one let me know if i can use the same program or need to do some modifications in it?
Pointa rewareded if useful.
Thanks,
Krishnahi
t-code smartforms
utilities->migrate sapscript
check the link below it provides steps to convert sap scripts to smartforms
http://www.ficoexpertonline.com/downloads/Iyer_SmartForms.pdf
Check these threads.
Smartforms -> sapscript
Re: Convert SapScript to Smartforms ?
regards.
Kiran Sure -
CS4, script files are not showing in script panel
I dont ever use scripts but I did have one i downloaded to use for CS3. Its been a while but I thought I just dropped it into the Scripts folder and it would show up in the scripts panel in InDesign. I just put that same script in my new CS4 scripts folder and its not showing up. I even restarted ID to make sure and it still doesnt. Is there something im forgetting?
CS4 has a slightly different model.
In the Scripts folder, there is a folder called "Scripts Panel". For scripts to show within the Scripts panel in InDesign, place your scripts within this internal folder. -
I have flash 5. I want to continue using it. (I cannot afford
to buy a new version)
I am used to using "tell target" and other obsolete scripting
tools.
If I make a website with flash 5 old school scripts, will the
Internet continue to play these old code?
Will the current, and future flash players support these old
scripts?Yes, new players include support for movies published under
older versions. The only problem is taking your old fla files and
publishing them with a newer version. That's when you have to
update your code. -
Mail server rejecting messages and carrying out old sieve scripts
A week ago I upgraded to 10.6 and am now experiencing strange behaviour: occasionally, incoming messages do not make it to their recipient and the sender gets an old vacation reply that I had set up using sieve scripts in Leopard. Here is what the SMTP log reports when a message does not make it:
"Recipient address rejected: Service is unavailable"
I do not know how to go in and investigate what is going on with sieve scripts because it seems sieveshell has been gutted in 10.6. I currently do not have SL's new vacation message feature enabled, but it worked fine when I tested it. Any help would be greatly appreciated!You can remove all of the old sieve scripts...
sudo rm -rf /usr/sieve/*
copy/paste into terminal.
Jeff -
Can i use this script in illustrator?
can i use this script in illustrator?
Newsgroup_User// This script exports extended layer.bounds information to [psd_file_name].xml
// by pattesdours
function docCheck() {
// ensure that there is at least one document open
if (!documents.length) {
alert('There are no documents open.');
return; // quit
docCheck();
var originalRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var docRef = activeDocument;
var docWidth = docRef.width.value;
var docHeight = docRef.height.value;
var mySourceFilePath = activeDocument.fullName.path + "/";
// Code to get layer index / descriptor
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
function getLayerDescriptor (doc, layer) {
var ref = new ActionReference();
ref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
return executeActionGet(ref)
function getLayerID(doc, layer) {
var d = getLayerDescriptor(doc, layer);
return d.getInteger(cTID('LyrI'));
var stackorder = 0;
// function from Xbytor to traverse all layers
traverseLayers = function(doc, ftn, reverse) {
function _traverse(doc, layers, ftn, reverse) {
var ok = true;
for (var i = 1; i <= layers.length && ok != false; i++) {
var index = (reverse == true) ? layers.length-i : i - 1;
var layer = layers[index];
// alert("layer.typename >>> "+layer.typename );
if (layer.typename == "LayerSet") {
ok = _traverse(doc, layer.layers, ftn, reverse);
} else {
stackorder = stackorder + 1;
ok = ftn(doc, layer, stackorder);
return ok;
return _traverse(doc, doc.layers, ftn, reverse);
// create a string to hold the data
var str ="";
// class using a contructor
function cLayer(doc, layer) {
//this.layerID = Stdlib.getLayerID(doc, layer);
this.layerID = getLayerID(doc, layer);
//alert("layer ID: " + this.layerID);
this.layerWidth = layer.bounds[2].value - layer.bounds[0].value;
this.layerHeight = layer.bounds[3].value - layer.bounds[1].value;
// these return object coordinates relative to canvas
this.upperLeftX = layer.bounds[0].value;
this.upperLeftY = layer.bounds[1].value;
this.upperCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.upperCenterY = layer.bounds[1].value;
this.upperRightX = layer.bounds[2].value;
this.upperRightY = layer.bounds[1].value;
this.middleLeftX = layer.bounds[0].value;
this.middleLeftY = this.layerHeight / 2 + layer.bounds[1].value;
this.middleCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.middleCenterY = this.layerHeight / 2 + layer.bounds[1].value;
this.middleRightX = layer.bounds[2].value;
this.middleRightY = this.layerHeight / 2 + layer.bounds[1].value;
this.lowerLeftX = layer.bounds[0].value;
this.lowerLeftY = layer.bounds[3].value;
this.lowerCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.lowerCenterY = layer.bounds[3].value;
this.lowerRightX = layer.bounds[2].value;
this.lowerRightY = layer.bounds[3].value;
// I'm adding these for easier editing of flash symbol transformation point (outputs a 'x, y' format)
// because I like to assign shortcut keys that use the numeric pad keyboard, like such:
// 7 8 9
// 4 5 6
// 1 2 3
var windowW=2048;
var windowH=1536;
this.leftBottom = this.lowerLeftX + ", " + (windowH-this.lowerLeftY);
this.bottomCenter = this.lowerCenterX + ", " + (windowH-this.lowerCenterY);
this.rightBottom = this.lowerRightX + ", " + this.lowerRightY;
this.leftCenter = this.middleLeftX + ", " + this.middleLeftY;
this.center = this.middleCenterX + ", " + this.middleCenterY;
this.rightCenter = this.middleRightX + ", " + this.middleRightY;
this.leftTop = this.upperLeftX + ", " + this.upperLeftY;
this.topCenter = this.upperCenterX + ", " + this.upperCenterY;
this.rightTop = this.upperRightX + ", " + this.upperRightY;
// these return object coordinates relative to layer bounds
this.relUpperLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relUpperLeftY = layer.bounds[0].value - layer.bounds[0].value;
this.relUpperCenterX = this.layerWidth / 2;
this.relUpperCenterY = layer.bounds[0].value - layer.bounds[0].value;
this.relUpperRightX = this.layerWidth;
this.relUpperRightY = layer.bounds[0].value - layer.bounds[0].value;
this.relMiddleLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relMiddleLeftY = this.layerHeight / 2;
this.relMiddleCenterX = this.layerWidth / 2;
this.relMiddleCenterY = this.layerHeight / 2;
this.relMiddleRightX = this.layerWidth;
this.relMiddleRightY = this.layerHeight / 2;
this.relLowerLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relLowerLeftY = this.layerHeight;
this.relLowerCenterX = this.layerWidth / 2;
this.relLowerCenterY = this.layerHeight / 2;
this.relLowerRightY = this.layerHeight;
this.relLowerRightX = this.layerWidth;
this.relLowerRightY = this.layerHeight;
return this;
// add header line
str = "<psd filename=\"" + docRef.name + "\" path=\"" + mySourceFilePath + "\" width=\"" + docWidth + "\" height=\"" + docHeight + "\">\n";
// now a function to collect the data
var isParentAvailable=false;
var prevLayerSetName="";
function exportBounds(doc, layer, i) {
var isVisible = layer.visible;
var layerData = cLayer(doc, layer);
//alert("layer.name >>> "+layer.name );
//alert("typename >>> "+layer.typename);
/*if(layer.parent.name == "ParentTest"){
for(var i in layer.parent){
alert(" III >>> "+i+"<<<layer.parent>>"+layer.parent[i]);
if(isVisible){
// Layer object main coordinates relative to its active pixels
var startStr="";
if(layer.parent.typename=="LayerSet"){
if(prevLayerSetName!="LayerSet") {
startStr="\t<parentlayer id='"+layer.parent.name+"'>\n\t";
}else{
startStr="\t";
// endStr="\t</parentlayer>\n";
prevLayerSetName=layer.parent.typename;
}else{
if(prevLayerSetName=="LayerSet"){
startStr="\t</parentlayer>\n";
prevLayerSetName="";
var positionStr=layer.name.split(".")[0].substr(layer.name.split(".")[0].length-3,layer.name. split(".")[0].length);
var assetPosition=leftTop;
if(positionStr=="L_B"){
assetPosition=leftBottom;
}else if(positionStr=="B_C"){
assetPosition=bottomCenter;
}else if(positionStr=="R_B"){
assetPosition=rightBottom;
}else if(positionStr=="L_C"){
assetPosition=leftCenter;
}else if(positionStr=="C"){
assetPosition=center;
}else if(positionStr=="R_C"){
assetPosition=rightCenter;
}else if(positionStr=="L_T"){
assetPosition=leftTop;
}else if(positionStr=="T_C"){
assetPosition=topCenter;
}else if(positionStr=="R_T"){
assetPosition=rightTop;
var str2 =startStr+ "\t<layer name=\"" + layer.name
+ "\" stack=\"" + (i - 1) // order in which layers are stacked, starting with zero for the bottom-most layer
+ "\" position=\"" + assetPosition // this is the
+ "\" layerwidth=\"" + layerData.layerWidth
+ "\" layerheight=\"" + layerData.layerHeight
+ "\" transformpoint=\"" + "center" + "\">" // hard-coding 'center' as the default transformation point
+ layer.name + ".png" + "</layer>\n" // I have to put some content here otherwise sometimes tags are ignored
str += str2.toString();
// call X's function using the one above
traverseLayers(app.activeDocument, exportBounds, true);
// Use this to export XML file to same directory where PSD file is located
var mySourceFilePath = activeDocument.fullName.path + "/";
// create a reference to a file for output
var csvFile = new File(mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".xml");
// open the file, write the data, then close the file
csvFile.open('w');
csvFile.writeln(str + "</psd>");
csvFile.close();
preferences.rulerUnits = originalRulerUnits;
// Confirm that operation has completed
alert("Operation Complete!" + "\n" + "Layer coordinates were successfully exported to:" + "\n" + "\n" + mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".xml"); -
Final Cut Pro X 10.2 crashes when I try to convert old libraries for use in the new software. Is there a workaround for this? Or will I have to continue using the previous version to complete older projects? the only foreseeable solution is to begin any new projects on 10.2 or importing footage on 10.2 and starting form scratch--which is something i definitely don't want to do or have time to do. ANY advice, thoughts, or opinions would be greatly appreciated! Thank you!
Running 10.10.3 // MacBook Pro (Retina, 15-inch, Early 2013) // 2.4 GHz Intel Core i7 // 8 GB 1600 MHz DDR3Exactly the same problem with me.
Some other threads advice to remove fonts, clean the caches, remove add ins but nothing works consistenty, for some it looks like it works, for me it failed.
What I did not try yet, was to move the Render files out of the malicious library to trash. -
Converting old analog video with maximum resoultion for archieving and eventual use in iMovie
There seems to be a lot of information on converting old (amatuer) analog video media to a digital format, and which one is best to preserve the maximum amount of data. I have already imported old VHS, analog 8, hi8, and dv into iMovie interations from iMovie 6 and forward. The later versions seem to convert the older files to their own format, I suspect, with a loss of data. I want to reimport the old media to create masters in the best digital format for eventual editing by iMovie 11, or whatever iMovie comes after that.
I have the following formats: VHS, super VHS, 8MM, Hi8, DV, and a memory card (from a camera which is not directly compatible with iMovie 11)
I have the following equimpent:
SONY dual deck VHS DVD. This allows me to convert VHS directly to DVD. I can later decode using Handbreak, and import etc. but it seems I would be losing quality.
SONY Digital 8 handicam. This will play analog tape and output a digital file. I do not know the quality of the output.
Canon VIXIA HFS100, HD camcorder. This uses memory cards. It is NOT compatible with iMovie 11, which I should have checked before I bought it. I have played around with the memory card and have been able to import video but, I do not know the quality, and I've forgotten how I did it.
MacBook Pro, about 4 years old, with a 2Ghz Intel core duo processor and 2GHz Ram. This is obviously not state of the art. I am willing to upgrade within the Mac family but I don't what to upgrade to for my purposes
Canopus ADVC 110. This as DV out via a firewire port, and a DV in/out. It also has svideo in, and composit in.
I have the following software:
iMovie 6, iMovie 9, and iMovie 11. I am fairly comfortable with each version.
Final Cut Express, circa 2006. I would have to learn this.
Handbreak. I use this to rip the DVDs I made with SONY deck. It outputs all kinds of video codecs but is obviously working with compressed imput files. I don't know if I could get it to accept input directly from one of the cameras or the Canopus.
Audacity. I'm using this to combine audio tracks from various sources to add commentary to silent videos, which i would like to add as a voice over track to my iMovies
Toast. I think this can convert files of one video format to another in the process of copying.
Thanks for any advice on any part of this question.
Steve BYes
I found a program but am experiencing lots of trouble with it. I was hoping that others could give me a better suggestion.
I've actually downloaded and installed ffmpeg but the problem I'm experiencing now is that the videos do not convert. The program starts to work and then three seconds later I get the dialog box that says everything has been converted but the file created is 0KB and of course will not open.
Any ideas about what could be going wrong? I've attempted to convert the files to different formats and try converting different files as well. I still have the problem. -
Transferring Old CS4 from my old Mac to my New Mac Error 6.
I am trying to transfer my old CS4 from my old Mac to a new Mac which doesn't have a disc drive. I copied all the files to a memory stick and the pulled them from the stick into the application folder on my new Mac but the software will not start and say Licensing Error 6.
It this the right way to transfer my old CS4 from my old Mac to the new one which doesn't have a disc drive? and if so what does Error 6 mean and how to I get that sorted so I can work with my CS4 on my new Mac?
Also I would like to have PS and AI in my doc - I am so bad to computer stuff so please explain it all in very plain language. ( :
Kind Regards
DYou can't do that. Download the most current version of PS CS4 for Mac from the Adobe download site and install it. Then you can copy over your preference file and any edits you have done in PS CS4 from the old Mac.
But if this new Mac you have is running Mavericks or Yosemite CS4 might not work on those newer versions of OS X. Not sure, I gave up on Mac OS X about a year ago. -
How to convert old Java Servlets to OSGi "Servlet" Bundles
Hello I'm looking for some help/insight on the best way to convert some of our old Java Servlet code into new OSGi Bundles that can be accessed as servlets. I'd like to be able to install the new bundles then access them on one of our CQ instance using something like "/servlet/servlet_name".
So far I've been able to create a new bundle, and install it into CQ but I haven't been able to access the bundle at the servlet mapping URL that I would expect. So far what I've found online has lead me to believe that I need to use the Felix Annotations to describe my servlet.
@Component(immediate = true, metatype = true, label = "Servlet Name")
@Service
@Properties({
@Property(name = Constants.SERVICE_DESCRIPTION, value = "Servlet Name"),
@Property(name = "sling.servlet.methods", value={"GET"}),
@Property(name = "sling.servlet.paths", value = "/servlet/my_servlet_mapping"),
@Property(name = Constants.SERVICE_VENDOR, value = "VendorName")
public class TellAFriend extends HttpServlet {...
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
Once I have this installed, and running without an error in the logs for CQ I tried to go on my local instance to http://localhost:4502/servlet/my_servlet_mapping but I only get 404 Resource Not Found errors. I've even gone to the Sling Resource Resolver and it doesn't resolve to anything either.
Is there more than the Servlet Information need into the Annotations to convert "old" code into a new OSGi Servlet Mapped Bundle?I must be missing something else configuration wise since I created a new Servlet basically using the code you provided above. I deployed it as part of the bundle that I'm trying to create.
The bundle installs and stars fine but I still can't access the servlet. Are there CRXDE based configurations that are requried too to configure Servlets.
Here's my test servlet file. I tried going to http://localhost:4502/servlet/TestCQServlet and just get the same 404 error I'm getting for the other 2 Servlets Java classes in my Bundle.
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
@SlingServlet(paths = "/servlet/TestCQServlet", methods = "GET")
public class TestCQServlet extends SlingSafeMethodsServlet {
// @Reference
// private Repository repository;
private static final long serialVersionUID = 6239754936223276983L;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
response.setHeader("Content-Type", "application/json");
response.getWriter().print("whatever");
Maybe you are looking for
-
How to sort files by TimeStamp.
Hello friends, I have files which has following format. Paymentxxxx.xml where xxxx is time in YYYYMMDDHH:MM:SS format.Example file name can be Payment20010726143455.xml.How to sort such files according to time so that i can get old files first. Thank
-
Is it possible to fix text boxes in position when making a masterslide?
Hi, I'm trying to make a set of Keynote templates for a small organisation - we need consistency, therefore I don't want any of the styles to be overwritten. As an example, I have a title page and subtitle page with two text boxes, one bold and one l
-
Hi Team, It is a regular requirement to have the requestid kind of functionality of the BI/BW to be had it BPC. i.e who did what and when. I haven't completely thought abt the whole step by step process....but here i
-
Exchange Server 2013 to 2010 mailbox proxy is not working
I have exchange server 2013 and exchange server 2010 in co-exist. I have 3 cas server and 3 mbx server 2013 on windows server 2012 standard, 2 hub/cas server and 2 mbx server 2010 on windows server 2008 r2. when I try to access owa of exchange server
-
Hi All Could any one pls. suggest me how to solve the below problem. We are using one object in fotter it displays the time and date. We wnat this two option in the report one from completely right side and another one is completely left side for tha