Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cariage return character is wrongly written #175

Open
sasensi opened this issue May 16, 2024 · 5 comments
Open

Cariage return character is wrongly written #175

sasensi opened this issue May 16, 2024 · 5 comments

Comments

@sasensi
Copy link

sasensi commented May 16, 2024

Hello and once again, thank you for the great work with this library which helps me so much ! 😊

Working with the following file:
input.zip

That looks like this in Photoshop:
image
Notice the text has a paragraph spacing set so the line 3 is separated from the line 2 by the expected gap but this gap is not between the line 1 and 2 because they are separated by a carriage return character and not a line break character.

So if we take this file, read it and write it using the library, like this:

import * as fs from 'fs';
import { readPsd, writePsdBuffer } from 'ag-psd';
import 'ag-psd/initialize-canvas.js';

const INPUT_FILE_PATH = 'input.psd';
const OUTPUT_FILE_PATH = 'output.psd';

const inBuffer = fs.readFileSync(INPUT_FILE_PATH);
const psd = readPsd(inBuffer);

const outBuffer = writePsdBuffer(psd, { invalidateTextLayers: true });
fs.writeFileSync(OUTPUT_FILE_PATH, outBuffer);

It then looks like this:
image
For some reason, the carriage return character is not preserved.


I tried to play with it a bit using this code, to try all possible line breaks characters that I knew but none seems to produce the expected result:

import * as fs from 'fs';
import { readPsd, writePsdBuffer } from 'ag-psd';
import 'ag-psd/initialize-canvas.js';

const INPUT_FILE_PATH = 'input.psd';
const OUTPUT_FILE_PATH = 'output.psd';
const LINE_BREAK_CHARACTER_INDEX = 1;

const inBuffer = fs.readFileSync(INPUT_FILE_PATH);
const psd = readPsd(inBuffer);

const shapeText = psd.children['0'].children['0'].text;
const carriageReturnCharacter = shapeText.text[LINE_BREAK_CHARACTER_INDEX];
const carriageReturnCharacterCode = shapeText.text.charCodeAt(LINE_BREAK_CHARACTER_INDEX);
const charactersToTest = [
  '\n',
  '\r',
  '\u0003',
  '\u8232',
  String.fromCharCode(3),
  String.fromCharCode(carriageReturnCharacterCode),
];
shapeText.text = `line${charactersToTest.join('line')}line`;

const outBuffer = writePsdBuffer(psd, { invalidateTextLayers: true });
fs.writeFileSync(OUTPUT_FILE_PATH, outBuffer);

And here's the visual result:
image


Hoping you can help with this 🤞

@Agamnentzar
Copy link
Owner

Agamnentzar commented May 16, 2024

It seems that Photoshop puts \u0003 symbol for new line, but also indicates that the line is broke in that spot in psd.engineData field, unfortunately engineData field is not yet implemented in ag-psd, there's no documentation for that object and it's compressed in a weird way that makes it really hard to decipher. invalidateTextLayers: true clears engineData field so that's why the information about that line break is lost.

@sasensi
Copy link
Author

sasensi commented May 17, 2024

@Agamnentzar, thank you for your quick response, ok, I see.
So is implementing engineData support in ag-psd something that you plan to do or not really ?
Also, is there something I can help with in order to support this use case ?

@Agamnentzar
Copy link
Owner

The problem is that the data in that section looks like this:

image

And I have no way of figuring out which numbers map to what property names, I managed to figure out some of the fields by just changing fields in Photoshop and seeing which one of these change values, but that doesn't work for all of the fields, so I'm stuck at this point until I have some way to find what these fields are. (My guess for why it is this way is that they wanted to compress the data so they replaced property names with numbers, and Photoshop has some internal dictionary that can translate numbers to names)

@Agamnentzar
Copy link
Owner

Did you try if it works without invalidateTextLayers: true ?

@sasensi
Copy link
Author

sasensi commented May 20, 2024

@Agamnentzar, I see quite clearly the problem because I once built a rough .ai writer (less advanced than yours though) and had to deal with this kind of data also 😄
And the way I went was exactly what you describe: guessing each piece of data meaning by trial and error.
And since it's not documented, I guess that it's the only way unfortunately.
I also tried without invalidateTextLayers: true but it doesn't work neither.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants