101 СПОСОБ  ЗАРАБОТАТЬ   НА ПЕЧАТИ

Руки прочь от EPS!

  • Михаил Борисов
  • 30 сентября 2008 г.
  • 4960
 

Хороший специалист по допечатной подготовке — находка для работодателя, отсюда и приличный уровень зарплаты. Но и ответственность велика — приходится иметь дело с разнообразными творениями не всегда технически грамотных «гениев» креатива. Чтобы сразить потребителя наповал, порой создаётся настолько умопомрачительный дизайн (усложнённый обилием смесевых красок и другими «отягчающими» обстоятельствами), что его подготовка к печати отнимает весьма значительное время.

Всех специалистов препресса по специфике работы можно разделить на две группы: сотрудников рекламных агентств (РА) и периодических изданий. Первые занимаются более разнообразной работой, сталкиваясь с широчайшим спектром полиграфической продукции: поступающие от дизайнеров заготовки-макеты они превращают в продукт, готовый к выводу на печать. Работа крайне напряжённая, особенно в крупных РА, из-за частых цейтнотов и разнообразия задач. В более спокойной обстановке специалисты из периодики: они лишь перепроверяют макеты, которые подготовили специалисты из первой группы. Встречаются и работы, заказанные не в РА, но сути дела это не меняет, поскольку в случае пропуска ошибки отдуваться за неё придётся тому, кто работу проверял. И если для сотрудников РА простора для упрощения процесса немного в силу уже упоминавшейся разноплановости, то для вторых это чрезвычайно действенный подход, значительно упрощающий процедуру контроля.

Именно им адресована статья — используя описанный подход как базу, можно наращивать функциональность скрипта. Здесь же из соображений компактности речь пойдёт только об автоматизации проверки документов EPS.

Основная цель предлагаемого материала — дать общее понятие об организации процесса проверки (на базе Illustrator); в дальнейших планах автора — ещё один обзор, где будут затронуты вопросы межпрограммного взаимодействия в пределах всего Creative Suite (связка Illustrator–Photoshop–InDesign). Они являются, скорее, административными, поскольку касаются управления переносом данных между ПО, а допечатная проверка занимает относительно малую долю. Но, почерпнув информацию из обеих статей, можно создать мощный работоспособный скрипт, который будет решать актуальные задачи в пределах всего комплекса Creative Suite.

Выбор формата EPS не случаен: он используется как стандарт для однополосных макетов и, как правило, представляет собой сборочный файл, агрегирующий все используемые ресурсы. В таком случае достаточно одного движения мышью, чтобы проверить весь макет, каким бы сложным он ни был. Выбранный в статье подход платформенно-независим (Mac OS и Windwos), что существенно расширяет сферу его применения.

Что именно проверяем и как?

Описываемый сценарий выполняет стандартную допечатную проверку и отслеживает:

  • наличие заказных красок;
  • надпечатку там, где она обычно не нужна (если компонента K<100);
  • разрешение у растровых изображений и их цветовые модели;
  • минимальную толщину окантовки;
  • наличие составного чёрного;
  • присутствие прозрачности и различных режимов её наложения (кроме растровых масок);
  • наличие редактируемого текста.

При необходимости список можно без проблем расширить за счёт собственных, нетипичных проверок.

Как известно, наличие у объекта тех или иных свойств (например, типа и цвета заливки, размера шрифта и др.) предопределено разработчиками, и их значения отображаются в соответствующих палитрах Illustrator. В большинстве случаев они предоставляют объём информации, достаточный для комфортной работы в редакторе. Для наших же целей будет недоставать ещё парочки свойств, которые мы и создадим: растровый объект или нет (isRaster) и более общее — графический ли он (isGraphics). Естественно, эти свойства будут доступны только из скрипта. Такой подход значительно повысит его читабельность, что, согласитесь, немаловажно. Растровыми будем считать файлы: внедрённые в документ (embedded), связанные (linked) с расширением TIF, связанные EPS, если они созданы в Photoshop (Photoshop EPS). Графическими объектами считаем любые внешние ресурсы.

Единственное замечание по поводу первого пункта списка. В процессе внедрения внешнего файла (любого типа — растрового, векторного) в текущий документ всё содержимое первого становится неотъемлемой частью второго. При этом все существующие ссылки на растровые изображения заменяются реальными объектами, а векторные становятся редактируемыми. Таким образом, внедрённым в документ может быть только растровое изображение, что мы и учтём в скрипте.

Для задания нового типа объекта воспользуемся глобальным JavaScript-свойством prototype, предназначенным для расширения свойств и методов объектов. Будем учитывать, что все внедрённые изображения в Illustrator принадлежат коллекции RasterItems, если же они являются ссылкой на внешний файл, то имеют тип PlacedItem. С учётом всего вышесказанного в итоге получим:

Object.prototype.isRaster = function(){
   if(this.typename=='RasterItem') return true;
   } else {
   return (this.typename=='PlacedItem' && this.file.toString().search(/\.(tif)|(eps)$/i)!=-1) ? true : false;
}
if(Object.prototype.isGraphics = function(){
   return (this.typename=='PlacedItem' || this.isRaster()) ? true : false;
}

Если объект растровый, наше свойство isRaster будет иметь значение true, иначе — false. Для проверки необходимого типа файла (определяем по расширению) мы воспользовались регулярными выражениями (похожий механизм используется при поиске/замене в InDesign — закладка GREP, детально об их реализации в JavaScript см. предыдущие номера Publish). Предварительные работы закончены, приступаем непосредственно к скрипту, который на протяжении длительного времени с успехом применяется для проверки рекламы, поступающей в несколько периодических изданий.

Основные шаги

Поскольку в нём мы будем обращаться ко всем объектам макета, для краткости введём сокращения для текущего документа и каждого объекта, составляющего макет (им соответствует коллекция элементов pageItems). Поскольку скрипт должен работать под Illustrator, указываем это:

#target 'illustrator'

С учётом особенностей объектно-ориентиро-
ванного программирования пляшем всегда от печки, которой в нашем случае является сам Illustrator (application, сокращённо app).

aD=app.activeDocument;
p=aD.pageItems;

Предположим, в процессе обработки были обнаружены объекты, требующие повышенного внимания. Как их обозначить, чтобы впоследствии детально проверить и внести исправления? Простейший способ — выделять, поэтому перед запуском скрипта, во избежание казусов, выделенных объектов быть не должно.

aD.selection.length!=0) alert('В документе не должно быть выделенных объектов');

Первый шаг — проверка цветового пространства документа. Если установлено RGB, любые дальнейшие действия теряют смысл, а скрипт завершается выводом описания проблемы, в противном случае работа продолжается.

Чтобы скрипт был достаточно гибким, создадим простое диалоговое окно, через которое можно будет задавать основные параметры проверки. Среди них:

  • минимально допустимое разрешение растровых объектов;
  • опцию сохранения заказных цветов Pantone (или же перевода их в стандартную триаду);
  • опцию просмотра только отображаемого на экране (слоёв и объектов); если для какого-то объекта ввод на экран отключён, он из проверки исключается.

Для работающих в РА полезен автоматический расчёт минимального разрешения для изображений (при этом в диалоге значение указывать не нужно). В качестве эталона выберем 300 dpi для макетов формата А3, а при превышении размера допустимое разрешение будем пропорционально уменьшать. Для более мелких зафиксируем его на 300 dpi. Учтём специфический метод определения разрешения в Illustrator (72 dpi соответствует 1, причём более высокому разрешению — меньшая величина). В результате получим:

//проверка цветового пространства
   if(aD.documentColorSpace==DocumentColorSpace.
   CMYK && aD.pluginItems.length==0)) {
   //пользовательский диалог
   a = prompt(«Проверять только видимое?, Удалять заказные цвета?, Мин.разрешение:», 'Y, n, 250');
   if(p.length>1000) alert(«В документе более 1000 объектов, проверка может занять определённое время»);
   a=a.split(', ');
   processVisible=a[0];
   removeSpotColors=a[1];
   minRes=(a[2]=='undefined') ? Math.min(300, 300*Math.min(650/aD.width, 900/aD.height)) : a[2];

После цветовой модели определим присутствие pluginItems — специфических объектов, используемых для получения различных сложных форм: перетеканий (Blend), искажений по заданному контуру (Envelope), художественных эффектов с текстом (TextWrap). Дело в том, что из-за сложности подобных эффектов управление ими через скриптинг не предусмотрено. Но при окончании проверки мы обязаны гарантировать отсутствие любых ошибок (в т. ч. присутствующих в pluginItems), поэтому при обнаружении объектов подобного типа будем выдавать предупреждение.

if(aD. pluginItems.length>0){
   alert (‘В макете присутствуют объекты, которые не могут быть проверены’);
   goOn=false;
} else { goOn=true }

Предстартовая подготовка завершена, переходим к проверке макета.

if(goOn)
   main();

В процессе проверки все подозрительные объекты заносятся в хранилище errArray, после чего выполняются заключительные шаги (удаление дублирующихся ошибок и вывод сообщений).

//если ошибки были обнаружены
if(errArray.length>0) {
   //удаление повторов в описании ошибок
   removeDuplicates();
   //вывод описания ошибок
   alert(«Найдены следующие проблемы:\r»+errArray2.join('\r'));
   //наведение на проблемные объекты
   zoomIn();
} else {
   alert('ОК! Все в порядке');
   //если все ОК — сохранение документа
   if(!aD.saved) aD.save();
   //завершающие шаги: формирование файла
   //предпросмотра для проверки
   make_PDF_Preview();

}

} else alert('Документ не в CMYK. Также проверьте наличие комбинированных объектов')
}

Логика управления ясна, переходим к самому вкусному — к допечатной проверке (функция main()), которая выполняется в последовательности, описанной во врезке 1.

Контроль и ещё раз контроль

Если в диалоге пользователь выбрал тотальную проверку (в т. ч. невидимых объектов), делаем все слои видимыми и доступными для внесения изменений. Если для какого-либо слоя возможность распечатки выключена (мало ли для каких целей это было сделано исполнителем), сигнализируем об этом:

function main(){
   //разблокировка всех слоёв для возможности //внесения в них изменений
   for(i=0; i<aD.layers.length; i++) {
      with(aD.layers[i]){
         if(processVisible!='Y') visible=true;
         if (!printable && visible && pageItems.length>0) LatchObj('Имеются непечатаемые объекты');
      }
   }

Обработку подозрительных элементов поручим функции LatchObj() — она ничего другого делать не будет, кроме выделения проблемных объектов и сохранения в их свойствах описания проблемы. Для этого можно, конечно, воспользоваться уже известным приёмом, создав собственное свойство, однако оно нигде в палитрах отображаться не будет (там отображаются только стандартные), а нам это необходимо. Поэтому нужно найти такое свойство среди стандартных, которое бы редко использовалось и не мешало основной работе. Оптимальный кандидат — свойство URL. В Illustrator оно используется крайне редко — только при создании веб-страниц, при подготовке же к печати пустует.

Следующий шаг — контроль заказных цветов. Если в окне диалога пользователь выбрал удаление заказных цветов, выполняем эту процедуру.

if (removeSpotColors=='Y') aD.spots.removeAll();

Переходим к проверке текста. Для макетов, принесённых со стороны, полезна проверка версии Illustrator — если документ сохранён в более старой версии ПО, а текст при этом не конвертирован в кривые, то простая проверка на наличие редактируемого текста textItems.length==0 будет некорректной, поскольку LegacyTextItems — отдельный тип объектов, который ещё должен быть конвертирован в редатируемый текст (textItems).

//текст, сохранённый в старых
//версиях ПО
if(typename=='LegacyTextItem') convertToNative(), LatchObj('Редактируемый текст из старой версии');
//текст не в кривых
if(typename=='TextFrame') LatchObj('Редактируемый текст');

После этого проверяем прозрачность (opacity) и режимы наложения (blendingMode). Если объект полупрозрачен или режим отличается от традиционного, выдаём сообщение об ошибке.

//прозрачность и разные режимы
//наложения
if (opacity!=100 || blendingMode!='BlendModes.NORMAL'){
   LatchObj('Прозрачный объект');
   if(constructor.name=='groupItem') LatchObj(‘Некоторые группы прозрачны’)
}

Разберём последнюю строку. В ней выполняется очень важная проверка — является ли текущий объект с прозрачностью группой, в случае положительного результата скрипт бьёт тревогу. Причина в том, что группа — коварный объект, поскольку при разгруппировке (например, после применения Epand Appearance) объекты, входящие в её состав, свойств родителя не получают, поэтому возможны проблемы. Например, прозрачность группы не распространится на её составляющие, что повлечёт за собой изменение внешнего вида макета со всеми вытекающими последствиями.

Итак, половина проверок выполнена, осталось разобраться с более сложными, касающимися цвета. Как упоминалось выше, объекты CompoundPath — частный случай pluginItems и не имеют собственной заливки/окантовки. Похожая ситуация с группами (они представляют собой полноправный объект макета наравне с отдельными контурами): они также не имеют собственного цвета, но в отличие от контуров их содержимое может иметь какую угодно заливку/окантовку — соответственно, из дальнейшей проверки, касающейся цвета, они должны быть исключены.

Последующие действия происходят по одному из сценариев, в зависимости от того, имеет объект векторный тип (isGraphics()) или является растровым изображением. В первом случае происходит проверка свойств заливки (if(filled)) и окантовки (if(stroked)). Для обеих проверяются наличие заказного цвета (checkSpot) и надпечатка (checkOverprint). Кроме того, для окантовки проводятся ещё две проверки: сравнение с минимально допустимой толщиной (стандартно — 0,25 pt) и проверка цветовых компонент для тонких линий. Последнее необходимо во избежание проблем несовмещения при печати составного цвета, когда используется более двух красок.

if(typename!='GroupItem'){
   //проверка только векторов
   if(!isGraphics()){
      //возможные специфические объекты
      if(typeof (fillColor)=='undefined'){
         alert('объект типа '+typename+' не может быть проверен.');
         selected=true;
      }else{
         if(filled){
            //проверка пантонов и надпечати
            if(removeSpotColors!='Y') checkSpot (fillColor, 'fill');
            if(fillOverprint) checkOverprint(fillColor, 'fill')}
         if(stroked){
         //то же для окантовки
            if(removeSpotColors!='Y') checkSpot (strokeColor, 'stroke');
            if(strokeOverprint) checkOverprint (strokeColor, 'stroke');
            //слишком тонкие линии
            if(strokeWidth < minStroke) LatchObj ('Слишком тонкая окантовка');
            sC = strokeColor;
            //отсутствие густого цвета
            //у тонких линий
            if((strokeWidth < minStroke*2) && sC.black+sC.cyan+sC.magenta+sC.yellow>200) LatchObj('У окантовки густой чёрный цвет'); 
         }
      }
   }

Проверка растровой графики

Если объект — растровое изображение (isRaster()), достаточно проверить его фактическое разрешение по горизонтали и вертикали (на случай, если оно было масштабировано непропорционально). В зависимости от типа изображения (цветное или в градациях серого) используются разные минимальные разрешения. Для первого берётся значение, заданное пользователем в окне диалога (если нет — рассчитывается автоматически на основании размеров макета), второе берётся как удвоенное значение первого.

Проверка цветовой модели для такого типа объектов не требуется — даже если они не внедрены, Illustrator корректно преобразует их в модель документа (как вы помните, такая проверка уже была выполнена). Соответственно, цветоделение (как из него непосредственно, так из InDesign) происходит без осложнений.

} else {
   if(isRaster()){
      //проверка разрешения по горизонтали
      //и вертикали
      with(matrix){
         if (imageColorSpace==ImageColorSpace.CMYK && (mValueA>72/minRes || mValueD>72/minRes))
            LatchObj('Низкое разрешение полноцветного изображения');
         if(imageColorSpace==ImageColorSpace.GrayScale && (mValueA>72/(minRes*2) || mValueD>72/(minRes*2)))
            LatchObj('Низкое разрешение у изображения в градациях серого');
}

Осталось рассмотреть более сложный случай — если связанный файл имеет разрешение EPS. Ведь в нём может находиться всё, что угодно: недаром такой формат расшифровывается как Encapsulated PostScript — это самодостаточный файл-программа для формирования изображения. При этом нужно учесть, что EPS бывают двух видов: растровые (созданные в Photoshop) и векторные (в Illustrator).

Независимо от того, внедрён растровый EPS или только связан с документом, Illustrator (даже c выключенной опцией Include CMYK PostScript in RGB files) гарантирует формирование корректного CMYK-PostScript, поэтому проверки цветовой модели также не требуется. Остаётся выполнить проверку разрешения, а это не совсем тривиальная задача. Дело в том, что JavaScript читает только текстовые файлы, а если EPS был записан в целях универсальности как двоичный (Encoding/Binary, что чаще всего и встречается), то его прочесть не удастся. Выход в том, чтобы прочитал файл Illustrator, после чего мы добудем требуемую информацию. Проще всего это реализовать путём временного внедрения файла, а после определения фактического разрешения снова заменить его ссылкой.

Поскольку мы проводим проверку в документе Illustrator, достаточно проверить только Photoshop EPS — на предмет разрешения. Ситуация, когда связанный EPS был создан в Illustrator, маловероятна, а потому рассматриваться не будет.


}else //если EPS линкнутый, пробуем определить его х-ки
   tempA.push(file.absoluteURI);
   embed();
   with(aD.rasterItems[aD.rasterItems.length-1]){
   // появившийся член коллекции
      if(mValueA>72/minRes || mValueD>72/minRes)
         LatchObj('Низкое разрешение полноцветного изображения');
      relink(tempA[tempA.length-1]);
   }
         }
      }
   } else LatchObj('Имеются скрытые объекты');
 }

    }
}

Заключительные шаги

Наступил черёд создавать файл предпросмотра для утверждения заказчиком или ответственным менеджером. Файл может быть формата JPEG и PDF, поэтому предусматриваем любой вариант. Для РА пригодится сохранение документа в формате Illustrator 8. Настройки для сохранения/экспорта представляют собой стили для выполнения той или иной операции, в которых перечислены пары «свойство/значение».

При экспорте в JPEG ограничиваемся лишь тем, что расположено на листе, без запасов на вылет (artBoardClipping). По умолчанию при такой операции устанавливается разрешение 72 dpi, и никакого механизма для его изменения нет. Можно экспортировать пропорционально увеличенный файл при условии, что программа-просмотрщик автоматически сожмёт его до размеров видимой области экрана и сможет в таком же виде распечатать. Если такой возможности нет, придётся вручную экспортировать документ либо воспользоваться, например, PDF.

Некоторые особенности есть и при выводе в формате PDF. Во-первых, происходит не экспорт, а сохранение, во-вторых, можно явно указать размеры вылетов, если они необходимы. Также предусмотрена опция просмотра готового результата в Acrobat.

function saveAS_EPS() {
   //задаём габаритные метки
   //удобно при помещении EPS в InDesign
   aD.cropBox = [-bleed*mm2pt, aD.height+bleed*mm2pt, aD.width+bleed*mm2pt*2, -bleed*mm2pt];
   //стиль для сохранения
   exOEPS = new EPSSaveOptions();
   with(exOEPS){
      cmykPostScript=true;
      compatibility = Compatibility.ILLUSTRATOR8;
      embedLinkedFiles=false;
      preview = EPSPreview.COLORTIFF;
   }
   aD.saveAs(epsF, exOEPS);
}
function saveAS_JPG(){
   exOJPG = new ExportOptionsJPEG();
   koef = jpegRes/72;
   with(exOJPG){
      antiAliasing=true;
      qualitySetting=50;
      artBoardClipping=true;
   //масштабирование, позволяющее обойти
   //ограничение в 72 dpi при экспорте в JPEG
      verticalScale=100*koef*Math.min(600/aD.width, 900/aD.height);
      horizontalScale=verticalScale;
   }
   aD.exportFile(jpgF, ExportType.JPEG, exOJPG);
}
function make_PDFPreview(){
   //вычленяем только название файла
   //(без расширения)
   n=aD.fullName.toString().replace(/(.+)\.ai$/, «$1»);
   //выставляем правильно начало координат,
   //на тот случай, если оно по каким-то
   //причинам было сдвинуто
   rulerOrigin=[0,0];
   //новое название для формируемого PDF
   pdfF = new File(n+’_preview’);
   exOPDF = new PDFSaveOptions();
   //настройки экспорта: соль/сахар — по вкусу
   with(exOPDF){
      bleedOffsetRect = [0, aD.height, aD.width, 0];
      colorCompression=CompressionQuality.JPEGMEDIUM;
      colorDownsampling=96;
      colorDownsamplingImageThreshold=96;
      compatibility=PDFCompatibility.ACROBAT5;
      compressArt=true;
      generateThumbnails=false;
      preserveEditability=false;
      viewAfterSaving=true;
   }
   aD.saveAs(pdfF, exOPDF);
}

Глобальные проверки выполнены, осталось написать действия, необходимые для контроля заказных цветов и надпечати, которые до сих пор были за кад-
ром. Эту проверку можно реализовать так:

function checkSpot (obj, prop){
//если свойство spot определено,
//то проверяем его
   if (typeof(obj.spot)!='undefined' && obj.spot.colorType!=ColorModel.PROCESS)
      LatchObj('Spot in '+prop);
}
function checkOverprint (obj, prop){
//то же самое с надпечатью
//отдельно — для серого и CMYK
if((typeof(obj.grayColor)=='undefined' && obj.black!=100)||(typeof(obj.grayColor)!='undefined' && obj.gray!=100))
   LatchObj('Надпечать в '+prop);
}

Удобная, но необязательная часть скрипта — одновременный вывод всех выделенных объектов на экран в максимальном масштабе: сначала определяются габариты выделенной области, после чего полученные значения используются для задания масштаба отображения.

function zoomIn(){
   sel=aD.selection;
   v=aD.views[0];
   for (i=0; i<sel.length; i++) {
      maxL = (sel[i].geometricBounds[0]<sel[0].geometricBounds[0]) ? sel[i].geometricBounds[0] : sel[0].geometricBounds[0];
      maxT = (sel[i].geometricBounds[1]>sel[0].geometricBounds[1]) ? sel[i].geometricBounds[1] : sel[0].geometricBounds[1];
      maxR = (sel[i].geometricBounds[2]>sel[0].geometricBounds[2]) ? sel[i].geometricBounds[2] : sel[0].geometricBounds[2];
      maxB = (sel[i].geometricBounds[3]<sel[0].geometricBounds[3]) ? sel[i].geometricBounds[3] : sel[0].geometricBounds[3];
   }
   //определяем масштаб относительно 100%
   v.zoom = 1;
   //масштаб
   v.zoom = Math.min( (v.bounds[2]-v.bounds[0])/((maxR-maxL)*1.1), (v.bounds[1]-v.bounds[3])/((maxT-maxB)*1.1) );
   //положение центра области просмотра
   v.centerPoint = [maxL+(maxR-maxL)/2, maxT-(maxT-maxB)/2];
}

Вот и всё. Надеюсь, описанные приёмы и подходы помогут вам в реализации всего потенциала Illustrator для облегчения повседневной работы. Удачи, господа препресс-специалисты!


Внимание: составные контуры!

Перед выполнением основного цикла обратим особое внимание на составные контуры (CompoundPath). Они представляют собой специфическую конструкцию, результат логических операций над несколькими объектами, в связи с чем:

  1. не имеют некоторых свойств, присущих объектам (например, Fill и Stroke, хотя входящие в них объекты их не имеют);
  2. заливка, а также окантовка у всех объектов, входящих в составной контур, совершенно одинаковы (составляющие контура являются, по сути, частями одного большого контура).

Нам достаточно проверить свойства, например, только первого объекта составного контура и пропустить все остальные — существенная экономия времени, особенно при больших объёмах текста, конвертированного в кривые. Соответственно, шаг перебора всех элементов (step) будет либо 1 (стандартно — каждый), либо равен количеству объектов в контуре CompoundPathItem.pathItems.length.

for(i=0; i<p.length; i+=step){
   //учитываем наличие CompoundPath
   with((p[i].typename=='CompoundPathItem') ? p[i].pathItems[0] : p[i]){
   //невидимые не трогаем — мало ли где они могут
   //проявиться
      if(visible){
         //оптимизация при обработке CompoundPath
         //пропускаем объекты, содержащиеся в нём
         step=(typename=='CompoundPathItem') ? pathItems.length : 1;


Выявляем неблагонадёжных

А вот как происходит сбор информации о подозрительных моментах: функция LatchObj выделяет проблемный объект и в его заметки (для векторных — в свойство note, отображаются в палитре Attributes) записывает причину, по которой объект был помечен как требующий дополнительного разбирательства.

function LatchObj (msg){
   with(aD.pageItems[i]) {
   //разблокировка
      layer.locked=false;
      locked=false, selected=true;
      //растровые объекты и группы
      //не могут иметь заметки — недоработка
      if(!isGraphics() && typename!='GroupItem') {
      //если проблемы есть в самой группе, дополнительно
      //сигнализируем — они появятся при выделении самой
      //группы
         if (typeof(parent.uRL)!='undefined')
            parent.uRL += 'В группе: '+msg+'; ';
         note += msg+'\r';
      }else {
      //учитываем что изображения могут быть в обтравочных
      //контурах если проблемы есть внутри группы, они
      //появятся при выделении самой группы —
      //после слов 'В группе:’ только URL
         if(parent.clipped && typeof(parent.uRL)!='undefined')
            parent.uRL += 'В : '+msg+'; ';
         //т. к. URL может содержать только одну строку, разделяем ошибки через « ;»
         uRL += msg+'; ';
      }
   }
   //накопление информации
   errArray.push(msg);
}

Поскольку одни и те же подозрения на ошибку могут возникнуть у множества объектов, скрипт будет выдавать предупреждение для каждого. Особого смысла в этом нет, достаточно выдать сообщение однократно, поэтому перед окончательным результатом все однотипные сообщения удаляем (removeDup):

function removeDup(){
   errArray2 = [], dupObj = {};
   for(i in errArray) {
      if (!dupObj[errArray[i]]) {
         dupObj[errArray[i]]=true;
         errArray2.push(errArray[i]);
      }
   }
}

ПОХОЖИЕ СТАТЬИ
Управление цветом в Adobe Creative Cloud без секретов

Подробное руководство по настройке параметров управления цветом в программах Adobe.

InDesign осваивает ePub

Приёмы построения ePub в Adobe InDesign CC. Советы издательствам, как без лишних хлопот готовить книги для LitRes или Bookmate.



Новый номер

Тема номера: С иголочки: всё о брендировании текстиля. RICOH Pro C7500. Скоростной УФ-принтер Artis CX-360G Gen 51. Текстильлегпром 2024. Кто побеждает в борьбе: DTG или DTF? День рождение будущего. Agfa Anapurna Ciervo H3200 + Спецпроект Publish Junior



Какой следующий принтер вы купите себе на производство?
    Проголосовало: 38