psdparse 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {psdparse-0.2.0 → psdparse-0.2.1}/PKG-INFO +1 -1
  2. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psddata.h +6 -1
  3. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdengine.cpp +45 -1
  4. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdparse.cpp +29 -1
  5. {psdparse-0.2.0 → psdparse-0.2.1}/pyproject.toml +1 -1
  6. {psdparse-0.2.0 → psdparse-0.2.1}/python/psdparse_module.cpp +4 -2
  7. {psdparse-0.2.0 → psdparse-0.2.1}/.gitignore +0 -0
  8. {psdparse-0.2.0 → psdparse-0.2.1}/CMakeLists.txt +0 -0
  9. {psdparse-0.2.0 → psdparse-0.2.1}/CMakePresets.json +0 -0
  10. {psdparse-0.2.0 → psdparse-0.2.1}/LICENSE +0 -0
  11. {psdparse-0.2.0 → psdparse-0.2.1}/Makefile +0 -0
  12. {psdparse-0.2.0 → psdparse-0.2.1}/README.md +0 -0
  13. {psdparse-0.2.0 → psdparse-0.2.1}/docs/ARCHITECTURE.md +0 -0
  14. {psdparse-0.2.0 → psdparse-0.2.1}/docs/PYTHON_API.md +0 -0
  15. {psdparse-0.2.0 → psdparse-0.2.1}/docs/ROADMAP.md +0 -0
  16. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/CMakeLists.txt +0 -0
  17. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/bmp.cpp +0 -0
  18. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psd_cli.cpp +0 -0
  19. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdbase.h +0 -0
  20. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psddesc.cpp +0 -0
  21. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psddesc.h +0 -0
  22. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdengine.h +0 -0
  23. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdfile.cpp +0 -0
  24. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdfile.h +0 -0
  25. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdimage.cpp +0 -0
  26. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdlayer.cpp +0 -0
  27. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdlayer.h +0 -0
  28. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdparse.h +0 -0
  29. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdresource.cpp +0 -0
  30. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdresource.h +0 -0
  31. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdwrite.cpp +0 -0
  32. {psdparse-0.2.0 → psdparse-0.2.1}/psdparse/psdwrite.h +0 -0
  33. {psdparse-0.2.0 → psdparse-0.2.1}/python/CMakeLists.txt +0 -0
  34. {psdparse-0.2.0 → psdparse-0.2.1}/tests/conftest.py +0 -0
  35. {psdparse-0.2.0 → psdparse-0.2.1}/tests/test_header.py +0 -0
  36. {psdparse-0.2.0 → psdparse-0.2.1}/tests/test_images.py +0 -0
  37. {psdparse-0.2.0 → psdparse-0.2.1}/tests/test_layers.py +0 -0
  38. {psdparse-0.2.0 → psdparse-0.2.1}/tests/test_save.py +0 -0
  39. {psdparse-0.2.0 → psdparse-0.2.1}/tests/test_text.py +0 -0
  40. {psdparse-0.2.0 → psdparse-0.2.1}/tools/psd_export.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: psdparse
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Fast PSD (Photoshop) reader/writer — C++17 core with pybind11 bindings
5
5
  Keywords: psd,photoshop,parser,image,graphics
6
6
  Author-Email: wamsoft <wtnbgo@gmail.com>
@@ -157,6 +157,8 @@ namespace psd {
157
157
  int width;
158
158
  int depth;
159
159
  int mode;
160
+ double hres = 72.0; // 水平解像度 dpi (image resource 1005)。 既定 72。
161
+ double vres = 72.0; // 垂直解像度 dpi。
160
162
  };
161
163
 
162
164
  // RGBAカラー
@@ -403,10 +405,13 @@ namespace psd {
403
405
  int tracking; // トラッキング (字送り, 1/1000 em)
404
406
  int kerning; // 手動カーニング
405
407
  bool autoKerning; // 自動カーニング (メトリクス/オプティカル) 有効
408
+ bool sizeInherited; // FontSize を既定 StyleSheet から継承したか。
409
+ // 継承分は nominal pt なので dpi/72 で px 化する
410
+ // (明示 run の FontSize は既に解決済み px)。内部用。
406
411
 
407
412
  TextStyleRun()
408
413
  : length(0), fontSize(0.0f), color{0,0,0,1}, hasColor(false),
409
- tracking(0), kerning(0), autoKerning(false) {}
414
+ tracking(0), kerning(0), autoKerning(false), sizeInherited(false) {}
410
415
  };
411
416
 
412
417
  // テキストレイヤ情報 (追加レイヤ情報 'TySh' 由来)。
@@ -204,6 +204,37 @@ namespace {
204
204
  }
205
205
  }
206
206
 
207
+ // 既定 StyleSheet (ResourceDict/StyleSheetSet[0]/StyleSheetData)。
208
+ // box text の基準 run は FontSize/Font 等の StyleSheetData を持たず、 この既定を
209
+ // 継承する。 これを読まないと FontSize=0 になる (実表示は既定サイズ)。
210
+ float defSize = 0.0f; int defFontIdx = -1; int defTracking = 0;
211
+ float defColor[4] = {0, 0, 0, 1}; bool defHasColor = false;
212
+ {
213
+ Node *rd2 = dget(root, "ResourceDict");
214
+ Node *sss = dget(rd2, "StyleSheetSet");
215
+ Node *dssd = 0;
216
+ if (sss && sss->kind == Node::ARRAY && !sss->arr.empty()) {
217
+ dssd = dget(sss->arr[0], "StyleSheetData");
218
+ if (!dssd) dssd = dget(dget(sss->arr[0], "StyleSheet"), "StyleSheetData");
219
+ }
220
+ if (dssd) {
221
+ Node *f = dget(dssd, "Font");
222
+ if (f && f->kind == Node::NUMBER) defFontIdx = (int)f->num;
223
+ Node *fs = dget(dssd, "FontSize");
224
+ if (fs && fs->kind == Node::NUMBER) defSize = (float)fs->num;
225
+ Node *tk = dget(dssd, "Tracking");
226
+ if (tk && tk->kind == Node::NUMBER) defTracking = (int)tk->num;
227
+ Node *vals = dget(dget(dssd, "FillColor"), "Values");
228
+ if (vals && vals->kind == Node::ARRAY && vals->arr.size() >= 4) {
229
+ defColor[3] = (float)vals->arr[0]->num; // A
230
+ defColor[0] = (float)vals->arr[1]->num; // R
231
+ defColor[1] = (float)vals->arr[2]->num; // G
232
+ defColor[2] = (float)vals->arr[3]->num; // B
233
+ defHasColor = true;
234
+ }
235
+ }
236
+ }
237
+
207
238
  // ラン単位スタイル (EngineDict/StyleRun)
