how to get the font-style from the psd file using PS script - photoshop-script

right now I want to get the font-style from the PSD file using
the Photoshop script, but I fail.

By font style do you mean italic, bold etc? You can pull up the font name using this:
for (var i = app.activeDocument.layers.length -1; i >= 0; i--)
{
var tempLayer = app.activeDocument.artLayers[i]
if (tempLayer.kind == 'LayerKind.TEXT')
{
var textContents = tempLayer.textItem.contents;
var fontSize = tempLayer.textItem.size;
var fontFace = tempLayer.textItem.font;
alert (fontFace)
-- will return something like Arial MT Bold
}
}
You might want to look at this post as well
PS text contents

Related

Google Slides API- How to change text color for all shapes of a certain color

I have 11 files with over 140 slides each, and none of the shapes are tied to a theme/master. My goal was the change the master font and also replace all the red text (there is SO much red text) with black text.
I successfully updated the master font (thanks to https://gist.github.com/dsottimano/20a50daded2128b4c86acb430cecba67), but have come up short in trying to write something for ForegoundColor.
I tried to adapt this code and cannot make it work: https://mashe.hawksey.info/2017/10/changing-the-color-of-all-links-in-google-slides-with-google-apps-script/
I need to replace all text formatted with foregroundcolor hex #e04935 with hex #000000.
Appreciate any tips on making this work!
Here is what I have done so far:
//original from: https://mashe.hawksey.info/2017/10/changing-the-color-of-all-links-in-google-slides-with-google-apps-script/
/**
* #OnlyCurrentDoc
*/
function changeTextColorforShapes(){
var deck = SlidesApp.getActivePresentation();
var slides = deck.getSlides();
slides.forEach(function(slide) {
// https://developers.google.com/apps-script/reference/slides/slide#getPageElements()
var elements = slide.getPageElements();
elements.forEach(function(element){
// https://developers.google.com/apps-script/reference/slides/page-element#getPageElementType()
var type = element.getPageElementType();
// Text boxes are 'SHAPES' (this code doesn't handle table cells)
if (type == "SHAPE"){
// https://developers.google.com/apps-script/reference/slides/text-range#getTextStyle()
var textStyle = element.asShape().getText().getForegroundColor();
// https://developers.google.com/apps-script/reference/slides/text-style#hasLink()
// Returns true if text is color #e04935 (https://www.color-hex.com/color/e04935) and changes text to color #ffffff (black)
if (ForegroundColor('#e04935')
textStyle.setForegroundColor('#ffffff');
}
});
});
}
If you want to change all the text from #E04935 to #000000, you can try the below snippet:
Snippet
// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0
function changeColor() {
var presentation = SlidesApp.getActivePresentation();
var slides = presentation.getSlides();
for (let i = 0; i < slides.length; i++) {
var elements = slides[i].getPageElements();
for (let j = 0; j < elements.length; j++)
if (elements[j].asShape().getText().getTextStyle().getForegroundColor().asRgbColor().asHexString() == '#E04935')
elements[j].asShape().getText().getTextStyle().setForegroundColor('#000000');
}
}
Explanation
The reason your code was not working is because you were trying to use the getForegroundColor() method on an object of type TextRange while this method is expected to be called from an object of type TextStyle.
So in order to test exactly if the color of the text is the wanted one, you will have to retrieve first the color as a RGB color in order to get the HEX value of it.
Reference
Apps Script Editing & Styling Text Slides;
Apps Script Class TextStyle - getForegroundColor().

InDesign Endnote Automation

I'm using this simple script to grab text wrapped in [ENDNOTE][/ENDNOTE] tags and make them into actual InDesign endnotes. The problem I'm having is that only the first 4 characters are being placed between the endnote markers (see screenshot below), any idea why this is happening, or how to make it work right?
var doc = app.activeDocument;
function footnoteToEndnotes () {
app.findGrepPreferences = null;
app.findGrepPreferences.findWhat = '\\[ENDNOTE\\](.+?)\\[\\/ENDNOTE\\]';
var endnote,
fnotes = doc.findGrep();
for (var i = fnotes.length-1; i >= 0; i--) {
var taggedText = fnotes[i].contents.replace('[ENDNOTE]', '').replace('[/ENDNOTE]', '');
endnote = fnotes[i].insertionPoints[0].createEndnote();
endnote.texts[0].contents = taggedText;
fnotes[i].remove();
}
}
if (parseInt (app.version) < 13) {
alert ('This script requires InDesign CC2018 or later');
exit();
}
doc.endnoteOptions.frameCreateOption = EndnoteFrameCreate.NEW_PAGE;
footnoteToEndnotes();
So, when I set the content of insertionPoints[0], the full endnote ended up inside the endnote markers. But, there was an extraneous tab character at the end of the string... I stripped it out and it's working like I want!
I replaced this line:
endnote.texts[0].contents = taggedText;
With these:
endnote.texts[0].insertionPoints[0].contents = taggedText;
endnote.texts[0].contents = endnote.texts[0].contents.replace('\t', '');

Something strange with positioning text with custom font in Itext7

I'm working on a program that creates several pdf docs and puts different text in the same location in them.
Text should be placed in a particular area and if it doesn't fit it in width it should wrap. It also has a custom font and may be differently aligned in that area. It should be Vertically aligned to Top because when the area is laid out for three lines and I has only one, it should appear on the top. Finally, I need to preserve leading on the level of font-size.
It is important to be precise in text positioning (e.g. I need an upper left corner of "H" from "Hello world" to appear definitely at 0, 100).
Now, I'm using
canvas.showTextAligned(paragraph, 0, 300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
However, when I try to implement it with different fonts it has a various offset from desired y = 300. Moreover, offset differ from font to font. For Helvetica (everywhere 50 fontSize is used) offset is about 13 px, for Oswald about 17 px and for SedgwickAveDisplay it is massive 90 px.
I added borders to paragraph for debugging purpose and things become more strange.
Helvetica:
SedgwickAveDisplay:
The full snippet of my code to create pdf is below:
public byte[] createBadgeInMemory(int i) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfDocument newPdf = new PdfDocument(new PdfWriter(out));
srcPdf.copyPagesTo(1,1,newPdf);
PdfPage page = newPdf.getFirstPage();
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, newPdf, pageSize);
File defaultFont = new File("src/main/resources/fonts/Helvetica.otf");
PdfFont font = PdfFontFactory
.createFont(fontPath == null ? defaultFont.getAbsolutePath() : fontPath,
PdfEncodings.IDENTITY_H, true);
String value = "Example word";
Paragraph paragraph = new Paragraph(value);
float textWidth = font.getWidth("Example", 50);
paragraph.setWidth(textWidth);
switch (alignment) {
case("CENTER"):
textWidth /= 2;
break;
case("RIGHT"):
break;
default:
textWidth = 0;
break;
}
paragraph.setFont(font)
.setFontSize(fontSize)
.setFixedLeading(fontSize)
.setFontColor(new DeviceRgb(red, green, blue))
.setMargin(0)
.setPadding(0);
paragraph.setBorderTop(new DashedBorder(Color.BLACK, 0.5f))
.setBorderBottom(new DashedBorder(Color.BLACK, 0.5f))
.setBorderRight(new DashedBorder(Color.BLACK, 0.5f));
paragraph.setHyphenation(new HyphenationConfig(0,
"Example".length()));
canvas.showTextAligned(paragraph,
0 + textWidth,
300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
newPdf.close();
return out.toByteArray();
}
I also tried variant from here, but for some reason text inside rectangle cuts out at some point (for instance, if I have area width 100px and text snippet I put in that I know occupies exactly 100 px (with the help of font.getWidth(value)), I have my text cut at nearly 80 px).
I also haven't found a way to align text inside a rectangle.
This is the result with Rectangle. A solid border is Rectangle border. As you can see it cuts letter "t" in "Redundant". It also should contain "word" on the second line, but it doesn't.
I copied code from an example.
I need your help. What am I doing wrong or may be there is another way to layout text in particular area with alignment and font?
Thank you in advance.
Update 21.09.17
Also tried variant from this question with SedgwickAveDisplay:
paragraph.setHorizontalAlignment(HorizontalAlignment.LEFT);
paragraph.setVerticalAlignment(VerticalAlignment.TOP);
paragraph.setFixedPosition( 0, 300 - textHeight, "Example".length());
doc.add(paragraph);
The result is the same as on the second screenshot.
This is a font-specific problem. iText guesses information about font glyphs, namely the bboxes incorrectly.
There is a quick and dirty method to adjust this behavior. You can create a custom renderer for text and adjust the calculated positions in it. An example of such a class would be as follows:
class CustomTextRenderer extends TextRenderer {
private CustomTextRenderer(Text text) {
super(text);
}
#Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
Rectangle oldBbox = this.occupiedArea.getBBox().clone();
// you can also make the height more than font size or less if needed
this.occupiedArea.setBBox(oldBbox.moveUp(oldBbox.getHeight() - fontSize).setHeight(fontSize));
yLineOffset = fontSize * 0.8f; // here you config the proportion of the ascender
return result;
}
#Override
public IRenderer getNextRenderer() {
return new CustomTextRenderer((Text) modelElement);
}
}
In order that new rendering logic to be applied, you have to use it in the following way:
Text text = new Text(value);
text.setNextRenderer(new CustomTextRenderer(text));
Paragraph paragraph = new Paragraph(text);
Please note that you have to be very careful with this kind of low-level layouting, be aware of you are doing and use this as seldom as possible.
Finally, I created a variant that worked for me.
pdfCanvas.beginText()
.setFontAndSize(font, fontSize)
.setLeading(fontSize)
.moveText(0, 300);
numberOfLines = 0;
sumOfShifts = 0;
float maxWidth = computeStringWidth("Exaxple");
String[] words = value.split("\\s");
StringBuilder line = new StringBuilder();
line.append(words[0]);
float spaceWidth = computeStringWidth(" ") ;
float lineWidth;
for (int index = 1; index < words.length; index++) {
String word = words[index];
float wordWidth = computeStringWidth(word) ;
lineWidth = computeStringWidth(line.toString()) ;
if (lineWidth + spaceWidth + wordWidth <= maxWidth) {
line.append(" ").append(word);
} else {
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
line.delete(0, line.length());
line.append(word);
}
}
if(line.length() != 0) {
lineWidth = computeStringWidth(line.toString()) ;
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
}
pdfCanvas.endText();
As computeStringWidth(String str) I used
Toolkit.getToolkit().getFontLoader().computeStringWidth(String str, Font font);
from import com.sun.javafx.tk.Toolkit with Font from javafx.scene.text.Font. I've chosen it because I use it in other parts of my app.
showTextAligned(...) is my own method that looks this way:
private void showTextAligned(String alignment,
PdfCanvas pdfCanvas,
String line,
float lineWidth,
float maxWidth) {
switch (alignment) {
case "CENTER": {
float shift = (maxWidth - lineWidth) / 2 - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
case "RIGHT": {
float shift = maxWidth - lineWidth - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
default:
pdfCanvas.moveText(0, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
break;
}
}
In my project, I used my variant, because it gives me an opportunity to work with hyphenation deeper (for instance, I can in future add functionality to avoid putting prepositions as a last word in the line).

How to replace selected text in InDesign via script?

In my scripted UI panel, I have a button that is supposed to insert some text. I came up with this routine, which, indeed, inserts whatever text wherever I want, but if there is any text already selected, it doesn't replace the selection.
How can I modify this function to replace the selection? If there is nothing selected, it should just insert the text normally.
function insertText(whattext){
if( app.selection.length < 1 ){ exit(); }
var tf = app.selection;
for( var q = 0; q < tf.length; q++ ){
var thisframe = tf[q];
var originaltext = thisframe.contents;
thisframe.contents = originaltext + whattext;
}
}
Hmmm... well, this seems to work pretty well... [embarassed look on face]
function insertText(whattext){
app.selection[0].contents = whattext;
}

Google Script Image Resizing

I'm trying to make a script that will resize the images in a google doc. What I have is:
var imgs = currentDoc.getImages();
for (var i = 1; i < imgs.length; i++)
{
cell = row.insertTableCell(1);
imgNew = imgs[i].setWidth(365);
cell.insertImage(1, imgNew.getBlob());
}
The image gets inserted correctly but the size does not change regardless of what I set the width to. Since the image is going into a cell (width=370), is it possible to just make the image take up 100% of the width and scale the height proportionally? If not I can deal with manually setting the number of pixels but that is not working either. Any ideas?
The problem is that the image size should be changed after it is inserted to a table. The following code works correctly
function test() {
var doc = DocumentApp.openById('here_is_doc_id');
var imgs = doc.getImages();
var table = doc.getTables()[0];
for (var i = 0; i < imgs.length; i++) {
var row = table.appendTableRow();
var cell = row.insertTableCell(0);
var imgNew = imgs[i].copy();
cell.insertImage(0, imgNew);
imgNew.setWidth(365);
}
}
Please mention, that array indexes, cells numbers, etc. start from 0 and not 1.
Just as an FYI, you don't need to call getBlob()... anything that has a getBlob() can be passed in directly wherever a Blob is needed.
Have you tried:
imgs[i].attr('width', '370');
Or try assigning a class that has width: 100%

Resources