208
239
  if (engine) {
209
240
  Node *styleRun = dget(engine, "StyleRun");
@@ -213,6 +244,16 @@ namespace {
213
244
  for (size_t i = 0; i < runArray->arr.size(); i++) {
214
245
  Node *ssd = dget(dget(runArray->arr[i], "StyleSheet"), "StyleSheetData");
215
246
  TextStyleRun r;
247
+ // 既定を先に適用 (未指定フィールドの継承)。
248
+ r.fontSize = defSize;
249
+ r.sizeInherited = true; // 既定継承 (下で run が上書きすれば false)
250
+ r.tracking = defTracking;
251
+ if (defFontIdx >= 0 && defFontIdx < (int)fonts.size()) r.font = fonts[defFontIdx];
252
+ if (defHasColor) {
253
+ r.color[0] = defColor[0]; r.color[1] = defColor[1];
254
+ r.color[2] = defColor[2]; r.color[3] = defColor[3];
255
+ r.hasColor = true;
256
+ }
216
257
  if (runLen && runLen->kind == Node::ARRAY && i < runLen->arr.size() &&
217
258
  runLen->arr[i]->kind == Node::NUMBER) {
218
259
  r.length = (int)runLen->arr[i]->num;
@@ -224,7 +265,10 @@ namespace {
224
265
  if (idx >= 0 && idx < (int)fonts.size()) r.font = fonts[idx];
225
266
  }
226
267
  Node *fsz = dget(ssd, "FontSize");
227
- if (fsz && fsz->kind == Node::NUMBER) r.fontSize = (float)fsz->num;
268
+ if (fsz && fsz->kind == Node::NUMBER) {
269
+ r.fontSize = (float)fsz->num; // 明示 = 解決済み px
270
+ r.sizeInherited = false;
271
+ }
228
272
  Node *trk = dget(ssd, "Tracking");
229
273
  if (trk && trk->kind == Node::NUMBER) r.tracking = (int)trk->num;
230
274
  Node *krn = dget(ssd, "Kerning");
@@ -35,11 +35,22 @@ Data::processParsed()
35
35
  success = loadResourceLayerComps(*this, res);
36
36
  break;
37
37
 
38
+ case 1005: { // 0x03ED -- ResolutionInfo。 hRes/vRes は Fixed 16.16 の dpi。
39
+ if (res.data) {
40
+ int32_t h = res.data->getInt32(); // hRes (Fixed 16.16)
41
+ (void)res.data->getInt16(); // hResUnit
42
+ (void)res.data->getInt16(); // widthUnit
43
+ int32_t v = res.data->getInt32(); // vRes (Fixed 16.16)
44
+ if (h > 0) header.hres = (double)(uint32_t)h / 65536.0;
45
+ if (v > 0) header.vres = (double)(uint32_t)v / 65536.0;
46
+ }
47
+ break;
48
+ }
49
+
38
50
  default: // 未実装はそのままスルー
39
51
  case 1000: // 0x03E8 -- (Obsolete--Photoshop 2.0 only ) Contains five 2-byte values: number of channels, rows, columns, depth, and mode
40
52
  case 1001: // 0x03E9 -- Macintosh print manager print info record
41
53
  case 1003: // 0x03EB -- (Obsolete--Photoshop 2.0 only ) Indexed color table
42
- case 1005: // 0x03ED -- ResolutionInfo structure. See Appendix A in Photoshop API Guide.pdf.
43
54
  case 1006: // 0x03EE -- Names of the alpha channels as a series of Pascal strings.
44
55
  case 1007: // 0x03EF -- (Obsolete) See ID 1077DisplayInfo structure. See Appendix A in Photoshop API Guide.pdf.
45
56
  case 1008: // 0x03F0 -- The caption as a Pascal string.
@@ -295,6 +306,23 @@ Data::processParsed()
295
306
  }
296
307
  }
297
308
 
309
+ // テキスト run の FontSize を px に正規化する (レイヤ解析後・解像度確定後)。 明示
310
+ // run の FontSize は既に解決済み px だが、 既定 StyleSheet から継承した分は nominal
311
+ // pt なので dpi/72 を掛ける (300dpi なら 12pt → 50px)。
312
+ {
313
+ double sc = header.hres / 72.0;
314
+ if (sc != 1.0) {
315
+ for (uint32_t li = 0; li < layerList.size(); li++) {
316
+ TextLayerData &td = layerList[li].textData;
317
+ if (!td.present) continue;
318
+ for (size_t ri = 0; ri < td.runs.size(); ri++) {
319
+ if (td.runs[ri].sizeInherited)
320
+ td.runs[ri].fontSize *= (float)sc;
321
+ }
322
+ }
323
+ }
324
+ }
325
+
298
326
  return success;
299
327
  }
300
328
 
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "psdparse"
7
- version = "0.2.0"
7
+ version = "0.2.1"
8
8
  description = "Fast PSD (Photoshop) reader/writer — C++17 core with pybind11 bindings"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -52,7 +52,7 @@ py::object layerText(const psd::LayerInfo &l) {
52
52
  py::dict rd;
53
53
  rd["length"] = r.length; // UTF-16 code units covered by this run
54
54
  rd["font"] = py::cast(r.font); // resolved font-set name
55
- rd["size_px"] = r.fontSize; // pt
55
+ rd["size_px"] = r.fontSize; // px (文書解像度で換算済み; 継承分は pt×dpi/72)
56
56
  rd["tracking"] = r.tracking; // 1/1000 em
57
57
  rd["kerning"] = r.kerning; // manual kerning
58
58
  rd["auto_kerning"] = r.autoKerning; // metrics/optical kerning on
@@ -134,7 +134,9 @@ PYBIND11_MODULE(psdparse, m) {
134
134
  .def_readonly("height", &psd::Header::height)
135
135
  .def_readonly("width", &psd::Header::width)
136
136
  .def_readonly("depth", &psd::Header::depth)
137
- .def_readonly("mode", &psd::Header::mode);
137
+ .def_readonly("mode", &psd::Header::mode)
138
+ .def_readonly("hres", &psd::Header::hres) // 水平解像度 dpi (既定 72)
139
+ .def_readonly("vres", &psd::Header::vres); // 垂直解像度 dpi
138
140
 
139
141
  py::class_<psd::ChannelInfo>(m, "ChannelInfo")
140
142
  .def_readonly("id", &psd::ChannelInfo::id)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes